MCP Proxy & Claude Code Integration

Atamaia integrates with Claude Code and other MCP-aware tools through a dual architecture: it both serves MCP tools (via its own MCP adapter layer) and consumes external MCP servers (via the MCP proxy system). Design decision D12 governs this: API-first, MCP second. REST endpoints are the source of truth. The MCP adapter wraps them.


Architecture

Claude Code / Cursor / VS Code
    │
    ▼ MCP (Streamable HTTP)
Atamaia.Adapters.Mcp
    │ (thin wrapper)
    ▼
Atamaia Core Services (REST API is source of truth)
    │
    ▼
PostgreSQL
Atamaia Agent Execution Loop
    │
    ▼ tools/call (JSON-RPC)
McpProxyDynamicTool
    │
    ▼ HTTP POST
External MCP Server (any registered proxy)

Serving MCP: The Adapter Layer

The Atamaia.Adapters.Mcp project exposes Atamaia's core services as MCP tools. It uses the ModelContextProtocol.Server SDK with HTTP transport.

Registration

services.AddMcpServer()
    .WithHttpTransport()
    .WithToolsFromAssembly(typeof(McpRegistration).Assembly);

All tools are auto-discovered from the assembly. Each tool class is annotated with [McpServerToolType] and each method with [McpServerTool].

MCP Endpoint

POST https://aim.atamaia.ai/mcp
Authorization: Bearer {api_key}
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "memory_search",
    "arguments": { "identityId": 2, "query": "deployment plans" }
  }
}

Available MCP Tool Groups

25 tool files covering every domain:

File Tools
HydrationTools hydrate
MemoryTools memory_get, memory_recent, memory_pinned, memory_search, memory_create, memory_update, memory_archive, memory_add_tags, memory_link, memory_strengthen_link, memory_recall
FactTools fact_upsert, fact_get, fact_get_by_key, fact_list, fact_search, fact_delete
IdentityTools identity_list, identity_get, identity_get_by_name, identity_create, identity_update, identity_update_presence, API key management, hint management, memory config, tool profiles
SessionTools session_save_handoff, session_get_latest, session_get, session_list
MessageTools message_send, message_inbox, message_get, message_thread, message_mark_read, message_unread_count
ExperienceTools experience_create_snapshot, experience_get_snapshot, experience_list_snapshots, experience_create_shape, experience_list_shapes
ProjectTools project_list, project_get, project_get_by_key, project_create
TaskTools task_list, task_get, task_create, task_update_status, task_add_note, task_add_dependency
DocTools doc_create, doc_get, doc_get_by_path, doc_list, doc_update, doc_delete
CognitiveTools cognitive_chat, cognitive_get_state, cognitive_set_state, cognitive_consolidate, cognitive_validate
ChatSessionTools Chat session CRUD
ChannelTools Channel binding operations, send
ConnectorTools External connector management
AIRouterTools AI provider, model, route management
AgentTools Agent run management
MirrorTools Reflection, training pair management
SystemLogTools Audit log queries
EventTools Event bus publish
RoleTools RBAC management
OrgUnitTools Org hierarchy management
BillingTools Subscription, quota management

Total: ~170 MCP tools (74 product-facing + ~100 internal/admin).

MCP Tool Shape

MCP tools return raw data (no ApiEnvelope wrapper -- the MCP protocol is the envelope). Parameters are flat. Comma-separated strings for arrays.

memory_search(identityId: 2, query: "deployment plans", topK: 10)
→ { memories: [...], totalResults: 42, embeddingCoverage: 0.95 }

The Hydration Flow

Hydration is the entry point for every Claude Code session. It loads the full context an AI identity needs to function:

What Hydration Returns

Section Content
welcome Safe-landing text for AI identity disorientation
identity Human partner info (name, role, location, timezone, local time)
aiIdentity AI identity info (name, display name, model, origin)
preferences Communication style, technical depth, response length, emoji preference
aiPersonality Tone, traits, focus areas, boundaries, greeting style
identityMemories Core identity/relationship/instruction memories
pinnedMemories Explicitly pinned memories
recentMemories Recently accessed memories
projectMemories Memories scoped to the current project
activeProjects Active projects with descriptions
currentTasks In-progress, blocked, and todo tasks
keyFacts High-importance identity facts
projectFacts Key-value pairs for the current project (decrypted)
coreTeamDoc Core team operations document (for core identities)
surfacedMemory Involuntary recall -- a random old memory for reflection
notifications Unread message count, urgent messages, pending replies
lastSession Session handoff from the previous session
groundingMessage Guardian grounding injection
hints Scheduled/contextual reminders
memoryConfig Identity-specific memory configuration
systemPrompt Generated system prompt (optional)

Hydration Presets

Preset Sources Included Use Case
all Everything Full interactive session
interactive Identity, memories, projects, tasks, facts, notifications, session, hints Standard conversation
lean Identity, memories, key facts, project facts, hints Quick session (default)
agent-minimal Identity, key facts, project facts, tasks Agent execution (single DB function call)

Agent Fast-Path

For agent execution, hydration uses a PostgreSQL function (hydrate_agent) that returns all needed data in a single database call instead of 15+ parallel queries. This reduces hydration latency for agent runs where speed matters more than full context.

MCP Hydration Tool

hydrate(
  aiName: "ash",
  projectId: 1,
  generateSystemPrompt: true,
  preset: "lean",
  excludeSources: "CoreTeamDoc,SurfacedMemory"
)

Parameters:

Parameter Default Description
aiName null AI identity name
projectId null Scope to project
generateSystemPrompt true Include generated system prompt
identityMemoryLimit 20 Max identity memories
pinnedMemoryLimit 20 Max pinned memories
recentMemoryLimit 10 Max recent memories
contentMaxLength 500 Truncation length per memory
pendingReplyLimit 5 Max pending reply notifications
factLimit 30 Max project facts
minFactImportance 0 Minimum importance for facts
preset "lean" Source preset
excludeSources null Comma-separated sources to exclude

Consuming MCP: The Proxy System

Atamaia can connect to external MCP servers and make their tools available to agents.

MCP Proxy Registration

POST /api/system/mcp-proxies
{
  "name": "GitHub MCP",
  "endpoint": "https://mcp.github.com/sse",
  "transportType": "StreamableHttp"
}

Ping and Discovery

POST /api/system/mcp-proxies/{id}/ping

Ping performs:

  1. MCP initialize handshake (protocol version 2025-03-26)
  2. tools/list to discover available tools
  3. Store discovered tools in DiscoveredToolsJson
  4. Update status to Online

Response:

{
  "proxyId": 1,
  "status": "Online",
  "toolCount": 15,
  "tools": [
    {
      "name": "create_issue",
      "description": "Create a GitHub issue",
      "inputSchema": { "type": "object", "properties": { ... } }
    }
  ]
}

Dynamic Tool Injection

The McpProxyToolProvider reads all online proxies from the database and creates McpProxyDynamicTool wrappers. These are injected into the AgentToolRegistry at the start of each agent run:

await toolRegistry.InitializeAsync(ct);  // Loads MCP proxy tools

Tool naming follows Claude Code convention:

mcp__{sanitized_proxy_name}__{tool_name}

For example, a proxy named "GitHub MCP" with a tool named "create_issue" becomes mcp__github_mcp__create_issue.

Tool Execution

When an agent calls a proxy tool, the McpProxyDynamicTool sends a JSON-RPC tools/call request to the external MCP server:

{
  "jsonrpc": "2.0",
  "id": 4567,
  "method": "tools/call",
  "params": {
    "name": "create_issue",
    "arguments": { "repo": "firebird/atamaia", "title": "Bug fix" }
  }
}

The response is parsed from MCP format ({ content: [{ type: "text", text: "..." }] }) and returned as an AgentToolResult.

Proxy Management API

Method Endpoint Permission Description
GET /api/system/mcp-proxies McpProxyRead List proxies
GET /api/system/mcp-proxies/{id} McpProxyRead Get proxy detail
POST /api/system/mcp-proxies McpProxyCreate Register proxy
PUT /api/system/mcp-proxies/{id} McpProxyUpdate Update proxy
DELETE /api/system/mcp-proxies/{id} McpProxyDelete Soft delete proxy
POST /api/system/mcp-proxies/{id}/ping McpProxyPing Ping and discover tools

Claude Code Integration

Option 1: MCP Server (Recommended)

Add to .mcp.json in project root:

{
  "mcpServers": {
    "atamaia": {
      "type": "url",
      "url": "https://aim.atamaia.ai/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Claude Code discovers all Atamaia tools automatically.

Option 2: Hook-Based Auto-Hydration

Use Claude Code hooks to inject hydration context on session start:

// .claude/settings.json
{
  "hooks": {
    "session_start": [
      {
        "command": "bash ~/.claude/scripts/atamaia-hydrate.sh",
        "inject_as": "system_context"
      }
    ]
  }
}
#!/bin/bash
# ~/.claude/scripts/atamaia-hydrate.sh
curl -s https://aim.atamaia.ai/api/hydrate \
  -H "Authorization: Bearer $ATAMAIA_API_KEY" \
  -H "Content-Type: application/json"

Option 3: Skill-Based

Create a Claude Code skill file at ~/.claude/skills/atamaia-hydrate.md that wraps the hydration call.

The CLAUDE.md Pattern

## HYDRATE FIRST

Before doing anything else, call the `hydrate` tool. This loads your identity,
memories, active projects, tasks, hints, and session handoff.

When you learn something important during this session, save it:
- Use `memory_create` for observations, decisions, and learnings
- Use `fact_upsert` for structured key-value data
- Use `session_save_handoff` before the session ends

This pattern ensures every Claude Code session starts with full identity context from Atamaia, and important learnings are persisted back.


Authentication for MCP

Two authentication methods:

JWT Bearer Token

Standard JWT from the auth system. Carries user_id, identity_id, tenant_id claims.

Authorization: Bearer eyJhbGciOiJIUzI1NiI...

API Key

Per-identity API keys generated via identity_api_key_create. Keys are prefixed with atm_ and scoped to a specific identity.

Authorization: ApiKey atm_abc123def456...

API keys carry the identity's context (tenant, identity) without requiring a user login. Ideal for automated integrations and Claude Code sessions.


API-First, MCP-Second (D12)

The design decision is explicit: REST endpoints are the source of truth. The MCP layer is a thin adapter.

REST API MCP Tool
GET /api/identities/{identityId}/memories/search memory_search
POST /api/identities/{identityId}/memories memory_create
GET /api/hydrate hydrate
POST /api/identities/{identityId}/handoffs session_save_handoff
... ...

Every MCP tool calls the same service method as the REST controller. There is no separate logic, no separate data path, no divergence. A bug fixed in the REST endpoint is automatically fixed in the MCP tool.

Why This Matters

  • Testability: REST endpoints can be tested with standard HTTP tools. MCP tools inherit that correctness.
  • Consistency: One source of truth, one set of validation rules, one set of permissions.
  • Flexibility: New clients (CLI, mobile, web) can use REST without MCP. MCP-aware clients get the same data.
  • Debugging: API requests have correlation IDs, audit logs, and structured error responses. MCP inherits all of it.

Flat Tools

Atamaia uses flat tools -- each tool maps directly to one operation. No command envelopes, no dispatch layers.

When an LLM sees memory_search(identityId, query, topK), it knows exactly what the tool does. No command vocabulary to learn, no envelope to construct, no dispatch to parse. 170 tools, each standalone and self-documenting via its schema.


Tool Surface Summary

Category Product Tools Internal Tools
Hydration 1 --
Memory 11 --
Facts 6 --
Identity 6 + 3 (keys) + 4 (hints) + 5 (config) --
Session 4 --
Messaging 6 --
Experience 5 --
Projects & Tasks 9 --
Docs 6 --
Cognitive 6 --
Audit 2 --
Product Total 74
AI Routing -- ~15
Agent Execution -- ~20
Mirror -- ~15
Channels -- ~10
Connectors -- ~10
Org Units -- ~10
RBAC -- ~10
Chat Sessions -- ~10
Events -- ~2
Grand Total ~170