Skip to main content
Glama
thedistance

Basecamp 2 MCP

by thedistance
README.md
# Basecamp 2 MCP

A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that connects Claude and other AI assistants to the [Basecamp 2 API](https://github.com/basecamp/bcx-api). Manage projects, todos, messages, and people directly from your AI assistant.

## Prerequisites

- Node.js 18 or later
- A Basecamp 2 account
- OAuth 2 credentials **or** your username and password

## OAuth Setup (recommended)

1. **Register your app** at [launchpad.37signals.com/integrations](https://launchpad.37signals.com/integrations) to obtain a `client_id` and `client_secret`.

2. **Run the auth helper** — it opens a browser, handles the redirect, exchanges the code for tokens, and prints your `BASECAMP_ACCOUNT_ID` automatically:

   ```bash
   BASECAMP_CLIENT_ID=your_client_id \
   BASECAMP_CLIENT_SECRET=your_client_secret \
   npx basecamp-2-mcp-auth
   ```

   Copy the printed env vars into your `.env` or MCP server config.

3. The MCP server will **automatically refresh the access token** when it expires (~2 weeks) as long as `BASECAMP_REFRESH_TOKEN`, `BASECAMP_CLIENT_ID`, and `BASECAMP_CLIENT_SECRET` are set.

   > By default `npx basecamp-2-mcp-auth` listens on port `3000`. Set `OAUTH_PORT` to change it (your registered redirect URI must match).

## Environment Variables

| Variable | Required | Description |
|---|---|---|
| `BASECAMP_ACCOUNT_ID` | Yes | Your account ID — printed by the auth helper, or found in the URL: `basecamp.com/{account_id}/` |
| `BASECAMP_ACCESS_TOKEN` | Yes* | OAuth 2 access token |
| `BASECAMP_REFRESH_TOKEN` | No | Enables automatic token refresh when the access token expires |
| `BASECAMP_CLIENT_ID` | No† | Required for automatic token refresh |
| `BASECAMP_CLIENT_SECRET` | No† | Required for automatic token refresh |
| `BASECAMP_USERNAME` | Yes* | Your Basecamp email (Basic Auth alternative) |
| `BASECAMP_PASSWORD` | Yes* | Your Basecamp password (Basic Auth alternative) |
| `USER_AGENT` | Yes | Identifies your integration, e.g. `MyApp (you@example.com)` |

\* Either `BASECAMP_ACCESS_TOKEN` **or** both `BASECAMP_USERNAME` + `BASECAMP_PASSWORD` are required.
† Required together with `BASECAMP_REFRESH_TOKEN` to enable automatic token refresh.

## Setup with Claude Desktop

Add the following to your `claude_desktop_config.json` (usually at `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):

```json
{
  "mcpServers": {
    "basecamp-2": {
      "command": "npx",
      "args": ["-y", "basecamp-2-mcp"],
      "env": {
        "BASECAMP_ACCOUNT_ID": "your_account_id",
        "BASECAMP_ACCESS_TOKEN": "your_access_token",
        "BASECAMP_REFRESH_TOKEN": "your_refresh_token",
        "BASECAMP_CLIENT_ID": "your_client_id",
        "BASECAMP_CLIENT_SECRET": "your_client_secret",
        "USER_AGENT": "MyApp (you@example.com)"
      }
    }
  }
}
```

Then restart Claude Desktop.

## Setup with Claude Code

```bash
claude mcp add basecamp-2 -- npx -y basecamp-2-mcp
```

Then set the required environment variables in your shell or `.env` file.

## Running Locally

```bash
# 1. Clone the repo and install dependencies
npm install

# 2. Copy and fill in environment variables
cp .env.example .env

# 3. Build
npm run build

# 4. Start the MCP server
npm start
```

For development with live reload:

```bash
npm run dev
```

To test interactively with the MCP Inspector:

```bash
npx @modelcontextprotocol/inspector npx tsx src/index.ts
```

## Available Tools

### Projects
| Tool | Description |
|---|---|
| `list_projects` | List all active projects |
| `get_project` | Get a project by ID |

### People
| Tool | Description |
|---|---|
| `get_me` | Get the currently authenticated user |
| `list_people` | List all people in the account |
| `get_person` | Get a person by ID |

### Todo Lists
| Tool | Description |
|---|---|
| `list_todolists` | List all todo lists in a project |
| `get_todolist` | Get a todo list with its todos |
| `create_todolist` | Create a new todo list in a project |

### Todos
| Tool | Description |
|---|---|
| `list_todos` | List all todos in a todo list |
| `get_todo` | Get a single todo item |
| `create_todo` | Create a new todo (supports due date + assignee) |
| `update_todo` | Update a todo's content, due date, or assignee |
| `complete_todo` | Mark a todo as completed |
| `delete_todo` | Delete a todo item |

### Messages & Topics
| Tool | Description |
|---|---|
| `list_topics` | List all topics (messages, forwards, etc.) in a project |
| `get_message` | Get a full message by ID (use the `topicable.id` from `list_topics`) |
| `create_message` | Post a new message to a project |

## Authentication

Basecamp 2 uses [OAuth 2 via Launchpad](https://github.com/basecamp/api/blob/master/sections/authentication.md). The authorization flow is:

1. User visits `https://launchpad.37signals.com/authorization/new?type=web_server&client_id=…&redirect_uri=…`
2. After approving, Basecamp redirects to your `redirect_uri` with a short-lived `code`
3. Your app POSTs the code to `https://launchpad.37signals.com/authorization/token` to receive an access token and a refresh token
4. Access tokens are sent as `Authorization: Bearer <token>`. Refresh tokens last ~2 weeks.

The `npx basecamp-2-mcp-auth` helper handles steps 1–3 automatically. The MCP server handles step 4 including silent refresh.

Every API request must also include a `User-Agent` header identifying your app and a contact email — this is a Basecamp API requirement. See [Identifying your application](https://github.com/basecamp/bcx-api#identifying-your-application).

## License

MIT

TDQS

B3.2/5.0

Scored across 17 tools

Disambiguation4/5

Most tools target distinct resource+action pairs (todo, todolist, project, person, message). Minor overlap exists between list_topics and get_message/create_message since messages are a subset of topics, and get_me vs get_person/list_people could momentarily confuse, but overall boundaries are clear.

Naming Consistency5/5

Every tool follows a consistent verb_noun snake_case pattern: list_x, get_x, create_x, update_x, complete_x, delete_x. Even get_me fits the convention, making the set highly predictable.

Tool Count4/5

17 tools is slightly heavy but well-scoped across five resources (projects, todolists, todos, messages, people). Each tool earns its place, with no obviously redundant entries.

Completeness3/5

Todos have full lifecycle (create/get/list/update/complete/delete), but todolists lack update/delete, messages lack update/delete (and only list_topics surfaces them), and projects lack create/update/delete. These notable gaps leave dead ends for common management workflows.

Maintenance

ActivityInactive
ResponsivenessNo issues