> ## Documentation Index
> Fetch the complete documentation index at: https://meepa.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP

> Connect agents to external tool servers via the Model Context Protocol

## Overview

MeepaGateway supports the [Model Context Protocol (MCP)](https://modelcontextprotocol.io), letting agents call tools hosted by external MCP servers. MCP tools appear alongside built-in tools — the LLM cannot tell the difference.

MCP servers are configured per-agent in `.mcp.json` inside the agent's home directory (`~/.meepagateway/agents/{agent_id}/.mcp.json`). This is the same format used by Claude Desktop and Cursor.

MeepaGateway uses the [`rmcp`](https://docs.rs/rmcp) crate for MCP communication.

***

## Transports

### Stdio

The gateway spawns the MCP server as a child process and communicates over stdin/stdout using JSON-RPC 2.0.

```json theme={null}
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"]
    }
  }
}
```

### Streamable HTTP

The gateway connects to an already-running HTTP MCP server.

```json theme={null}
{
  "mcpServers": {
    "my-api": {
      "url": "http://localhost:3000/mcp"
    }
  }
}
```

`command` and `url` are mutually exclusive — use one or the other per server.

***

## `.mcp.json` Format

The file follows the standard MCP JSON format:

```json theme={null}
{
  "mcpServers": {
    "server-name": {
      "command": "executable",
      "args": ["arg1", "arg2"],
      "env": {
        "API_KEY": "your-key"
      },
      "disabled": false
    }
  }
}
```

### Fields

<ParamField path="command" type="string">
  Executable to launch for stdio transport. Mutually exclusive with `url`.
</ParamField>

<ParamField path="args" type="array">
  Arguments passed to the spawned command.
</ParamField>

<ParamField path="url" type="string">
  HTTP endpoint for streamable HTTP transport. Mutually exclusive with `command`.
</ParamField>

<ParamField path="env" type="object">
  Extra environment variables injected into the spawned process (stdio only).
</ParamField>

<ParamField path="disabled" type="boolean" default="false">
  Set to `true` to disable this server without removing it from the file.
</ParamField>

***

## Examples

### Memory server (stdio)

```json theme={null}
{
  "mcpServers": {
    "memory": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-memory"]
    }
  }
}
```

### GitHub (stdio)

```json theme={null}
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_..."
      }
    }
  }
}
```

### Multiple servers

```json theme={null}
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp/workspace"]
    },
    "search": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-brave-search"],
      "env": {
        "BRAVE_API_KEY": "BSA..."
      }
    },
    "internal-api": {
      "url": "http://localhost:4000/mcp"
    }
  }
}
```

***

## Managing MCP Servers

### Via CLI

```bash theme={null}
# Edit .mcp.json directly (opens editor)
meepagateway agent mcp meepa
```

### Via Captain Dashboard

Navigate to **Agents → {agent} → MCP** to add, edit, disable, and remove MCP servers through the web UI.

### Via API

```bash theme={null}
# List MCP servers
curl -H "Authorization: Bearer $API_KEY" \
  http://localhost:63372/api/agents/meepa/mcp

# Add a server
curl -X POST -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "filesystem",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
  }' \
  http://localhost:63372/api/agents/meepa/mcp
```

***

## How Tool Bridging Works

At agent startup:

1. `McpManager` reads `.mcp.json` and connects to each enabled server
2. For each server, `list_tools()` is called to discover available tools
3. Each discovered tool is wrapped in `McpToolBridge` — an adapter that implements the internal `Tool` trait
4. Bridged tools are registered in the agent's `ToolRegistry` alongside built-in tools

When the LLM calls an MCP tool:

1. The gateway looks up the tool by name in the registry
2. `McpToolBridge.execute()` calls `call_tool()` on the `McpClient`
3. The result is returned to the LLM as a tool result message

Connection failures on startup are logged but do not prevent the agent from starting — only tools from the failed server are unavailable.

***

## Architecture

```
Agent tool registry
  ├── built-in: shell, read_file, write_file, web_fetch, web_search
  ├── memory: memory_store, memory_search, memory_delete, memory_note, memory_read
  ├── soul: soul_read, soul_edit
  └── mcp (via McpToolBridge):
        ├── McpClient[filesystem] → stdio → npx server-filesystem
        └── McpClient[internal-api] → HTTP → localhost:4000/mcp
```

| Component       | Role                                                                     |
| --------------- | ------------------------------------------------------------------------ |
| `McpClient`     | Connects to one MCP server; handles handshake, `list_tools`, `call_tool` |
| `McpManager`    | Manages multiple `McpClient` instances per agent                         |
| `McpToolBridge` | Adapts an MCP tool into the internal `Tool` trait                        |
