# Skill: Configure MCP Tool Servers

Use when you want agents to call external services via MCP — GitHub, Notion, Slack,
Google Workspace, custom servers, or any other MCP-compatible tool provider.

## How it works

arccrew reads `arccrew.json` at the project root. Any MCP server defined there is
available to every agent with a single call — no per-agent config needed.

```json
{
  "mcpServers": {
    "github": {
      "transport": "sse",
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": { "Authorization": "Bearer ${GITHUB_TOKEN}" }
    },
    "notion": {
      "transport": "sse",
      "url": "https://mcp.notion.com/sse",
      "headers": { "Authorization": "Bearer ${NOTION_TOKEN}" }
    }
  }
}
```

`${ENV_VAR}` placeholders are interpolated from the environment at runtime — API keys
stay in `.env` and never touch `arccrew.json`.

## Install

```bash
pip install "arccrew[mcp]"
```

Add to `requirements.txt`:
```
arccrew[mcp]
```

## Usage in agents

```python
from arccrew.tools import get_mcp_tools

# All servers in arccrew.json
tools = await get_mcp_tools()

# Specific servers only
tools = await get_mcp_tools(["github"])

# Inline config (backwards compatible, no arccrew.json needed)
tools = await get_mcp_tools({
    "github": {
        "transport": "sse",
        "url": "https://api.githubcopilot.com/mcp/",
        "headers": {"Authorization": f"Bearer {os.getenv('GITHUB_TOKEN')}"},
    }
})
```

Combine with built-in tools:
```python
tools = (
    get_research_tools()
    + create_workspace_tools(workspace_path)
    + await get_mcp_tools()
)
result = await self.run_react(task=task, tools=tools)
```

## arccrew.json — full reference

```json
{
  "mcpServers": {
    "github": {
      "transport": "sse",
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": { "Authorization": "Bearer ${GITHUB_TOKEN}" }
    },
    "notion": {
      "transport": "sse",
      "url": "https://mcp.notion.com/sse",
      "headers": { "Authorization": "Bearer ${NOTION_TOKEN}" }
    },
    "slack": {
      "transport": "sse",
      "url": "https://mcp.slack.com/sse",
      "headers": { "Authorization": "Bearer ${SLACK_BOT_TOKEN}" }
    },
    "google": {
      "transport": "stdio",
      "command": "npx",
      "args": ["-y", "@google/mcp-server-google-workspace"]
    },
    "local_server": {
      "transport": "stdio",
      "command": "python",
      "args": ["my_mcp_server.py"]
    }
  }
}
```

Keys starting with `_` are treated as comments and ignored.

## Transport types

### SSE — remote servers (most common)
```json
{
  "transport": "sse",
  "url": "https://mcp.example.com/sse",
  "headers": { "Authorization": "Bearer ${TOKEN}" }
}
```

### HTTP — streamable HTTP servers
```json
{
  "transport": "http",
  "url": "http://localhost:8000/mcp"
}
```

### Stdio — local processes
```json
{
  "transport": "stdio",
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
}
```

## API keys

Add tokens to `.env`:
```bash
GITHUB_TOKEN=github_pat_...
NOTION_TOKEN=secret_...
SLACK_BOT_TOKEN=xoxb-...
```

Reference them in `arccrew.json` with `${VAR_NAME}` — they are never hardcoded.

## Agent prompt — name MCP tools explicitly

Tools not mentioned in the prompt will be ignored by the LLM.

```markdown
# GitHub Agent

## Instructions
1. Use `github_search_repositories` to find repos
2. Use `github_get_file_contents` to read files
3. Use `github_list_issues` to check issues
```

`prefix_tool_names=True` (default) prefixes tools with the server name:
`github_search`, `notion_query`, etc. — prevents naming conflicts.

## Common MCP servers

| Service | Transport | Notes |
|---------|-----------|-------|
| GitHub Copilot | SSE | `https://api.githubcopilot.com/mcp/` |
| Notion | SSE | `https://mcp.notion.com/sse` |
| Google Workspace | stdio | `npx @google/mcp-server-google-workspace` |
| Filesystem | stdio | `npx @modelcontextprotocol/server-filesystem` |
| Postgres | stdio | `npx @modelcontextprotocol/server-postgres` |
| Custom arccrew | HTTP | `http://localhost:8000/mcp` |

See [MCP servers directory](https://github.com/modelcontextprotocol/servers) for more.

## Stateless vs stateful sessions

`get_mcp_tools()` opens a fresh connection per tool call (stateless). For servers
that need persistent state within a single agent run, use `MultiServerMCPClient` directly:

```python
from langchain_mcp_adapters.client import MultiServerMCPClient
from langchain_mcp_adapters.tools import load_mcp_tools

client = MultiServerMCPClient(connections={"db": DB_CONFIG})
async with client.session("db") as session:
    tools = await load_mcp_tools(session)
    result = await self.run_react(task=task, tools=tools)
```
