Skip to main content
Glama
CLAUDE.md13.8 kB
# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Agent MCP Gateway is an MCP server that acts as a proxy/gateway to multiple downstream MCP servers. It enables per-agent/subagent access control, solving Claude Code's context window waste where all MCP tool definitions load upfront instead of being discovered on-demand. **Core Problem:** When multiple MCP servers are configured, all tools from all servers (5,000-50,000+ tokens) load into every agent's context at startup. This wastes 80-95% of context on unused tools. **Solution:** Gateway exposes only 3 minimal tools (~2k tokens) that allow agents to discover and request specific tools on-demand based on configurable access rules. ## Tech Stack - **Python 3.12+** (required) - **FastMCP 2.0** (version 2.13.0.1+) - MCP server framework - **uv** - Package and project manager ## Development Commands ```bash # Install dependencies uv sync # Run gateway uv run python main.py # Add dependency uv add <package-name> # Add dev dependency uv add --dev <package-name> # Update dependencies uv lock --upgrade ``` See README.md for production MCP client configuration. ## Release Management **CRITICAL:** NEVER bump version in `pyproject.toml` without explicit user approval. **When version is updated:** - Update ALL version files together: `pyproject.toml`, `server.json` (root `version` and `packages[0].version`), and `CHANGELOG.md` - Run `uv lock` to sync lockfile - DO NOT release without user approval **To release:** See `docs/release-process.md` for complete workflow. Key: pushing the git tag (not just commits) triggers automated PyPI, MCP Registry, and GitHub release publishing via GitHub Actions. ## Architecture ### Gateway Model ``` Agent → Gateway (3 tools, ~2k tokens) → Policy Engine → Downstream MCP Servers (100s of tools) ↓ Audit Log ``` **Traditional MCP:** All tools loaded upfront → Agent discovers what's available **Gateway MCP:** Minimal interface loaded → Agent requests what it needs → Gateway provides filtered access ### Core Components 1. **Gateway Server** - FastMCP-based, exposes 3 gateway tools + 1 debug tool, uses `FastMCP.as_proxy()` for downstream proxying 2. **Policy Engine** - Stateless evaluation with deny-before-allow precedence, wildcard support 3. **Proxy Layer** - Transparent forwarding, stdio/HTTP transports, OAuth auto-detection 4. **Session Manager** - Per-agent isolation via FastMCP context ### Gateway Tools (Exposed to Agents) ```python list_servers(agent_id: Optional[str], include_metadata: bool) -> List[Server] get_server_tools(agent_id: Optional[str], server: str, names: Optional[List[str]], pattern: Optional[str], max_schema_tokens: Optional[int]) -> List[Tool] execute_tool(agent_id: Optional[str], server: str, tool: str, args: dict, timeout_ms: Optional[int]) -> Any ``` All tools accept optional `agent_id` (uses fallback chain if not provided). See README.md for detailed parameter descriptions. ### Configuration Structure **MCP Servers Config** (`.mcp.json`): ```json { "mcpServers": { "server-name": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-name"], "env": {"API_KEY": "${API_KEY}"} } } } ``` **Gateway Rules Config** (`.mcp-gateway-rules.json`): ```json { "agents": { "agent-name": { "allow": {"servers": ["server-name"], "tools": {"server-name": ["*"]}}, "deny": {"tools": {"server-name": ["dangerous_*"]}} } }, "defaults": {"deny_on_missing_agent": false} } ``` See `config/*.example` files for complete examples and README.md for detailed configuration guide. ### Policy Evaluation Rules (CRITICAL - DO NOT CHANGE) **Exact precedence order with short-circuit evaluation:** 1. Explicit deny rules → if match, DENY and STOP 2. Wildcard deny rules → if match, DENY and STOP 3. Explicit allow rules → if match, ALLOW and STOP 4. Wildcard allow rules → if match, ALLOW and STOP 5. Implicit grant - if server allowed but no tool rules specified for that server → ALLOW and STOP 6. Default policy → DENY **Critical principle:** All deny rules (explicit + wildcard) checked before any allow rules. **Implicit Grant Behavior:** - If agent has server access AND no `allow.tools.{server}` entry → all tools from that server implicitly granted - `allow.tools.{server}` entries are server-specific and narrow access for that server only - `deny.tools.{server}` entries are server-specific and filter tools for that server only (evaluated in steps 1-2) ### Agent Identity All gateway tools accept optional `agent_id` parameter. When not provided, uses fallback chain: 1. Explicit `agent_id` in tool call (highest priority) 2. `GATEWAY_DEFAULT_AGENT` env var 3. Agent named "default" in rules (if `deny_on_missing_agent` is false) 4. Error if none configured See `docs/claude-code-subagent-mcp-limitations.md` for single-agent vs multi-agent configuration details. ### OAuth Support Gateway auto-detects OAuth-protected downstream servers (Notion, GitHub, etc.) via 401 responses. Zero configuration needed - just add server URL to `.mcp.json`. Browser auth happens once, then tokens are cached. See `docs/oauth-user-guide.md` for setup and troubleshooting. ## Tool Description Standards Gateway tools must be **self-documenting** - agents in Claude Desktop and similar MCP clients have no custom prompts, only tool descriptions. **Concise is key:** Default assumption is Claude is already smart. Only add context Claude doesn't have. **Tool descriptions:** - Single sentence, include workflow if relevant - No Args/Returns sections (use `Annotated[Type, "description"]` and Pydantic output models instead) **Parameter descriptions:** 4-7 words, actionable (e.g., "leave empty if not provided to you", "Server name from list_servers") **Output field descriptions:** 3-6 words, clarify ambiguities (e.g., "less than total_available is normal due to filtering") ## FastMCP 2.0 Implementation Patterns Key patterns used in this project: - **Gateway creation:** `FastMCP.as_proxy(mcp_config)` for automatic downstream proxying - **Middleware:** `AgentAccessControl(Middleware)` with `on_call_tool` hook for policy enforcement - **Custom tools:** `@gateway.tool` decorator with `Context` for state access - **State management:** `gateway.set_state()` and `ctx.get_state()` for config sharing See `docs/fastmcp-implementation-guide.md` for complete code examples and detailed patterns. ## Implementation Milestones - **M0: Foundation** - Gateway with stdio, config loading, list_servers, audit logging - **M1: Core** - get_server_tools, execute_tool, session isolation, metrics - **M2: Production** - HTTP transport, health checks, error handling - **M3: DX** - Single-agent mode, config validation CLI, Docker container ## Environment Variables | Variable | Default | Purpose | |----------|---------|---------| | `GATEWAY_MCP_CONFIG` | `.mcp.json` | MCP server definitions path | | `GATEWAY_RULES` | `.mcp-gateway-rules.json` | Agent policies path | | `GATEWAY_DEFAULT_AGENT` | None | Default agent when agent_id not provided | | `GATEWAY_DEBUG` | `false` | Enable debug mode + get_gateway_status tool | | `GATEWAY_AUDIT_LOG` | `~/.cache/agent-mcp-gateway/logs/audit.jsonl` | Audit log path | | `GATEWAY_TRANSPORT` | `stdio` | Transport type (stdio or http) | | `GATEWAY_INIT_STRATEGY` | `eager` | Initialization strategy (eager or lazy) | **Note:** `GATEWAY_DEBUG=true` enables `get_gateway_status` diagnostic tool. For security considerations and detailed env var descriptions, see README.md Environment Variables Reference. ## Error Codes - `DENIED_BY_POLICY` - Agent lacks permission for requested operation - `SERVER_UNAVAILABLE` - Downstream MCP server unreachable - `TOOL_NOT_FOUND` - Requested tool doesn't exist - `INVALID_AGENT_ID` - Missing or unknown agent identifier - `FALLBACK_AGENT_NOT_IN_RULES` - Configured fallback agent not found in gateway rules - `NO_FALLBACK_CONFIGURED` - No agent_id provided and no fallback agent configured - `TIMEOUT` - Operation exceeded time limit ## Performance Targets - `list_servers`: <50ms (P95) - `get_server_tools`: <300ms (P95) - `execute_tool` overhead: <30ms (P95) - Overall added latency: <100ms (P95) ## Key Documentation - `/docs/specs/PRD.md` - Complete product requirements and specifications - `/docs/fastmcp-implementation-guide.md` - FastMCP 2.0 patterns and examples - `/docs/claude-code-subagent-mcp-limitations.md` - Agent identity workaround details - `/docs/pypi-readme-transformation.md` - Build-time README transformation for PyPI compatibility - `/docs/release-process.md` - Version bumping, building, and publishing workflow for PyPI releases ## Design Philosophy - **Zero modifications to downstream MCP servers** - Full compatibility with existing servers - **Context preservation** - 90%+ reduction in upfront token usage - **Deny-before-allow security** - Safe by default - **Principle of least privilege** - No implicit "allow all" access, even with fallbacks - **Transparent proxying** - Downstream servers unaware of gateway - **Audit everything** - Complete operation logging - **Configuration-driven** - No code changes for permission updates - **Flexible agent identity** - Optional agent_id with secure fallback chain ## Documentation Guidelines ### Writing Principles When writing documentation for this project, apply the **"Concise is key" principle**: **Context window is a public good.** Default assumption: **Claude is already very smart** Challenge each piece of information: - "Does Claude really need this explanation?" - "Can I assume Claude knows this?" - "Does this paragraph justify its token cost?" **Know Your Audience:** Documentation has two types of consumers: - **Human end-users** - Need sufficient context, practical examples, and clear explanations - **AI coding agents (like Claude Code)** - Already possess broad knowledge; need only project-specific, essential context **Balance Requirements:** - Not too verbose (exhausting for humans to read) - Not too shallow (missing key information) - Not too token-heavy (LLMs understand general concepts; focus on what's unique to this project) **Reference, Don't Repeat:** Information well-documented elsewhere should be referenced, not duplicated. ### Permanent Documentation (committed to git) Store in appropriate `docs/` subdirectories based on content type: **docs/milestones/** - Milestone completion reports (m0-success-report.md, m1-success-report.md, etc.) - Success criteria validation - Performance metrics and test results - Historical records of milestone achievements **docs/specs/** - Product requirements (PRD.md) - Milestone specifications (m0-foundation.md, m1-core.md, m2-production.md, m3-dx.md) - Technical specifications - Architecture decision records **docs/** (root) - Quick start guides (quickstart-config.md) - Framework summaries (validation-framework-summary.md) - Implementation guides (fastmcp-implementation-guide.md) - General documentation that doesn't fit other categories ### Temporary Documentation (NOT committed to git) Store in `docs/temp/` (gitignored) for work-in-progress content: **docs/temp/** - Work-in-progress feature documentation - Troubleshooting notes for open bugs - Investigation findings (not yet resolved) - Draft documentation being reviewed - Session handoff notes (use /session-doc slash command) - Temporary reference materials **Examples:** - `docs/temp/bug-hot-reload-investigation.md` - Active bug troubleshooting - `docs/temp/feature-draft-http-transport.md` - Feature design in progress - `docs/temp/session-2025-10-30.md` - Development session context ### Important Rules 1. **No documentation in project root** - All docs must be in `docs/` or its subdirectories 2. **Use relative paths** - Never use absolute paths like `/Users/username/...` in documentation 3. **Choose permanent vs temporary carefully** - If it's valuable for future reference, it's permanent 4. **Temporary docs are truly temporary** - Move to permanent location or delete when work is done 5. **Update existing docs** - Don't create duplicates; update existing documentation when appropriate 6. **Keep docs concise** - Reference other docs instead of duplicating content; only include information that is necessary, valuable, or unique 7. **No comments in JSON files** - JSON doesn't support comments; users should be able to copy example files without cleaning content 8. **Reference, don't duplicate** - If information is well-documented elsewhere, link to it rather than repeating it ### Documentation Content Guidelines **What to include in each file type:** **CLAUDE.md (this file):** - High-level overviews with links to detailed docs - Critical implementation patterns specific to this project - Information Claude needs for immediate context - References to detailed documentation for deep dives **README.md:** - User-facing quick start and usage instructions - Essential configuration examples - Links to detailed guides for advanced topics **Configuration Examples (config/*.example):** - Valid, copy-paste ready configurations only - No comments or explanations (especially not in JSON files) - Examples should be self-explanatory through naming - Documentation belongs in README.md or dedicated guides **Detailed Guides (docs/*.md):** - Comprehensive explanations and tutorials - Troubleshooting procedures - Architecture deep dives - Reference material for specific features ### Documentation Naming Convention Use kebab-case for all documentation files unless the user specifies otherwise or the file already has a well-established casing convention (e.g., README.md, CLAUDE.md, PRD.md).

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/roddutra/agent-mcp-gateway'

If you have feedback or need assistance with the MCP directory API, please join our Discord server