Skip to main content
OpenFang supports the Model Context Protocol (MCP) for tool interoperability. MCP allows OpenFang agents to use tools from external MCP servers, and external MCP clients to use OpenFang tools.

List MCP Servers

Retrieve all configured MCP servers and their connection status.
curl http://127.0.0.1:4200/api/mcp/servers
servers
array
{
  "servers": [
    {
      "name": "filesystem",
      "transport": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem"],
      "connected": true,
      "tools": [
        {
          "name": "mcp_filesystem_read_file",
          "description": "Read a file from the filesystem",
          "input_schema": {
            "type": "object",
            "properties": {
              "path": {"type": "string"}
            },
            "required": ["path"]
          }
        },
        {
          "name": "mcp_filesystem_write_file",
          "description": "Write content to a file",
          "input_schema": {
            "type": "object",
            "properties": {
              "path": {"type": "string"},
              "content": {"type": "string"}
            },
            "required": ["path", "content"]
          }
        }
      ]
    }
  ],
  "total": 1
}

MCP Server Configuration

Configure MCP servers in ~/.openfang/config.toml:

stdio Transport

Run an MCP server as a subprocess:
[mcp_servers.filesystem]
transport = "stdio"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem"]

[mcp_servers.github]
transport = "stdio"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]
env = { GITHUB_TOKEN_ENV = "GITHUB_TOKEN" }

HTTP Transport

Connect to a remote MCP server over HTTP:
[mcp_servers.remote]
transport = "http"
url = "https://mcp.example.com"
auth = { bearer_token_env = "MCP_TOKEN" }

SSE Transport

Connect to an MCP server using Server-Sent Events:
[mcp_servers.streaming]
transport = "sse"
url = "https://mcp.example.com/sse"

Tool Discovery

When an MCP server connects, OpenFang automatically:
  1. Discovers tools — Sends tools/list JSON-RPC request
  2. Prefixes tool names — Adds mcp_{server}_ prefix to avoid conflicts
  3. Registers tools — Makes tools available to agents
  4. Caches schemas — Stores input schemas for validation
Example: The filesystem MCP server’s read_file tool becomes mcp_filesystem_read_file.

Agent MCP Configuration

Agents can configure which MCP servers they use:
agent.toml
# Allowlist mode (explicit list)
mcp_servers = ["filesystem", "github"]

# Default mode (all servers)
mcp_servers = []  # Empty = all available MCP servers
API endpoint to update agent MCP servers:
curl -X PUT http://127.0.0.1:4200/api/agents/{id}/mcp_servers \
  -H "Content-Type: application/json" \
  -d '{
    "mcp_servers": ["filesystem", "github"],
    "mode": "allowlist"
  }'

MCP HTTP Endpoint

OpenFang exposes an MCP HTTP endpoint to allow external MCP clients to use OpenFang tools.

POST /mcp

Send JSON-RPC 2.0 requests to interact with OpenFang tools via MCP.
curl -X POST http://127.0.0.1:4200/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/list",
    "id": 1
  }'
jsonrpc
string
required
Always "2.0"
method
string
required
JSON-RPC method:
  • tools/list — List available tools
  • tools/call — Execute a tool
  • resources/list — List resources (future)
  • prompts/list — List prompts (future)
params
object
Method parameters (varies by method)
id
number
required
Request ID (must match response)
Example: List tools
curl -X POST http://127.0.0.1:4200/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/list",
    "id": 1
  }'
{
  "jsonrpc": "2.0",
  "result": {
    "tools": [
      {
        "name": "file_read",
        "description": "Read a file's contents",
        "inputSchema": {
          "type": "object",
          "properties": {
            "path": {"type": "string"}
          },
          "required": ["path"]
        }
      },
      {
        "name": "web_fetch",
        "description": "Fetch a URL",
        "inputSchema": {
          "type": "object",
          "properties": {
            "url": {"type": "string"}
          },
          "required": ["url"]
        }
      }
    ]
  },
  "id": 1
}
Example: Call tool
curl -X POST http://127.0.0.1:4200/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
      "name": "file_read",
      "arguments": {
        "path": "/tmp/test.txt"
      }
    },
    "id": 2
  }'
{
  "jsonrpc": "2.0",
  "result": {
    "content": [
      {
        "type": "text",
        "text": "File contents here..."
      }
    ]
  },
  "id": 2
}

Connection Status

MCP server connections are monitored continuously:
  • Connected — Server is reachable and tools are available
  • Disconnected — Server is unreachable (will retry)
  • Failed — Server configuration error
View connection status:
curl http://127.0.0.1:4200/api/mcp/servers | jq '.servers[] | {name, connected}'

Error Handling

MCP tool calls can fail for various reasons:
  • Server disconnected — Retry with exponential backoff
  • Tool not found — Check tool name and server connection
  • Invalid input — Validate against input_schema
  • Execution error — Server returned error response
All MCP errors are logged to the audit trail with:
  • Timestamp
  • Server name
  • Tool name
  • Error message
  • Request/response payload (if debug enabled)

Supported MCP Servers

OpenFang is compatible with all MCP-compliant servers, including:
  • @modelcontextprotocol/server-filesystem — File operations
  • @modelcontextprotocol/server-github — GitHub integration
  • @modelcontextprotocol/server-postgres — PostgreSQL queries
  • @modelcontextprotocol/server-sqlite — SQLite queries
  • @modelcontextprotocol/server-slack — Slack integration
  • @modelcontextprotocol/server-gdrive — Google Drive access
  • Custom MCP servers — Any MCP-compliant implementation

Best Practices

For tools that run locally (filesystem, git, etc.), use stdio transport:
[mcp_servers.filesystem]
transport = "stdio"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem"]
This avoids network overhead and improves performance.
For cloud APIs or remote tools, use HTTP transport:
[mcp_servers.cloud_api]
transport = "http"
url = "https://api.example.com/mcp"
auth = { bearer_token_env = "API_TOKEN" }
OpenFang automatically prefixes MCP tools with mcp_{server}_, but you can also:
  • Use unique server names in config
  • Filter tools in agent manifests
  • Rename tools in server configuration
Check logs for connection issues:
openfang logs --follow | grep "mcp_client"
Never hardcode API keys in MCP server configs:
[mcp_servers.github]
transport = "stdio"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]
env = { GITHUB_TOKEN_ENV = "GITHUB_TOKEN" }
Then set the env var:
export GITHUB_TOKEN="ghp_..."
openfang restart

Next Steps

Agents API

Configure agent MCP servers

Skills API

Compare with OpenFang skills

MCP Specification

Learn about MCP protocol

Tool Development

Build custom tools

Build docs developers (and LLMs) love