Contents

EONYX and MCP: connecting external tools

Model Context Protocol (MCP) is an open standard through which an agent gains access to external systems: databases, APIs, issue trackers and any other services. EONYX has a built-in MCP client based on the official Go SDK (modelcontextprotocol/go-sdk) — servers are described right in eonyx.json and their tools show up for the model alongside the built-in ones.

Connecting an MCP server takes two steps: describe it in the config and grant access to its tools. And for one common case MCP is not needed at all — we will cover that too.

MCP servers are described in the mcp array of the config. There is no separate “type” field — the transport is inferred from the fields: if there is a url it is HTTP, if there is a command it is stdio.

A local process, communication over stdin/stdout:

"mcp": [
  {
    "name": "github",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-github"],
    "env": { "GITHUB_TOKEN": "ghp_..." }
  }
]

env is added to the environment of the spawned process on top of the current one.

A remote server, HTTP/SSE transport:

"mcp": [
  {
    "name": "tracker",
    "url": "https://mcp.example.com/sse",
    "headers": { "Authorization": "Bearer $TRACKER_TOKEN" }
  }
]

headers are added to every request; values can reference environment variables ($TRACKER_TOKEN) — the token is not stored in the file.

Server fields:

FieldPurpose
nameserver name — becomes the prefix of all its tools
commandexecutable of the stdio server
argscommand arguments
envenvironment variables for the server process
urlendpoint of the HTTP server (presence of url switches transport)
headersheaders for every HTTP request, support $ENV
Connection is best-effort
On startup EONYX tries to connect to all servers; a failing server is skipped rather than breaking the launch — a warning: mcp: … goes to stderr. The client identifies itself to the server as eonyx with the build version.

MCP tools are not on the always-allowed list — on the first call EONYX shows an Allow once / Allow always / Deny dialog, just like for any writing tool. So that a trusted tool does not ask every time:

"permissions": {
  "allowed_tools": ["github_search_issues", "tracker_get_task"]
}
Security
  • Do not keep tokens in the config text (the project config is committed to the repository). In the headers of an HTTP server, values expand $ENV references. For a stdio server the env values are substituted literally — but the process inherits your environment, so it is enough to keep the secret in an environment variable instead of the config.
  • Add specific tools to allowed_tools, not everything at once: an MCP server performs actions on your behalf.
  • Remember that descriptions and results of MCP tools end up in the model’s context — do not connect servers you do not trust.

For one common case MCP is not required: EONYX has built-in read-only reporting tools for PostgreSQL. It is enough to set the connection string:

"report": { "database_url": "$DATABASE_URL" }

Leave it empty and the tools are not registered at all; that is the off switch.

Once connected, the server’s tools line up alongside the built-in ones. Here is exactly what the model receives.

Every tool of a server is registered under the name <server>_<tool>: on the github server the search_issues tool becomes github_search_issues. The argument schema is taken from the server as is, and the result is returned to the model as text.

The path of a single call

sequenceDiagram
    participant M as Model
    participant P as EONYX
    participant S as MCP server
    participant E as External system
    M->>P: github_search_issues call
    P->>S: request over stdio / HTTP
    S->>E: call to the API or database
    E-->>S: data
    S-->>P: result
    P-->>M: result as text

Connecting servers at startup

sequenceDiagram
    participant P as EONYX
    participant A as github server
    participant B as tracker server
    P->>A: connect at startup
    A-->>P: tools registered
    P->>B: connect at startup
    B--xP: server unavailable
    Note over P,B: warning: mcp — skipped
    Note over P: startup continues without it

Connecting is best-effort: working servers register their tools, a failing one is cut off with a warning, and EONYX starts in any case.

If the server declares the corresponding capabilities (EONYX checks this during registration), these appear as well:

ToolPurpose
<server>_list_resourceslist the server’s resources
<server>_read_resourceread a resource by uri
<server>_list_promptslist the prompts
<server>_get_promptget a prompt by name (+ arguments)

Binary resources are not dumped into the context: instead of the content the model sees the marker (binary resource <uri>, N bytes).

Active servers are visible in the TUI header — the » mcp segment. Ctrl+K opens the capabilities dialog (Skills / MCP tabs): any server can be turned off and on right in the session — its tools are hidden from the model and stop being called, with no restart and no config edits. The / marks show the state.

Cheat sheet
  • Configuration
    • the mcp array in eonyx.json
    • command+args+env for stdio, url+headers for HTTP
  • Naming
    • <server>_<tool> for every tool
    • plus resource and prompt tools if the server supports them
  • Fault tolerance
    • a failing server is skipped with a warning
    • EONYX always starts
  • Management
    • Ctrl+K turns servers on and off on the fly
    • the header shows the active ones
  • Permissions
    • MCP tools go through the common gate
    • add trusted ones to allowed_tools by name