MCP Client
Agenvoy's MCP client lets agents call tools exposed by any MCP server. Client and server share one package (internal/runtime/mcp) built on the official modelcontextprotocol/go-sdk.
Configuration layout
One file. The session-scoped layer was removed — every client reads the same config:
~/.config/agenvoy/mcp.json
JSON format
{
"servers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
},
"remote-api": {
"url": "https://api.example.com/mcp",
"headers": { "Authorization": "Bearer ${TOKEN}" }
}
}
}
command and url are mutually exclusive. ${VAR} / $VAR placeholders inside env, headers, and args are expanded with os.Expand at startup.
Transport types
| Type | Config keys | SDK transport | Use case |
|---|---|---|---|
| stdio | command + args + env |
CommandTransport |
Local CLIs (npx, native binaries) |
| Streamable HTTP | url + headers |
StreamableClientTransport |
Remote services, long-running MCP servers |
Both transports are handled by the SDK; Agenvoy only supplies the command or the endpoint plus a header-injecting HTTP client.
Management
| Task | TUI | HTTP |
|---|---|---|
| List servers | /mcp |
GET /v1/mcp |
| Add a server | /mcp |
POST /v1/mcp |
| Remove a server | /mcp → d on the server |
POST /v1/mcp/remove |
| Connection status | /mcp |
GET /v1/mcp/status |
| Reconnect and re-register tools | /mcp → server → reconnect (that server only) |
POST /v1/mcp/reconnect (all servers) |
| List registered MCP tools | /mcp → server → tools |
GET /v1/mcp/tools |
| Per-tool auto-approve | /mcp → server → tools |
POST /v1/allowlist with a tool block |
| Browser OAuth login | /mcp → server → login / relogin |
GET /v1/mcp/oauth?name=X (SSE) |
| Pre-registered OAuth client | /mcp → server → client |
POST /v1/mcp/oauth/client |
| Clear an OAuth login | — | DELETE /v1/mcp/oauth |
The add flow asks for the server name, transport (Local stdio / Remote HTTP), and the type-specific fields. There are no agen mcp CLI subcommands.
OAuth for HTTP servers
A server marked auth: oauth logs in through mcp.Login: the daemon opens a loopback callback listener on localhost:17988, performs dynamic client registration when the provider allows it, and stores the resulting token and client id in the OS keychain. When the provider rejects dynamic registration, supply a pre-registered client with POST /v1/mcp/oauth/client (redirect_uri defaults to http://localhost:17988/callback and must match the provider console exactly). When the browser cannot reach the listener, paste the redirect URL back with POST /v1/mcp/oauth/callback.
Tool naming
MCP-exposed tools are auto-registered with the format:
mcp__<server_name>__<tool_name>
Example: mcp__github__create_issue, mcp__sqlite-notes__read_query.
Result size cap
Each MCP tool result is capped at 1 MiB. When exceeded, the result is truncated with the marker:
[mcp output truncated: <total> bytes total, <kept> kept]
This avoids OpenAI Responses API's 10 MB single-tool-output limit triggering a same-signature retry storm. SQLite SELECT * on a large table will hit this — add LIMIT / WHERE.
Confirm behavior
MCP tools route through the most conservative defaults:
- Every MCP tool call goes through the same confirm gate as a built-in tool, under whatever permission mode the request carries
- No per-server
read_onlytoggle — Agenvoy does not extend trust to third-party servers because their behavior is unverifiable (a Slack MCP could silently send messages, a Filesystem MCP could silently write files)
Trust is granted per tool, not per server: /mcp → server → tools (or POST /v1/allowlist with a tool block) replaces the auto-approve entries for one prefix, leaving unrelated rules alone. Every entry must start with that prefix, and prefix* collapses the rest into a whole-server grant. The list lives in ~/.config/agenvoy/allow_tool.
Lifecycle
- Startup:
app.NewMCPcallsmcp.New(ctx, sid), thenRegisterAll(ctx), then startsWatch(ctx), before the agent registry is built; clients close on shutdown - Live tool refresh: clients subscribe to the server's
notifications/tools/list_changedand re-register that server's tools when its catalog changes — no restart needed for a server that adds or drops tools - Server instructions: whatever a server declares as its instructions is surfaced into the agent system prompt, so per-server usage rules reach the model
- Per-server failures: a start or tool-list failure logs a warning and skips that server; core functionality never blocks
- Manual recovery:
POST /v1/mcp/reconnectreconnects every client and re-registers tools;/mcp→ server → reconnect in the TUI does the same for one server
Recommended servers
Zero-auth, locally executed (no API key required):
| Server | Purpose |
|---|---|
mcp-server-sqlite |
Run SQL on local .db files |
@modelcontextprotocol/server-memory |
Persistent knowledge graph |
@playwright/mcp |
Browser automation (downloads chromium) |
@modelcontextprotocol/server-postgres |
Local Postgres connection |
mcp-server-time |
Timezone conversion / relative time |
Avoid registering MCP servers whose capabilities overlap with built-in tools (e.g., filesystem, git, fetch, shell) — duplicates only inflate the LLM tool list.