Basecamp's own interface makes "what is assigned to this person everywhere" and "what is overdue across all projects" into a lot of clicking; here each is one call. Know one limit before you rely on the file tools: the project's own compatibility note says Claude Code passes PDF blobs through to the model, while Claude Desktop and claude.ai currently reject non-image embedded resources — the bytes reach the host and stop there. Use the CLI client when you need a document read.
A FastMCP server for Basecamp 3 that covers most of the product rather than a slice of it — projects, to-dos, message boards, campfires, card tables, inbox forwards, documents, uploads, comments, events, webhooks and search — authenticated through an OAuth application you create yourself.
- Projects and search: `get_projects`, `get_project`, `search_basecamp`, `global_search`
- Cross-project reports, which is where it beats clicking: `get_person_assignments` returns everything assigned to one person across all projects, `get_overdue_todos` returns overdue items grouped by lateness, `get_assignable_people` lists who can be assigned
- To-dos: `get_todolists`, `create_todolist`, `get_todos`, `create_todo`, `update_todo`, `complete_todo`, `reposition_todo`, `create_todolist_group`
- Card tables: `get_card_tables`, `get_columns`, `create_column`, `put_column_on_hold`, `get_cards`, `create_card`, `move_card`, `create_card_step`, `complete_card_step`
- Messages and documents, drafts included: `get_messages`, `create_message`, `create_draft_message`, `get_documents`, `create_document`, `create_draft_document`, `get_comments`, `create_comment`
- Files that reach the model: `download_upload` and `download_attachment` return the bytes as MCP content rather than a link
- Events and webhooks: `get_events`, `get_webhooks`, `create_webhook`, `delete_webhook`
- Config generators for Codex, Cursor and Claude Desktop, so the client entry is written for you
Python 3.10 or newer, a Basecamp 3 account, and your own OAuth application from launchpad.37signals.com. `BASECAMP_CLIENT_ID`, `BASECAMP_CLIENT_SECRET`, `BASECAMP_ACCOUNT_ID` and a `USER_AGENT` string go into `.env`, then `python oauth_app.py` runs the browser flow on `http://localhost:8000` and stores the token in `oauth_tokens.json`. If your system Python is older, `uv venv --python 3.12` is the documented way around it.
