🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
#!/usr/bin/env python3
"""
FastMCP server for Basecamp integration .
This server implements the MCP ( Model Context Protocol ) using the official
Anthropic FastMCP framework , replacing the custom JSON - RPC implementation .
"""
import logging
import os
import sys
from typing import Any , Dict , List , Optional
import anyio
import httpx
from mcp . server . fastmcp import FastMCP
2026-01-21 20:42:05 +01:00
from config_paths import get_log_directory , get_env_file_path , ensure_directories_exist
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
# Import existing business logic
from basecamp_client import BasecampClient
from search_utils import BasecampSearch
import token_storage
2026-01-08 21:14:19 +00:00
import auth_manager
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
from dotenv import load_dotenv
2026-01-21 20:42:05 +01:00
ensure_directories_exist ( )
DOTENV_PATH = get_env_file_path ( )
if DOTENV_PATH . exists ( ) :
load_dotenv ( DOTENV_PATH )
logger = logging . getLogger ( " basecamp_fastmcp " )
logger . debug ( f " Loaded .env from { DOTENV_PATH } " )
else :
logger = logging . getLogger ( " basecamp_fastmcp " )
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
2026-01-21 20:42:05 +01:00
LOG_FILE_PATH = get_log_directory ( ) / " basecamp_fastmcp.log "
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
logging . basicConfig (
level = logging . DEBUG ,
2026-01-21 20:42:05 +01:00
format = " %(asctime)s - %(name)s - %(levelname)s - %(message)s " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
handlers = [
logging . FileHandler ( LOG_FILE_PATH ) ,
2026-01-21 20:42:05 +01:00
logging . StreamHandler ( sys . stderr ) , # Critical: log to stderr, not stdout
] ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
)
2026-01-21 20:42:05 +01:00
logger = logging . getLogger ( " basecamp_fastmcp " )
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
# Initialize FastMCP server
mcp = FastMCP ( " basecamp " )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
# Auth helper functions (reused from original server)
def _get_basecamp_client ( ) - > Optional [ BasecampClient ] :
""" Get authenticated Basecamp client (sync version from original server). """
try :
token_data = token_storage . get_token ( )
logger . debug ( f " Token data retrieved: { token_data } " )
2026-01-21 20:42:05 +01:00
if not token_data or not token_data . get ( " access_token " ) :
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
logger . error ( " No OAuth token available " )
return None
2026-01-08 21:14:19 +00:00
# Check and automatically refresh if token is expired
if not auth_manager . ensure_authenticated ( ) :
logger . error ( " OAuth token has expired and automatic refresh failed " )
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
return None
2026-01-08 21:14:19 +00:00
# Get fresh token data after potential refresh
token_data = token_storage . get_token ( )
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
# Get account_id from token data first, then fall back to env var
2026-01-21 20:42:05 +01:00
account_id = token_data . get ( " account_id " ) or os . getenv ( " BASECAMP_ACCOUNT_ID " )
user_agent = (
os . getenv ( " USER_AGENT " ) or " Basecamp MCP Server (cursor@example.com) "
)
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
if not account_id :
2026-01-21 20:42:05 +01:00
logger . error (
f " Missing account_id. Token data: { token_data } , Env BASECAMP_ACCOUNT_ID: { os . getenv ( ' BASECAMP_ACCOUNT_ID ' ) } "
)
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
return None
2026-01-21 20:42:05 +01:00
logger . debug (
f " Creating Basecamp client with account_id: { account_id } , user_agent: { user_agent } "
)
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
return BasecampClient (
2026-01-21 20:42:05 +01:00
access_token = token_data [ " access_token " ] ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
account_id = account_id ,
user_agent = user_agent ,
2026-01-21 20:42:05 +01:00
auth_mode = " oauth " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
)
except Exception as e :
logger . error ( f " Error creating Basecamp client: { e } " )
return None
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
def _get_auth_error_response ( ) - > Dict [ str , Any ] :
""" Return consistent auth error response. """
if token_storage . is_token_expired ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token has expired. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
else :
return {
2026-01-21 20:42:05 +01:00
" error " : " Authentication required " ,
" message " : " Please authenticate with Basecamp first. Visit http://localhost:8000 to log in. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
async def _run_sync ( func , * args , * * kwargs ) :
""" Wrapper to run synchronous functions in thread pool. """
return await anyio . to_thread . run_sync ( func , * args , * * kwargs )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
# Core MCP Tools - Starting with essential ones from original server
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def get_projects ( ) - > Dict [ str , Any ] :
""" Get all Basecamp projects. """
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
projects = await _run_sync ( client . get_projects )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " projects " : projects , " count " : len ( projects ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error getting projects: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def get_project ( project_id : str ) - > Dict [ str , Any ] :
""" Get details for a specific project.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
project = await _run_sync ( client . get_project , project_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " project " : project }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error getting project { project_id } : { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def search_basecamp (
query : str , project_id : Optional [ str ] = None
) - > Dict [ str , Any ] :
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
""" Search across Basecamp projects, todos, and messages.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
query : Search query
project_id : Optional project ID to limit search scope
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
search = BasecampSearch ( client = client )
results = { }
if project_id :
# Search within specific project
2026-01-21 20:42:05 +01:00
results [ " todolists " ] = await _run_sync (
search . search_todolists , query , project_id
)
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
results [ " todos " ] = await _run_sync ( search . search_todos , query , project_id )
else :
# Search across all projects
results [ " projects " ] = await _run_sync ( search . search_projects , query )
results [ " todos " ] = await _run_sync ( search . search_todos , query )
results [ " messages " ] = await _run_sync ( search . search_messages , query )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " query " : query , " results " : results }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error searching Basecamp: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def get_todolists ( project_id : str ) - > Dict [ str , Any ] :
""" Get todo lists for a project.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
todolists = await _run_sync ( client . get_todolists , project_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " todolists " : todolists , " count " : len ( todolists ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error getting todolists: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def get_todos ( project_id : str , todolist_id : str ) - > Dict [ str , Any ] :
""" Get todos from a todo list.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : Project ID
todolist_id : The todo list ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
todos = await _run_sync ( client . get_todos , project_id , todolist_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " todos " : todos , " count " : len ( todos ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error getting todos: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
2025-08-20 14:42:55 +10:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def create_todo (
project_id : str ,
todolist_id : str ,
content : str ,
description : Optional [ str ] = None ,
assignee_ids : Optional [ List [ str ] ] = None ,
completion_subscriber_ids : Optional [ List [ str ] ] = None ,
notify : bool = False ,
due_on : Optional [ str ] = None ,
starts_on : Optional [ str ] = None ,
) - > Dict [ str , Any ] :
2025-08-20 14:42:55 +10:00
""" Create a new todo item in a todo list.
2026-01-21 20:42:05 +01:00
2025-08-20 14:42:55 +10:00
Args :
project_id : Project ID
todolist_id : The todo list ID
content : The todo item ' s text (required)
description : HTML description of the todo
assignee_ids : List of person IDs to assign
completion_subscriber_ids : List of person IDs to notify on completion
notify : Whether to notify assignees
due_on : Due date in YYYY - MM - DD format
starts_on : Start date in YYYY - MM - DD format
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-08-20 14:42:55 +10:00
try :
# Use lambda to properly handle keyword arguments
todo = await _run_sync (
lambda : client . create_todo (
2026-01-21 20:42:05 +01:00
project_id ,
todolist_id ,
content ,
2025-08-20 14:42:55 +10:00
description = description ,
assignee_ids = assignee_ids ,
completion_subscriber_ids = completion_subscriber_ids ,
notify = notify ,
due_on = due_on ,
2026-01-21 20:42:05 +01:00
starts_on = starts_on ,
2025-08-20 14:42:55 +10:00
)
)
return {
" status " : " success " ,
" todo " : todo ,
2026-01-21 20:42:05 +01:00
" message " : f " Todo ' { content } ' created successfully " ,
2025-08-20 14:42:55 +10:00
}
except Exception as e :
logger . error ( f " Error creating todo: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-08-20 14:42:55 +10:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-08-20 14:42:55 +10:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def update_todo (
project_id : str ,
todo_id : str ,
content : Optional [ str ] = None ,
description : Optional [ str ] = None ,
assignee_ids : Optional [ List [ str ] ] = None ,
completion_subscriber_ids : Optional [ List [ str ] ] = None ,
notify : Optional [ bool ] = None ,
due_on : Optional [ str ] = None ,
starts_on : Optional [ str ] = None ,
) - > Dict [ str , Any ] :
2025-08-20 14:42:55 +10:00
""" Update an existing todo item.
2026-01-21 20:42:05 +01:00
2025-08-20 14:42:55 +10:00
Args :
project_id : Project ID
todo_id : The todo ID
content : The todo item ' s text
description : HTML description of the todo
assignee_ids : List of person IDs to assign
completion_subscriber_ids : List of person IDs to notify on completion
due_on : Due date in YYYY - MM - DD format
starts_on : Start date in YYYY - MM - DD format
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-08-20 14:42:55 +10:00
try :
2025-08-27 09:59:40 +10:00
# Guard against no-op updates
2026-01-21 20:42:05 +01:00
if all (
v is None
for v in [
content ,
description ,
assignee_ids ,
completion_subscriber_ids ,
notify ,
due_on ,
starts_on ,
]
) :
2025-08-27 09:59:40 +10:00
return {
" error " : " Invalid input " ,
2026-01-21 20:42:05 +01:00
" message " : " At least one field to update must be provided " ,
2025-08-27 09:59:40 +10:00
}
2025-08-20 14:42:55 +10:00
# Use lambda to properly handle keyword arguments
todo = await _run_sync (
lambda : client . update_todo (
2026-01-21 20:42:05 +01:00
project_id ,
todo_id ,
2025-08-20 14:42:55 +10:00
content = content ,
description = description ,
assignee_ids = assignee_ids ,
completion_subscriber_ids = completion_subscriber_ids ,
2025-08-27 09:59:40 +10:00
notify = notify ,
2025-08-20 14:42:55 +10:00
due_on = due_on ,
2026-01-21 20:42:05 +01:00
starts_on = starts_on ,
2025-08-20 14:42:55 +10:00
)
)
return {
" status " : " success " ,
" todo " : todo ,
2026-01-21 20:42:05 +01:00
" message " : " Todo updated successfully " ,
2025-08-20 14:42:55 +10:00
}
except Exception as e :
logger . error ( f " Error updating todo: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-08-20 14:42:55 +10:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-08-20 14:42:55 +10:00
@mcp.tool ( )
async def delete_todo ( project_id : str , todo_id : str ) - > Dict [ str , Any ] :
""" Delete a todo item.
2026-01-21 20:42:05 +01:00
2025-08-20 14:42:55 +10:00
Args :
project_id : Project ID
todo_id : The todo ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-08-20 14:42:55 +10:00
try :
await _run_sync ( client . delete_todo , project_id , todo_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Todo deleted successfully " }
2025-08-20 14:42:55 +10:00
except Exception as e :
logger . error ( f " Error deleting todo: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-08-20 14:42:55 +10:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-08-20 14:42:55 +10:00
@mcp.tool ( )
async def complete_todo ( project_id : str , todo_id : str ) - > Dict [ str , Any ] :
""" Mark a todo item as complete.
2026-01-21 20:42:05 +01:00
2025-08-20 14:42:55 +10:00
Args :
project_id : Project ID
todo_id : The todo ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-08-20 14:42:55 +10:00
try :
completion = await _run_sync ( client . complete_todo , project_id , todo_id )
return {
" status " : " success " ,
" completion " : completion ,
2026-01-21 20:42:05 +01:00
" message " : " Todo marked as complete " ,
2025-08-20 14:42:55 +10:00
}
except Exception as e :
logger . error ( f " Error completing todo: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-08-20 14:42:55 +10:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-08-20 14:42:55 +10:00
@mcp.tool ( )
async def uncomplete_todo ( project_id : str , todo_id : str ) - > Dict [ str , Any ] :
""" Mark a todo item as incomplete.
2026-01-21 20:42:05 +01:00
2025-08-20 14:42:55 +10:00
Args :
project_id : Project ID
todo_id : The todo ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-08-20 14:42:55 +10:00
try :
await _run_sync ( client . uncomplete_todo , project_id , todo_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Todo marked as incomplete " }
2025-08-20 14:42:55 +10:00
except Exception as e :
logger . error ( f " Error uncompleting todo: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-08-20 14:42:55 +10:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-08-20 14:42:55 +10:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def global_search ( query : str ) - > Dict [ str , Any ] :
""" Search projects, todos and campfire messages across all projects.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
query : Search query
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
search = BasecampSearch ( client = client )
results = await _run_sync ( search . global_search , query )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " query " : query , " results " : results }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error in global search: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def get_comments (
recording_id : str , project_id : str , page : int = 1
) - > Dict [ str , Any ] :
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
""" Get comments for a Basecamp item.
2026-01-10 00:33:00 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
recording_id : The item ID
project_id : The project ID
2026-01-10 00:33:00 +01:00
page : Page number for pagination ( default : 1 ) . Basecamp uses geared pagination :
page 1 has 15 results , page 2 has 30 , page 3 has 50 , page 4 + has 100.
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-10 00:33:00 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
2026-01-10 00:33:00 +01:00
result = await _run_sync ( client . get_comments , project_id , recording_id , page )
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
return {
" status " : " success " ,
2026-01-10 00:33:00 +01:00
" comments " : result [ " comments " ] ,
" count " : len ( result [ " comments " ] ) ,
" page " : page ,
" total_count " : result [ " total_count " ] ,
2026-01-21 20:42:05 +01:00
" next_page " : result [ " next_page " ] ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
except Exception as e :
logger . error ( f " Error getting comments: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
2025-09-11 20:50:06 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def create_comment (
recording_id : str , project_id : str , content : str
) - > Dict [ str , Any ] :
2025-09-11 20:50:06 +01:00
""" Create a comment on a Basecamp item.
Args :
recording_id : The item ID
project_id : The project ID
content : The comment content in HTML format
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
try :
2026-01-21 20:42:05 +01:00
comment = await _run_sync (
client . create_comment , recording_id , project_id , content
)
2025-09-11 20:50:06 +01:00
return {
" status " : " success " ,
" comment " : comment ,
2026-01-21 20:42:05 +01:00
" message " : " Comment created successfully " ,
2025-09-11 20:50:06 +01:00
}
except Exception as e :
logger . error ( f " Error creating comment: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-09-11 20:50:06 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def get_campfire_lines ( project_id : str , campfire_id : str ) - > Dict [ str , Any ] :
""" Get recent messages from a Basecamp campfire (chat room).
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
campfire_id : The campfire / chat room ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
lines = await _run_sync ( client . get_campfire_lines , project_id , campfire_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " campfire_lines " : lines , " count " : len ( lines ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error getting campfire lines: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def get_card_tables ( project_id : str ) - > Dict [ str , Any ] :
""" Get all card tables for a project.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
card_tables = await _run_sync ( client . get_card_tables , project_id )
return {
" status " : " success " ,
" card_tables " : card_tables ,
2026-01-21 20:42:05 +01:00
" count " : len ( card_tables ) ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
except Exception as e :
logger . error ( f " Error getting card tables: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def get_card_table ( project_id : str ) - > Dict [ str , Any ] :
""" Get the card table details for a project.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
card_table = await _run_sync ( client . get_card_table , project_id )
2026-01-21 20:42:05 +01:00
card_table_details = await _run_sync (
client . get_card_table_details , project_id , card_table [ " id " ]
)
return { " status " : " success " , " card_table " : card_table_details }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error getting card table: { e } " )
error_msg = str ( e )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
return {
" status " : " error " ,
" message " : f " Error getting card table: { error_msg } " ,
2026-01-21 20:42:05 +01:00
" debug " : error_msg ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def get_columns ( project_id : str , card_table_id : str ) - > Dict [ str , Any ] :
""" Get all columns in a card table.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
card_table_id : The card table ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
columns = await _run_sync ( client . get_columns , project_id , card_table_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " columns " : columns , " count " : len ( columns ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error getting columns: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def get_cards ( project_id : str , column_id : str ) - > Dict [ str , Any ] :
""" Get all cards in a column.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
column_id : The column ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
cards = await _run_sync ( client . get_cards , project_id , column_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " cards " : cards , " count " : len ( cards ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error getting cards: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def create_card (
project_id : str ,
column_id : str ,
title : str ,
content : Optional [ str ] = None ,
due_on : Optional [ str ] = None ,
notify : bool = False ,
) - > Dict [ str , Any ] :
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
""" Create a new card in a column.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
column_id : The column ID
title : The card title
content : Optional card content / description
due_on : Optional due date ( ISO 8601 format )
notify : Whether to notify assignees ( default : false )
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
2026-01-21 20:42:05 +01:00
card = await _run_sync (
client . create_card , project_id , column_id , title , content , due_on , notify
)
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
return {
" status " : " success " ,
" card " : card ,
2026-01-21 20:42:05 +01:00
" message " : f " Card ' { title } ' created successfully " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
except Exception as e :
logger . error ( f " Error creating card: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def get_column ( project_id : str , column_id : str ) - > Dict [ str , Any ] :
""" Get details for a specific column.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
column_id : The column ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
column = await _run_sync ( client . get_column , project_id , column_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " column " : column }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error getting column: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def create_column (
project_id : str , card_table_id : str , title : str
) - > Dict [ str , Any ] :
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
""" Create a new column in a card table.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
card_table_id : The card table ID
title : The column title
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
column = await _run_sync ( client . create_column , project_id , card_table_id , title )
return {
" status " : " success " ,
" column " : column ,
2026-01-21 20:42:05 +01:00
" message " : f " Column ' { title } ' created successfully " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
except Exception as e :
logger . error ( f " Error creating column: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def move_card ( project_id : str , card_id : str , column_id : str ) - > Dict [ str , Any ] :
""" Move a card to a new column.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
card_id : The card ID
column_id : The destination column ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
await _run_sync ( client . move_card , project_id , card_id , column_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : f " Card moved to column { column_id } " }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error moving card: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def complete_card ( project_id : str , card_id : str ) - > Dict [ str , Any ] :
""" Mark a card as complete.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
card_id : The card ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
await _run_sync ( client . complete_card , project_id , card_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Card marked as complete " }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error completing card: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
async def get_card ( project_id : str , card_id : str ) - > Dict [ str , Any ] :
""" Get details for a specific card.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
card_id : The card ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
card = await _run_sync ( client . get_card , project_id , card_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " card " : card }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
except Exception as e :
logger . error ( f " Error getting card: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
2026-01-21 20:42:05 +01:00
" error " : " OAuth token expired " ,
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def update_card (
project_id : str ,
card_id : str ,
title : Optional [ str ] = None ,
content : Optional [ str ] = None ,
due_on : Optional [ str ] = None ,
assignee_ids : Optional [ List [ str ] ] = None ,
) - > Dict [ str , Any ] :
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
""" Update a card.
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
Args :
project_id : The project ID
card_id : The card ID
title : The new card title
content : The new card content / description
due_on : Due date ( ISO 8601 format )
assignee_ids : Array of person IDs to assign to the card
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
try :
2026-01-21 20:42:05 +01:00
card = await _run_sync (
client . update_card ,
project_id ,
card_id ,
title ,
content ,
due_on ,
assignee_ids ,
)
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
return {
" status " : " success " ,
" card " : card ,
2026-01-21 20:42:05 +01:00
" message " : " Card updated successfully " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
except Exception as e :
logger . error ( f " Error updating card: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def get_daily_check_ins (
project_id : str , page : Optional [ int ] = None
) - > Dict [ str , Any ] :
2025-07-27 19:39:08 +01:00
""" Get project ' s daily checking questionnaire.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
page : Page number paginated response
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
if page is not None and not isinstance ( page , int ) :
page = 1
2026-01-21 20:42:05 +01:00
answers = await _run_sync (
client . get_daily_check_ins , project_id , page = page or 1
)
return { " status " : " success " , " campfire_lines " : answers , " count " : len ( answers ) }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error getting daily check ins: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def get_question_answers (
project_id : str , question_id : str , page : Optional [ int ] = None
) - > Dict [ str , Any ] :
2025-07-27 19:39:08 +01:00
""" Get answers on daily check-in question.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
question_id : The question ID
page : Page number paginated response
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
if page is not None and not isinstance ( page , int ) :
page = 1
2026-01-21 20:42:05 +01:00
answers = await _run_sync (
client . get_question_answers , project_id , question_id , page = page or 1
)
return { " status " : " success " , " campfire_lines " : answers , " count " : len ( answers ) }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error getting question answers: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
# Column Management Tools
@mcp.tool ( )
async def update_column ( project_id : str , column_id : str , title : str ) - > Dict [ str , Any ] :
""" Update a column title.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
column_id : The column ID
title : The new column title
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
column = await _run_sync ( client . update_column , project_id , column_id , title )
return {
" status " : " success " ,
" column " : column ,
2026-01-21 20:42:05 +01:00
" message " : " Column updated successfully " ,
2025-07-27 19:39:08 +01:00
}
except Exception as e :
logger . error ( f " Error updating column: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def move_column (
project_id : str , card_table_id : str , column_id : str , position : int
) - > Dict [ str , Any ] :
2025-07-27 19:39:08 +01:00
""" Move a column to a new position.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
card_table_id : The card table ID
column_id : The column ID
position : The new 1 - based position
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
2026-01-21 20:42:05 +01:00
await _run_sync (
client . move_column , project_id , column_id , position , card_table_id
)
return { " status " : " success " , " message " : f " Column moved to position { position } " }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error moving column: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def update_column_color (
project_id : str , column_id : str , color : str
) - > Dict [ str , Any ] :
2025-07-27 19:39:08 +01:00
""" Update a column color.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
column_id : The column ID
color : The hex color code ( e . g . , #FF0000)
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
2026-01-21 20:42:05 +01:00
column = await _run_sync (
client . update_column_color , project_id , column_id , color
)
2025-07-27 19:39:08 +01:00
return {
" status " : " success " ,
" column " : column ,
2026-01-21 20:42:05 +01:00
" message " : f " Column color updated to { color } " ,
2025-07-27 19:39:08 +01:00
}
except Exception as e :
logger . error ( f " Error updating column color: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def put_column_on_hold ( project_id : str , column_id : str ) - > Dict [ str , Any ] :
""" Put a column on hold (freeze work).
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
column_id : The column ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
await _run_sync ( client . put_column_on_hold , project_id , column_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Column put on hold " }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error putting column on hold: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def remove_column_hold ( project_id : str , column_id : str ) - > Dict [ str , Any ] :
""" Remove hold from a column (unfreeze work).
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
column_id : The column ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
await _run_sync ( client . remove_column_hold , project_id , column_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Column hold removed " }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error removing column hold: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def watch_column ( project_id : str , column_id : str ) - > Dict [ str , Any ] :
""" Subscribe to notifications for changes in a column.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
column_id : The column ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
await _run_sync ( client . watch_column , project_id , column_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Column notifications enabled " }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error watching column: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def unwatch_column ( project_id : str , column_id : str ) - > Dict [ str , Any ] :
""" Unsubscribe from notifications for a column.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
column_id : The column ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
await _run_sync ( client . unwatch_column , project_id , column_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Column notifications disabled " }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error unwatching column: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
2026-01-21 20:42:05 +01:00
# More Card Management Tools
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def uncomplete_card ( project_id : str , card_id : str ) - > Dict [ str , Any ] :
""" Mark a card as incomplete.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
card_id : The card ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
await _run_sync ( client . uncomplete_card , project_id , card_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Card marked as incomplete " }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error uncompleting card: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
# Card Steps (Sub-tasks) Management
@mcp.tool ( )
async def get_card_steps ( project_id : str , card_id : str ) - > Dict [ str , Any ] :
""" Get all steps (sub-tasks) for a card.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
card_id : The card ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
steps = await _run_sync ( client . get_card_steps , project_id , card_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " steps " : steps , " count " : len ( steps ) }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error getting card steps: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def create_card_step (
project_id : str ,
card_id : str ,
title : str ,
due_on : Optional [ str ] = None ,
assignee_ids : Optional [ List [ str ] ] = None ,
) - > Dict [ str , Any ] :
2025-07-27 19:39:08 +01:00
""" Create a new step (sub-task) for a card.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
card_id : The card ID
title : The step title
due_on : Optional due date ( ISO 8601 format )
assignee_ids : Array of person IDs to assign to the step
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
2026-01-21 20:42:05 +01:00
step = await _run_sync (
client . create_card_step , project_id , card_id , title , due_on , assignee_ids
)
2025-07-27 19:39:08 +01:00
return {
" status " : " success " ,
" step " : step ,
2026-01-21 20:42:05 +01:00
" message " : f " Step ' { title } ' created successfully " ,
2025-07-27 19:39:08 +01:00
}
except Exception as e :
logger . error ( f " Error creating card step: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def get_card_step ( project_id : str , step_id : str ) - > Dict [ str , Any ] :
""" Get details for a specific card step.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
step_id : The step ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
step = await _run_sync ( client . get_card_step , project_id , step_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " step " : step }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error getting card step: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def update_card_step (
project_id : str ,
step_id : str ,
title : Optional [ str ] = None ,
due_on : Optional [ str ] = None ,
assignee_ids : Optional [ List [ str ] ] = None ,
) - > Dict [ str , Any ] :
2025-07-27 19:39:08 +01:00
""" Update a card step.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
step_id : The step ID
title : The step title
due_on : Due date ( ISO 8601 format )
assignee_ids : Array of person IDs to assign to the step
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
2026-01-21 20:42:05 +01:00
step = await _run_sync (
client . update_card_step , project_id , step_id , title , due_on , assignee_ids
)
2025-07-27 19:39:08 +01:00
return {
" status " : " success " ,
" step " : step ,
2026-01-21 20:42:05 +01:00
" message " : f " Step updated successfully " ,
2025-07-27 19:39:08 +01:00
}
except Exception as e :
logger . error ( f " Error updating card step: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def delete_card_step ( project_id : str , step_id : str ) - > Dict [ str , Any ] :
""" Delete a card step.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
step_id : The step ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
await _run_sync ( client . delete_card_step , project_id , step_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Step deleted successfully " }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error deleting card step: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def complete_card_step ( project_id : str , step_id : str ) - > Dict [ str , Any ] :
""" Mark a card step as complete.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
step_id : The step ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
await _run_sync ( client . complete_card_step , project_id , step_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Step marked as complete " }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error completing card step: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def uncomplete_card_step ( project_id : str , step_id : str ) - > Dict [ str , Any ] :
""" Mark a card step as incomplete.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : The project ID
step_id : The step ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
await _run_sync ( client . uncomplete_card_step , project_id , step_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Step marked as incomplete " }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error uncompleting card step: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
# Attachments, Events, and Webhooks
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def create_attachment (
file_path : str , name : str , content_type : Optional [ str ] = None
) - > Dict [ str , Any ] :
2025-07-27 19:39:08 +01:00
""" Upload a file as an attachment.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
file_path : Local path to file
name : Filename for Basecamp
content_type : MIME type
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
2026-01-21 20:42:05 +01:00
result = await _run_sync (
client . create_attachment ,
file_path ,
name ,
content_type or " application/octet-stream " ,
)
return { " status " : " success " , " attachment " : result }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error creating attachment: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def get_events ( project_id : str , recording_id : str ) - > Dict [ str , Any ] :
""" Get events for a recording.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : Project ID
recording_id : Recording ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
events = await _run_sync ( client . get_events , project_id , recording_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " events " : events , " count " : len ( events ) }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error getting events: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def get_webhooks ( project_id : str ) - > Dict [ str , Any ] :
""" List webhooks for a project.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : Project ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
hooks = await _run_sync ( client . get_webhooks , project_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " webhooks " : hooks , " count " : len ( hooks ) }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error getting webhooks: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def create_webhook (
project_id : str , payload_url : str , types : Optional [ List [ str ] ] = None
) - > Dict [ str , Any ] :
2025-07-27 19:39:08 +01:00
""" Create a webhook.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : Project ID
payload_url : Payload URL
types : Event types
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
hook = await _run_sync ( client . create_webhook , project_id , payload_url , types )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " webhook " : hook }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error creating webhook: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def delete_webhook ( project_id : str , webhook_id : str ) - > Dict [ str , Any ] :
""" Delete a webhook.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : Project ID
webhook_id : Webhook ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
await _run_sync ( client . delete_webhook , project_id , webhook_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Webhook deleted " }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error deleting webhook: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
# Document Management
@mcp.tool ( )
async def get_documents ( project_id : str , vault_id : str ) - > Dict [ str , Any ] :
""" List documents in a vault.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : Project ID
vault_id : Vault ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
docs = await _run_sync ( client . get_documents , project_id , vault_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " documents " : docs , " count " : len ( docs ) }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error getting documents: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def get_document ( project_id : str , document_id : str ) - > Dict [ str , Any ] :
""" Get a single document.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : Project ID
document_id : Document ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
doc = await _run_sync ( client . get_document , project_id , document_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " document " : doc }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error getting document: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def create_document (
project_id : str , vault_id : str , title : str , content : str
) - > Dict [ str , Any ] :
2025-07-27 19:39:08 +01:00
""" Create a document in a vault.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : Project ID
vault_id : Vault ID
title : Document title
content : Document HTML content
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
2026-01-21 20:42:05 +01:00
doc = await _run_sync (
client . create_document , project_id , vault_id , title , content
)
return { " status " : " success " , " document " : doc }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error creating document: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def update_document (
project_id : str ,
document_id : str ,
title : Optional [ str ] = None ,
content : Optional [ str ] = None ,
) - > Dict [ str , Any ] :
2025-07-27 19:39:08 +01:00
""" Update a document.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : Project ID
document_id : Document ID
title : New title
content : New HTML content
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
2026-01-21 20:42:05 +01:00
doc = await _run_sync (
client . update_document , project_id , document_id , title , content
)
return { " status " : " success " , " document " : doc }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error updating document: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
@mcp.tool ( )
async def trash_document ( project_id : str , document_id : str ) - > Dict [ str , Any ] :
""" Move a document to trash.
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
Args :
project_id : Project ID
document_id : Document ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-27 19:39:08 +01:00
try :
await _run_sync ( client . trash_document , project_id , document_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " message " : " Document trashed " }
2025-07-27 19:39:08 +01:00
except Exception as e :
logger . error ( f " Error trashing document: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-27 19:39:08 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-27 19:39:08 +01:00
2025-07-30 10:22:42 +01:00
# Upload Management
@mcp.tool ( )
2026-01-21 20:42:05 +01:00
async def get_uploads (
project_id : str , vault_id : Optional [ str ] = None
) - > Dict [ str , Any ] :
2025-07-30 10:22:42 +01:00
""" List uploads in a project or vault.
2026-01-21 20:42:05 +01:00
2025-07-30 10:22:42 +01:00
Args :
project_id : Project ID
vault_id : Optional vault ID to limit to specific vault
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-30 10:22:42 +01:00
try :
uploads = await _run_sync ( client . get_uploads , project_id , vault_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " uploads " : uploads , " count " : len ( uploads ) }
2025-07-30 10:22:42 +01:00
except Exception as e :
logger . error ( f " Error getting uploads: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-30 10:22:42 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-30 10:22:42 +01:00
@mcp.tool ( )
async def get_upload ( project_id : str , upload_id : str ) - > Dict [ str , Any ] :
""" Get details for a specific upload.
2026-01-21 20:42:05 +01:00
2025-07-30 10:22:42 +01:00
Args :
project_id : Project ID
upload_id : Upload ID
"""
client = _get_basecamp_client ( )
if not client :
return _get_auth_error_response ( )
2026-01-21 20:42:05 +01:00
2025-07-30 10:22:42 +01:00
try :
upload = await _run_sync ( client . get_upload , project_id , upload_id )
2026-01-21 20:42:05 +01:00
return { " status " : " success " , " upload " : upload }
2025-07-30 10:22:42 +01:00
except Exception as e :
logger . error ( f " Error getting upload: { e } " )
if " 401 " in str ( e ) and " expired " in str ( e ) . lower ( ) :
return {
" error " : " OAuth token expired " ,
2026-01-21 20:42:05 +01:00
" message " : " Your Basecamp OAuth token expired during the API call. Please re-authenticate by visiting http://localhost:8000 and completing the OAuth flow again. " ,
2025-07-30 10:22:42 +01:00
}
2026-01-21 20:42:05 +01:00
return { " error " : " Execution error " , " message " : str ( e ) }
2025-07-30 10:22:42 +01:00
2025-07-27 19:39:08 +01:00
# 🎉 COMPLETE FastMCP server with ALL 46 Basecamp tools migrated!
🚀 MAJOR: Migrate to official FastMCP framework
- Create new basecamp_fastmcp.py using official Anthropic MCP SDK
- Migrate 19 essential tools following official MCP best practices
- Maintain identical tool names and API compatibility with original server
- Add FastMCP dependencies (mcp[cli]>=1.2.0, httpx, anyio)
- Use async/await with anyio.to_thread for sync→async bridge
- Follow official logging practices (stderr + file, not stdout)
- Full compatibility with Cursor and Claude Desktop
Core tools migrated:
✅ Projects: get_projects, get_project, get_todolists, get_todos
✅ Search: search_basecamp, global_search
✅ Communication: get_comments, get_campfire_lines
✅ Card Tables: get_card_tables, get_card_table, get_columns, get_cards
✅ Card Management: create_card, get_card, update_card, move_card, complete_card
✅ Column Management: get_column, create_column
Next: Update config generation for dual-run support
2025-07-27 19:30:59 +01:00
if __name__ == " __main__ " :
logger . info ( " Starting Basecamp FastMCP server " )
# Run using official MCP stdio transport
2026-01-21 20:42:05 +01:00
mcp . run ( transport = " stdio " )