basecamp-mcp-server
by HuskyDS
README.md
# basecamp-mcp-server
An [MCP](https://modelcontextprotocol.io) server for **Basecamp 5** — gives your AI assistant
access to projects, to-dos, messages, campfire chat, documents, and card tables.
Works with Claude Code, Claude Desktop, Cursor, OpenAI Codex, and VS Code.
```
You: What's on my plate in Basecamp this week?
→ basecamp_my_assignments
→ Two things are assigned to you, both in Fieldwork Study:
• Send Robin the drafted survey instrument — due today, 2 subtasks
• Review the pilot analysis — due Friday
```
## Requirements
- **Python 3.11+**
- A **Basecamp 5** account
- Credentials, via either:
- the [Basecamp CLI](https://github.com/basecamp/basecamp-cli) — recommended, because it keeps a
self-refreshing OAuth token in your OS keyring and this server never touches your disk; or
- a `BASECAMP_ACCESS_TOKEN` environment variable (expires after 14 days, with no refresh)
## Quick start
```bash
# 1. Authenticate, if you have not already
basecamp auth login
# 2. Check that everything resolves — this makes a real API call
uvx basecamp-mcp-server doctor
# 3. Add it to your client (Claude Code shown; others below)
claude mcp add basecamp -- uvx basecamp-mcp-server serve
```
`doctor` prints the resolved credential source, your Basecamp accounts, and a paste-ready config
block for every supported client. Start there if anything below does not work.
## Client configuration
The formats genuinely differ between clients — the key name, the file, and whether it is JSON or
TOML. Copy the one you need.
### Claude Code
```bash
claude mcp add basecamp -- uvx basecamp-mcp-server serve
```
Verify with `claude mcp list`; it should report `✔ Connected`.
### Claude Desktop
`claude_desktop_config.json` — **macOS** `~/Library/Application Support/Claude/`,
**Windows** `%APPDATA%\Claude\`:
```json
{
"mcpServers": {
"basecamp": {
"command": "uvx",
"args": ["basecamp-mcp-server", "serve"]
}
}
}
```
### Cursor
`.cursor/mcp.json` in the project, or `~/.cursor/mcp.json` globally. Same `mcpServers` shape as
Claude Desktop.
### VS Code
`.vscode/mcp.json`. Note the key is **`servers`**, not `mcpServers`, and `type` is required:
```json
{
"servers": {
"basecamp": {
"type": "stdio",
"command": "uvx",
"args": ["basecamp-mcp-server", "serve"]
}
}
}
```
### OpenAI Codex
`~/.codex/config.toml` — TOML, and the table is `mcp_servers` with an underscore:
```toml
[mcp_servers.basecamp]
command = "uvx"
args = ["basecamp-mcp-server", "serve"]
```
## Permissions
The server has three modes. **Tools you have not enabled are not registered at all**, so the model
never sees them and never proposes an action you have forbidden.
| Mode | Flag | Tools | What it can do |
|---|---|---:|---|
| Read-only | `--read-only` | 19 | Look at everything; change nothing |
| Default | *(none)* | 28 | Create and edit; remove nothing |
| Full | `--allow-destructive` | 29 | Also trash and archive, and only with `confirm: true` |
```bash
# See exactly what a given configuration exposes
uvx basecamp-mcp-server tools list --read-only
```
Read-only is worth considering if you mainly want your assistant to *answer questions* about
Basecamp. You can always restart with writes enabled.
## What it can do
**Find things** — `list_projects` · `get_project` · `search` · `my_assignments` · `list_people`
**To-dos** — `list_todolists` · `list_todos` · `get_todo` · `create_todo` · `update_todo` ·
`complete_todo`
**Messages and chat** — `list_messages` · `get_message` · `create_message` · `list_comments` ·
`create_comment` · `list_campfire_lines` · `create_campfire_line`
**Docs and cards** — `list_documents` · `get_document` · `get_card_table` · `list_cards` ·
`create_card` · `move_card`
**Anything else** — `basecamp_request` reaches any Basecamp endpoint these tools do not cover
(GET only), and `basecamp_write_request` covers POST and PUT.
Start with `basecamp_get_project`: it returns a `tools` map giving the ids every other tool in
that project needs, so your assistant does not have to guess them.
## Configuration
Everything is optional; the defaults are chosen to be safe rather than fast.
| Variable | Default | Notes |
|---|---|---|
| `BASECAMP_ACCESS_TOKEN` | — | Only needed without the Basecamp CLI |
| `BASECAMP_ACCOUNT_ID` | auto | Required only if you belong to several Basecamp accounts |
| `BASECAMP_MCP_READ_ONLY` | `false` | Same as `--read-only` |
| `BASECAMP_MCP_ALLOW_DESTRUCTIVE` | `false` | Same as `--allow-destructive` |
| `BASECAMP_MCP_USER_AGENT` | this project | Must contain a contact URL or email, or Basecamp rejects every request with a `400` |
| `BASECAMP_MCP_MAX_PAGES` | `25` | Upper bound on auto-pagination per call. Capped at 200 |
| `BASECAMP_MCP_MAX_RESULT_CHARS` | `25000` | Size ceiling for one tool result |
| `BASECAMP_MCP_LOG_LEVEL` | `INFO` | Logs go to stderr, never stdout |
## Notes
**Responses are projected, not passed through.** Basecamp payloads are built for a rich web
client: one to-do is ~5 KB of JSON and a single message can be 37 KB. Unprojected, a hundred
to-dos would be around 530 KB — enough to end a conversation. Every response is reduced to the
fields that let a model answer and chain to the next call, which is a 12–60× cut depending on
type, with every id preserved.
**Content from Basecamp is untrusted input.** To-do titles, message bodies and comments are
written by other people. The server tells your assistant to treat them as data to report on
rather than instructions to follow, but that is a mitigation, not a guarantee — bear it in mind
before enabling writes on an account with people you do not know.
**Edits preserve fields you did not mention.** `update_todo` reads the record, overlays your
changes and writes it back, so setting a due date does not erase the assignees. The cost is that
it is two requests rather than one, and a concurrent edit in between is overwritten.
## Development
```bash
uv sync
uv run ruff check . && uv run ruff format --check . && uv run mypy && uv run pytest
```
See [AGENTS.md](AGENTS.md) for architecture, layer rules, and a list of verified upstream
behaviours that look like bugs until you read the source.
## License
MIT — see [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues