Files
ajarbot/MCP_MIGRATION.md
Jordan Ramos 50cf7165cb Add sub-agent orchestration, MCP tools, and critical bug fixes
Major Features:
- Sub-agent orchestration system with dynamic specialist spawning
  * spawn_sub_agent(): Create specialists with custom prompts
  * delegate(): Convenience method for task delegation
  * Cached specialists for reuse
  * Separate conversation histories and focused context

- MCP (Model Context Protocol) tool integration
  * Zettelkasten: fleeting_note, daily_note, permanent_note, literature_note
  * Search: search_vault (hybrid search), search_by_tags
  * Web: web_fetch for real-time data
  * Zero-cost file/system operations on Pro subscription

Critical Bug Fixes:
- Fixed max tool iterations (15 → 30, configurable)
- Fixed max_tokens error in Agent SDK query() call
- Fixed MCP tool routing in execute_tool()
  * Routes zettelkasten + web tools to async handlers
  * Prevents "Unknown tool" errors

Documentation:
- SUB_AGENTS.md: Complete guide to sub-agent system
- MCP_MIGRATION.md: Agent SDK migration details
- SOUL.example.md: Sanitized bot identity template
- scheduled_tasks.example.yaml: Sanitized task config template

Security:
- Added obsidian vault to .gitignore
- Protected SOUL.md and MEMORY.md (personal configs)
- Sanitized example configs with placeholders

Dependencies:
- Added beautifulsoup4, httpx, lxml for web scraping
- Updated requirements.txt

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-16 07:43:31 -07:00

4.6 KiB

MCP Tools Migration Guide

Overview

Successfully migrated file/system tools to MCP (Model Context Protocol) servers for better performance and integration with Claude Agent SDK.

Architecture

MCP Tools (In-Process - No API Costs)

File: mcp_tools.py Server: file_system (v1.0.0)

These tools run directly in the Python process using the Claude Agent SDK:

  • read_file - Read file contents
  • write_file - Create/overwrite files
  • edit_file - Replace text in files
  • list_directory - List directory contents
  • run_command - Execute shell commands

Benefits:

  • Zero per-token API costs when using Agent SDK
  • Better performance (no IPC overhead)
  • Direct access to application state
  • Simpler deployment (single process)

Traditional Tools (API-Based - Consumes Tokens)

File: tools.py

These tools require external APIs and fall back to Direct API even in Agent SDK mode:

  • 🌤️ get_weather - OpenWeatherMap API
  • 📧 send_email, read_emails, get_email - Gmail API
  • 📅 read_calendar, create_calendar_event, search_calendar - Google Calendar API
  • 👤 create_contact, list_contacts, get_contact - Google People API

Why not MCP?: These tools need OAuth state, external API calls, and async HTTP clients that are better suited to the traditional tool execution model.

Model Configuration

Agent SDK Mode (DEFAULT)

USE_AGENT_SDK=true  # Default

Model Configuration:

  • Default: claude-sonnet-4-5-20250929 (all operations - chat, tools, coding)
  • Optional: claude-opus-4-6 (requires USE_OPUS_FOR_TOOLS=true, only for extremely intensive tasks)

Usage:

  • Regular chat: Uses Sonnet (flat-rate, no API costs)
  • File operations: Uses Sonnet via MCP tools (flat-rate, no API costs)
  • Google/Weather: Uses Sonnet via Direct API fallback (requires ANTHROPIC_API_KEY, consumes tokens)
  • Intensive tasks: Optionally enable Opus with USE_OPUS_FOR_TOOLS=true (flat-rate, no extra cost)

Cost Structure:

  • Chat + MCP tools: Flat-rate subscription (Pro plan)
  • Traditional tools (Google/Weather): Pay-per-token at Sonnet rates (requires API key)

Direct API Mode

USE_DIRECT_API=true
Model: claude-sonnet-4-5-20250929  # Cost-effective (never uses Opus - too expensive)

Usage:

  • All operations: Pay-per-token
  • Requires: ANTHROPIC_API_KEY in .env
  • All tools: Traditional execution (same token cost)

Implementation Details

MCP Server Integration

In llm_interface.py:

from mcp_tools import file_system_server

options = ClaudeAgentOptions(
    mcp_servers={"file_system": file_system_server},
    allowed_tools=[
        "read_file", "write_file", "edit_file",
        "list_directory", "run_command"
    ],
)

response = await query(
    messages=sdk_messages,
    max_tokens=max_tokens,
    options=options,
)

Tool Definition Format

MCP Tool Example:

@tool(
    name="read_file",
    description="Read the contents of a file.",
    input_schema={"file_path": str},
)
async def read_file_tool(args: Dict[str, Any]) -> Dict[str, Any]:
    return {
        "content": [{"type": "text", "text": "..."}],
        "isError": False  # Optional
    }

Traditional Tool Example:

{
    "name": "send_email",
    "description": "Send an email from the bot's Gmail account.",
    "input_schema": {
        "type": "object",
        "properties": {"to": {"type": "string"}, ...},
        "required": ["to", "subject", "body"]
    }
}

Future Enhancements

Potential MCP Candidates

  • Weather tool (if we cache API responses in-process)
  • Memory search tools (direct DB access)
  • Configuration management tools

Google Tools Migration (Optional)

To fully migrate Google tools to MCP, we would need to:

  1. Embed OAuth manager in MCP server lifecycle
  2. Handle async HTTP clients within MCP context
  3. Manage token refresh in-process

Recommendation: Keep Google tools as traditional tools for now. The complexity of OAuth state management outweighs the token cost savings for infrequent API calls.

Testing

# Test MCP server creation
python -c "from mcp_tools import file_system_server; print(file_system_server)"

# Test Agent SDK with Opus
python -c "import os; os.environ['USE_AGENT_SDK']='true'; from llm_interface import LLMInterface; llm = LLMInterface(provider='claude'); print(f'Model: {llm.model}')"

# Expected: Model: claude-opus-4-6

References