项目协议服务器

一个将Basecamp 3项目管理操作作为工具暴露的MCP(模型上下文协议)服务器,支持AI助手如Claude与Basecamp交互,包括列出项目、管理待办事项、读取/发布消息等功能。

  • by k0va1
  • Ruby
  • 本地部署
  • 更新于
在 GitHub 查看 k0va1/basecamp-mcp

使用说明

Basecamp MCP服务器

MCP(模型上下文协议)服务器,将Basecamp 3项目管理操作作为工具公开。这允许像克劳德这样的人工智能助手与Basecamp进行交互——列出项目、管理待办事项、阅读/发布消息等等。

用Ruby、Sinatra和 主控程序 gem使用流式HTTP传输。

先决条件

  • Ruby 3.2+
  • 打包机
  • 带有API访问令牌的Basecamp 3帐户

设置

git clone https://github.com/k0va1/basecamp-mcp.git && cd basecamp-mcp
make install
cp .env.example .env

编辑 .env 使用您的Basecamp证书:

BASECAMP_ACCESS_TOKEN=your_access_token_here
BASECAMP_ACCOUNT_ID=your_account_id_here
MCP_AUTH_TOKEN=optional_secret_token

您可以通过以下方式获得访问令牌 Basecamp的OAuth 2流程 或者通过创建个人整合。

认证

集 MCP_AUTH_TOKEN 要求所有MCP请求上都有承载令牌。设置后,客户端必须包含 Authorization: Bearer <token> 头球未设置时,MCP端点打开(适用于本地开发)。

OAuth2授权流

要通过浏览器进行身份验证而不是手动获取令牌,请将您的OAuth2凭据添加到 .env:

BASECAMP_CLIENT_ID=your_oauth_client_id
BASECAMP_CLIENT_SECRET=your_oauth_client_secret
BASECAMP_REDIRECT_URI=http://localhost:9292/oauth/callback

然后访问 http://localhost:9292/oauth/authorize 在您的浏览器中。使用37signals授权后,令牌会自动保存。

设置OAuth凭据后,服务器还会:

  • 将令牌持久化 .basecamp_tokens.json (自动识别)
  • 在到期前5分钟主动刷新令牌
  • 使用401错误的新令牌检索请求

如果未设置这些变量,服务器将使用静态 BASECAMP_ACCESS_TOKEN.

跑步

bundle exec rackup

服务器启动于 http://localhost:9292 默认情况下。

  • MCP端点: POST / --处理所有MCP协议消息
  • 健康检查: GET /health --退货 {"status":"ok"}
  • OAuth授权: GET /oauth/authorize --启动OAuth2流
  • OAuth回调: GET /oauth/callback --处理OAuth2重定向

集 DEBUG=1 以启用MCP和Basecamp API调用的请求/响应日志记录。

工具

项目

工具 说明
list_projects 列出所有活动项目
get_project 获取特定项目的详细信息

待办事项

工具 说明
list_todolists 在项目的待办事项集中列出待办事项列表(支持 status 过滤器)
get_todolist 获取特定待办事项列表的详细信息
create_todolist 创建新的待办事项列表
update_todolist 更新现有待办事项列表

大惊小怪

工具 说明
list_todos 在待办事项列表中列出待办事项
get_todo 获取特定待办事项的详细信息
create_todo 创建新待办事项
update_todo 更新现有待办事项
complete_todo 将待办事项标记为已完成

消息

工具 说明
list_messages 在留言板上列出消息
get_message 获取特定消息的详细信息
create_message 发布新消息

评论

工具 说明
list_comments 列出对录音的评论
create_comment 在录音中添加评论

人们

工具 说明
list_people 列出所有可见的人
get_person 获取特定人员的详细信息

MCP客户端配置

要与Claude Code或其他MCP客户端一起使用,请在MCP配置中添加:

{
  "mcpServers": {
    "basecamp": {
      "url": "http://localhost:9292/",
      "headers": {
        "Authorization": "Bearer YOUR_MCP_AUTH_TOKEN"
      }
    }
  }
}

省略 headers 字段if MCP_AUTH_TOKEN 未设置。

发展

make install    # install dependencies
make test       # run tests
make lint-fix   # fix linting issues

测试使用Minitest+WebLock。所有的HTTP调用都是存根-测试中没有真正的API请求。

项目结构

basecamp-mcp/
├── Gemfile              # Dependencies
├── Rakefile             # Test + lint tasks
├── Makefile             # Dev shortcuts
├── Dockerfile           # Multi-stage Docker build
├── config.ru            # Rack entrypoint
├── app.rb               # Server setup and wiring
├── .env.example         # Environment variable template
├── .standard.yml        # StandardRB linter config
└── lib/
    ├── basecamp/
    │   ├── client.rb          # Faraday HTTP client for Basecamp 3 API
    │   ├── errors.rb          # Custom error classes
    │   ├── token_store.rb     # Thread-safe token persistence
    │   └── oauth_refresher.rb # OAuth2 token refresh
    ├── oauth_app.rb           # OAuth2 authorize/callback Sinatra app
    ├── middleware/
    │   ├── downcase_headers.rb # Rack 3 header normalization
    │   ├── request_logger.rb   # DEBUG-gated request logger
    │   └── token_auth.rb       # Bearer token authentication
    └── tools/
        ├── base_tool.rb # Shared base class with helpers
        └── *.rb         # Auto-discovered tool classes

码头工人

本地建设

docker build -t basecamp-mcp .
docker run -e BASECAMP_ACCESS_TOKEN=... -e BASECAMP_ACCOUNT_ID=... -p 9292:9292 basecamp-mcp

Docker Compose

services:
  basecamp-mcp:
    image: ghcr.io/k0va1/basecamp-mcp:latest
    ports:
      - "9292:9292"
    environment:
      - BASECAMP_ACCESS_TOKEN=${BASECAMP_ACCESS_TOKEN}
      - BASECAMP_ACCOUNT_ID=${BASECAMP_ACCOUNT_ID}
      - MCP_AUTH_TOKEN=${MCP_AUTH_TOKEN:-}
      - BASECAMP_CLIENT_ID=${BASECAMP_CLIENT_ID:-}
      - BASECAMP_CLIENT_SECRET=${BASECAMP_CLIENT_SECRET:-}
      - BASECAMP_REDIRECT_URI=${BASECAMP_REDIRECT_URI:-http://localhost:9292/oauth/callback}
      - BASECAMP_TOKEN_PATH=/app/data/.basecamp_tokens.json
    volumes:
      - basecamp-tokens:/app/data
    restart: unless-stopped

volumes:
  basecamp-tokens:

验证

# Health check
curl http://localhost:9292/health

# MCP initialize
curl -X POST http://localhost:9292/ \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"initialize","id":1,"params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'