How to Integrate Agent Reach with Custom MCP Servers Beyond Exa

You integrate Agent Reach with custom MCP servers by exposing a JSON-RPC 2.0 endpoint that implements the Meta-Command Protocol, registering it with mcporter, and optionally creating a Channel subclass that probes the configuration to activate the backend.

Agent Reach uses the Meta-Command Protocol (MCP) as a thin bridge between its channel logic and external services. While the repository ships with built-in Exa search integration via agent_reach/channels/exa_search.py, you can extend this architecture to any custom service by following the patterns established in agent_reach/integrations/mcp_server.py.

Understanding the MCP Architecture

Agent Reach's MCP integration relies on two core components. First, agent_reach/integrations/mcp_server.py registers Agent Reach status as an MCP tool and exposes it via JSON-RPC 2.0 over HTTP (lines 27-34). Second, channel implementations like the Exa search channel probe mcporter and read MCP configuration to determine backend availability (lines 23-30 in agent_reach/channels/exa_search.py).

To hook a custom MCP server into this ecosystem, you must expose a compatible endpoint, register it with mcporter, and ensure Agent Reach can verify its availability.

Step 1: Install Agent Reach with MCP Support

Before implementing custom integrations, install the package with MCP extras:

pip install "agent-reach[mcp]"

This installs the mcp Python package required to run the built-in MCP server and communicate with any MCP endpoint.

Step 2: Implement Your Custom MCP Server

Create a JSON-RPC 2.0 HTTP service following the MCP specification. Your server must implement list_tools() to advertise available tools and call_tool(name, arguments) to execute them, similar to the built-in server implementation in agent_reach/integrations/mcp_server.py (lines 36-43).

Here is a minimal implementation:

from mcp.server import Server
from mcp.types import Tool, TextContent
import json

def create_server():
    server = Server("my-mcp")
    
    @server.list_tools()
    async def list_tools():
        return [
            Tool(
                name="my_search",
                description="Search my custom index",
                inputSchema={"type": "object", "properties": {"q": {"type": "string"}}},
            )
        ]

    @server.call_tool()
    async def call_tool(name: str, arguments: dict):
        if name == "my_search":
            result = {"hits": ["item1", "item2"]}
            text = json.dumps(result, ensure_ascii=False, indent=2)
            return [TextContent(type="text", text=text)]
        return [TextContent(type="text", text=f"Unknown tool: {name}")]

    return server

if __name__ == "__main__":
    import asyncio
    from mcp.server.stdio import stdio_server
    
    async def main():
        srv = create_server()
        async with stdio_server() as (read, write):
            await srv.run(read, write, srv.create_initialization_options())
    
    asyncio.run(main())

Run this server with python my_mcp_server.py, ensuring it listens on a stable URL such as http://localhost:18061/mcp.

Step 3: Register the Endpoint with mcporter

Once your server is running, register it with Agent Reach's configuration tool:

mcporter config add myservice http://localhost:18061/mcp

Replace myservice with a short identifier that you will reference in your Channel subclass. This mirrors the Exa registration pattern, where mcporter config add exa https://mcp.exa.ai/mcp enables the Exa channel to discover its backend.

Step 4: Create a Custom Channel Subclass

To officially recognize your MCP server as an active backend, create a new Channel subclass in agent_reach/channels/myservice.py. As defined in agent_reach/channels/base.py (lines 29-71), the Channel base class requires you to implement a check() method that probes mcporter to verify the endpoint is reachable.

Here is a complete template:

from agent_reach.probe import probe_command
from .base import Channel

class MyServiceChannel(Channel):
    name = "myservice"
    description = "Custom MCP-backed service"
    backends = ["MyService via mcporter"]
    tier = 0

    def can_handle(self, url: str) -> bool:
        # Optional: return True for URLs your service can handle

        return False

    def check(self, config=None):
        self.active_backend = None
        probe = probe_command(
            "mcporter", ["config", "list"], timeout=10, package="mcporter"
        )
        if probe.status == "missing":
            return "off", "Install mcporter and add your MCP endpoint."
        if probe.status == "broken":
            return "error", "mcporter is broken – reinstall it."
        if "myservice" in probe.output.lower():
            self.active_backend = self.backends[0]
            return "ok", "MyService MCP is configured and reachable."
        return "off", "mcporter is installed but MyService not configured."

Add this file to agent_reach/channels/__init__.py to ensure discovery by the core system. The probe_command function verifies that your service appears in mcporter config list before marking the backend as active.

Step 5: Verify Integration with the Doctor Command

Validate that Agent Reach recognizes your custom MCP server by running:

python -m agent_reach.cli doctor

As implemented in agent_reach/core.py (lines 39-42), the doctor_report() method invokes each channel's check() method. The output should list your service under "Active backends," confirming that downstream AI agents can invoke your MCP tools via mcporter call myservice.mytool.

Key Integration Files

Understanding these source files helps debug custom integrations:

Summary

  • Install MCP dependencies using pip install "agent-reach[mcp]" to enable protocol support.
  • Expose a JSON-RPC 2.0 endpoint implementing list_tools() and call_tool() following the pattern in agent_reach/integrations/mcp_server.py.
  • Register with mcporter using mcporter config add <name> <url> to make the endpoint discoverable.
  • Subclass Channel in agent_reach/channels/ to probe the configuration and mark the backend as active, mirroring the pattern in agent_reach/channels/exa_search.py.
  • Verify with doctor by running python -m agent_reach.cli doctor to confirm your custom MCP server appears in the health report.

Frequently Asked Questions

What is the MCP protocol in Agent Reach?

The Meta-Command Protocol (MCP) is a thin bridge between Agent Reach's channel logic and external services. It uses JSON-RPC 2.0 over HTTP to allow AI agents to invoke tools exposed by external servers. The protocol is implemented in agent_reach/integrations/mcp_server.py and consumed by channels that probe mcporter for configuration.

Do I need to create a Channel subclass for every custom MCP server?

While you can register an MCP endpoint with mcporter without creating a Channel, implementing a Channel subclass is recommended for full integration. The Channel class (defined in agent_reach/channels/base.py) provides the check() method that determines whether the backend is available, allowing the doctor command to report status and enabling the tiered backend selection logic.

How does Agent Reach verify that my MCP server is running?

Agent Reach verifies MCP servers through the mcporter command-line tool. Your Channel's check() method should call probe_command("mcporter", ["config", "list"], ...) to confirm the endpoint is registered. The doctor command in agent_reach/cli.py aggregates these checks via AgentReach.doctor_report() (lines 39-42 in agent_reach/core.py) to display active backends.

Can I use stdio transport instead of HTTP for my MCP server?

The provided examples use stdio transport via mcp.server.stdio for simplicity, but production deployments typically expose HTTP endpoints. Agent Reach's mcporter configuration expects HTTP URLs (e.g., http://localhost:18061/mcp). Ensure your server implements the same JSON-RPC 2.0 protocol regardless of transport, matching the interface defined in agent_reach/integrations/mcp_server.py.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →