# How mcporter Integrates with the Exa MCP Server in Agent Reach

> Discover how mcporter integrates with the Exa MCP server in Agent Reach. Learn how the mcporter package provides the MCP transport layer for diagnostics over stdio.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: how-to-guide
- Published: 2026-08-04

---

**The `mcporter` package provides the MCP transport layer that lets Agent Reach expose its internal `doctor_report()` diagnostics as an MCP-compatible tool over stdio.**

Agent Reach is an open-source automation framework that uses the **Model Context Protocol (MCP)** to make its diagnostic capabilities callable from external agents. The integration with `mcporter` enables any MCP client to query Agent Reach's status without importing the Python library directly. This article examines the implementation in [`agent_reach/integrations/mcp_server.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/integrations/mcp_server.py) and how `mcporter` handles the underlying JSON-RPC transport.

## MCP Server Architecture in Agent Reach

The MCP server implementation follows a minimal wrapper pattern: it registers one tool—`get_status`—that delegates to existing Agent Reach internals.

### Server Bootstrap and Initialization

When you execute `python -m agent_reach.integrations.mcp_server`, the `main()` coroutine performs two critical setup steps:

1. Creates a `Server` instance named **"agent-reach"** (line 32)
2. Constructs an `AgentReach` core object (line 34) containing configuration and doctor logic

```python

# Simplified from agent_reach/integrations/mcp_server.py

async def main():
    server = Server("agent-reach")  # line 32

    eyes = AgentReach(config)        # line 34

    # ... tool registration follows

```

This design reuses the same `AgentReach` class that powers the CLI's `doctor` command, ensuring consistent reporting between interactive and programmatic access.

### Tool Registration with @server.list_tools()

The `@server.list_tools()` decorator registers a single tool called **`get_status`** (lines 38-42). Its description informs MCP clients that the tool returns current channel installation and activation status.

### Tool Handler Implementation

The `@server.call_tool()` handler (lines 44-55) receives tool name and arguments, then:

1. For `get_status` calls, invokes `eyes.doctor_report()` (the same method used by the CLI)
2. Serializes results to JSON (lines 48-53)
3. Catches and returns any errors as text responses

```python
@server.call_tool()
async def handle_tool(name: str, arguments: dict):
    if name == "get_status":
        report = eyes.doctor_report()  # Same as CLI doctor command

        return [TextContent(type="text", text=json.dumps(report, indent=2))]

```

## How mcporter Provides MCP Transport

**`mcporter`** implements the standard MCP transport that Agent Reach uses. The server runs over **stdio** via `mcp.server.stdio.stdio_server` (lines 60-64), which creates a process that:

- Reads JSON-RPC messages from **stdin**
- Writes responses to **stdout**

This is exactly what `mcporter` expects. The CLI can install `mcporter` on the host through `_install_mcporter()` in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py), making the server instantly accessible to any MCP client.

## Calling Agent Reach via mcporter

### Starting the MCP Server

```bash

# Start the server (blocks; use & for background execution)

python -m agent_reach.integrations.mcp_server

```

### Using the mcporter CLI

```bash

# Call the get_status tool with JSON output

mcporter call 'get_status()' --json

```

Expected output structure:

```json
{
  "channels": {
    "twitter": "active",
    "youtube": "inactive",
    "exa_search": "active"
  },
  "backends": ["mcporter"],
  "message": "All systems operational"
}

```

### Direct Python Access (No MCP Overhead)

For same-process usage, bypass the MCP layer entirely:

```python
from agent_reach.core import AgentReach
from agent_reach.config import Config

cfg = Config()
reach = AgentReach(cfg)

# Identical report to what mcporter receives

status = reach.doctor_report()
print(status)

```

## Key Implementation Files

| File | Purpose |
|------|---------|
| [`agent_reach/integrations/mcp_server.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/integrations/mcp_server.py) | MCP server implementation, tool registration, stdio transport |
| [`agent_reach/core.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/core.py) | `AgentReach` class with `doctor_report()` method |
| [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) | `_install_mcporter()` helper and CLI entry points |
| [`agent_reach/utils/process.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/process.py) | `mcporter_utf8_env_args()` for proper UTF-8 environment handling |

The `mcporter_utf8_env_args()` utility in [`agent_reach/utils/process.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/utils/process.py) ensures correct character encoding when spawning `mcporter` subprocesses, preventing issues with non-ASCII status messages.

## Summary

- **`mcporter`** provides the stdio-based JSON-RPC transport that makes Agent Reach's diagnostics externally callable
- Agent Reach's MCP server exposes a single **`get_status`** tool that wraps `doctor_report()`
- The same `AgentReach` core powers both CLI `doctor` commands and MCP tool responses
- UTF-8 handling via `mcporter_utf8_env_args()` ensures robust cross-platform operation

## Frequently Asked Questions

### What is mcporter in the context of Agent Reach?

**`mcporter`** is the MCP (Model Context Protocol) transport package that Agent Reach uses to expose its internal diagnostic tools. It provides both the server-side stdio transport in [`agent_reach/integrations/mcp_server.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/integrations/mcp_server.py) and the client-side CLI for making JSON-RPC calls from external processes or agents.

### How does the MCP server handle errors from doctor_report()?

The `@server.call_tool()` handler wraps the `eyes.doctor_report()` call in a try-except block (lines 44-55 in [`mcp_server.py`](https://github.com/Panniantong/Agent-Reach/blob/main/mcp_server.py)). Any exceptions are caught and returned as text content with an error message, ensuring the MCP protocol never returns malformed responses even when internal diagnostics fail.

### Can I extend the MCP server with additional tools?

Yes. The pattern in [`agent_reach/integrations/mcp_server.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/integrations/mcp_server.py) demonstrates how to register new tools: add entries to the `@server.list_tools()` return value and handle them in `@server.call_tool()`. Each handler can invoke any `AgentReach` method or custom logic, then return JSON-serialized results.

### Is mcporter required to use Agent Reach's doctor functionality?

No. `mcporter` is only needed for **inter-process** MCP communication. As shown in the Python example above, you can call `reach.doctor_report()` directly after `from agent_reach.core import AgentReach`. The MCP server and `mcporter` become relevant when you need external agents or CLIs to query status without Python imports.