Content
# agtp-mcp
An AGTP-to-MCP translation gateway. Wraps any stdio-based [Model
Context Protocol][mcp] server with [AGTP][agtp] + TLS, adding agent
identity, Authority-Scope enforcement, Budget-Limit enforcement, and
signed Attribution-Records. Zero changes required to the backing MCP
server.
Run it once in front of `@modelcontextprotocol/server-filesystem`,
`@modelcontextprotocol/server-brave-search`, or your own MCP server,
and AGTP clients can call it like any other AGTP method — with all
the AGTP guarantees layered on top.
## Verb mapping
| AGTP verb + path | MCP JSON-RPC |
|----------------------|--------------------|
| `DESCRIBE` + tools | `tools/list` |
| `EXECUTE` + tools | `tools/call` |
| `DISCOVER` + resources | `resources/list` |
| `QUERY` + resources | `resources/read` |
| `DISCOVER` + prompts | `prompts/list` |
| `QUERY` + prompts | `prompts/get` |
## Architecture
```
AGTP client ──TLS──▶ agtp-mcp gateway ──stdio──▶ MCP server
│ (filesystem,
▼ brave-search,
registry.agtp.io your own…)
(agent identity)
```
The gateway is a single Python process. It:
1. Terminates TLS on its public port (default 4480, configurable
via `AGTP_MCP_PORT`).
2. Parses incoming AGTP requests, verifies agent identity against
the AGTP registry, enforces scopes and budgets.
3. Spawns the configured MCP server as a subprocess and speaks
JSON-RPC to it over stdio (per the MCP spec).
4. Translates the response back to AGTP frames, signs an
Attribution-Record, and emits it on the wire and to the
attribution log.
## Install
```bash
git clone https://github.com/nomoticai/agtp-mcp
cd agtp-mcp
pip install -r requirements.txt
```
Python 3.11+ recommended.
## Configuration
Everything is environment-variable driven so the same gateway image
runs in dev, staging, and production.
| Variable | Default | What |
|---------------------------|------------------------------------------------------|-----------------------------------------------|
| `AGTP_MCP_HOST` | `0.0.0.0` | TCP bind host |
| `AGTP_MCP_PORT` | `4481` | TCP bind port (production: 4480 standard AGTP)|
| `AGTP_MCP_CERT` | Let's Encrypt path | TLS fullchain |
| `AGTP_MCP_KEY` | Let's Encrypt path | TLS private key |
| `AGTP_REGISTRY` | `https://registry.agtp.io` | AGTP agent registry |
| `AGTP_MCP_BACKEND` | mock MCP server | Command to launch the backing MCP server |
| `AGTP_GATEWAY_KEY` | `/var/lib/agtp/gateway_signing_key.pem` | Ed25519 key for signing Attribution-Records |
| `AGTP_ATTRIBUTION_LOG` | `/var/log/agtp/attribution.log` | Append-only attribution log path |
| `AGTP_REQUIRE_SIGNATURE` | `0` | When `1`, reject requests without a valid agent signature |
### Running directly
```bash
export AGTP_MCP_BACKEND="npx -y @modelcontextprotocol/server-filesystem /var/lib/agtp/mcp-sandbox"
export AGTP_MCP_CERT=/etc/letsencrypt/live/mcp.example.com/fullchain.pem
export AGTP_MCP_KEY=/etc/letsencrypt/live/mcp.example.com/privkey.pem
python gateway.py
```
### Running via systemd
A unit file ships in this repo:
```bash
sudo cp agtp-mcp.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now agtp-mcp
```
Edit the unit to point `AGTP_MCP_BACKEND` at the MCP server you want
to expose.
## Trying it locally
`mock_mcp_server.py` is a tiny stdio MCP server that exposes one
tool (`echo`) — useful for smoke-testing the gateway without
installing a real MCP backend:
```bash
# Terminal 1: gateway + mock backend
AGTP_MCP_BACKEND="python mock_mcp_server.py" \
AGTP_MCP_CERT=server.crt \
AGTP_MCP_KEY=server.key \
python gateway.py
# Terminal 2: client demo
python client_demo.py
```
## Why bridge instead of replace
MCP clients (Claude Desktop, Cline, etc.) already speak the JSON-RPC
flavour over stdio or HTTP. Replacing them would mean rewriting
every MCP client. Bridging means:
- Existing MCP servers gain agent identity, scopes, budgets, and
cryptographic attribution **without code changes**.
- MCP clients that learn to speak AGTP get the full AGTP feature
set (registry-backed discovery, cross-agent budgets, mutual auth
via Agent-Cert).
- The AGTP and MCP communities can evolve independently. AGTP isn't
trying to define a tool-call schema; MCP isn't trying to define a
cross-agent transport.
## Related
- [AGTP spec repo][agtp] — protocol drafts (IETF), `agtpd` daemon,
conformance tests
- [Model Context Protocol][mcp] — upstream MCP spec from Anthropic
- [`agtp-a2a`][a2a] — sibling cross-protocol bridge (currently
in-tree in the spec repo while the surface stabilises)
## History
This package was originally named `mcp-on-agtp/`. Renamed to
`agtp-mcp/` for consistency with the other connector packages
(`agtp-drupal`, `agtp-symfony`, `agtp-laravel`, `agtp-wordpress`).
Later extracted into its own repo so MCP users don't have to clone
the entire AGTP stack to run a single bridge.
[mcp]: https://modelcontextprotocol.io/
[agtp]: https://github.com/nomoticai/agtp
[a2a]: https://github.com/nomoticai/agtp/tree/main/connectors/agtp-a2a