Implements the walking skeleton from the roadmap: agents connect to one HTTP
endpoint and Nexus aggregates upstream MCP servers behind it with namespaced
tools. Written in Go (single static binary), no external services required.
What works end-to-end (verified live + hermetic e2e tests):
- MCP protocol layer: JSON-RPC 2.0 + initialize/tools.list/tools.call
(internal/mcp), with stdio (subprocess) and Streamable HTTP client
transports, and a reusable stream transport for in-process wiring.
- Router + Dynamic Tool Registry: connects/initializes upstreams in parallel,
loads tools, namespaces them as {namespace}.{tool}, dispatches tools/call to
the owning upstream; refreshes on list_changed. A failed upstream stays
not-ready without taking down the gateway (data plane stays up).
- Gateway: single MCP endpoint (POST /mcp) that is an MCP server to agents,
plus /healthz and a minimal /metrics exposition.
- CLI (cmd/nexus): `serve`, `connect` (stdio<->HTTP bridge for local agents),
`demo-mcp` (built-in zero-dep demo server: echo/add/now), `version`.
- Config: declarative YAML with env expansion + validation.
- Store: persistence interfaces + in-memory impl (SQLite lands later).
Foundations for later phases: domain types (ARCHITECTURE §7), two-plane
split, event-driven refresh seam.
Tooling: Makefile (build/test/vet/fmt with version ldflags), config.example
.yaml. GOPATH moved to /go so it doesn't collide with the module root at /root;
.gitignore whitelist extended to track Go sources while ignoring build output.
Tests: unit (registry/namespacing) + full e2e (client -> demo server over
pipes -> router -> HTTP gateway: initialize, aggregated tools/list, tool-call
routing, unknown-tool error). go vet + gofmt clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
38 lines
1.2 KiB
YAML
38 lines
1.2 KiB
YAML
# MCP Nexus — example configuration (Phase 1).
|
|
#
|
|
# In Phase 1, upstream MCP servers are declared statically here. Later phases
|
|
# populate them automatically via Discovery + Recipes + the Installer.
|
|
#
|
|
# Environment variables in this file are expanded (e.g. ${HOME}, ${GH_TOKEN}).
|
|
|
|
server:
|
|
# Address the aggregated MCP endpoint + ops routes listen on.
|
|
address: ":8080"
|
|
|
|
gateway:
|
|
name: "MCP Nexus"
|
|
# Path the single aggregated MCP endpoint is served on.
|
|
mcp_path: "/mcp"
|
|
|
|
upstreams:
|
|
# Zero-dependency demo server built into the nexus binary. Great for a first
|
|
# end-to-end test: exposes demo.echo, demo.add, demo.now.
|
|
- namespace: demo
|
|
transport: stdio
|
|
command: nexus
|
|
args: ["demo-mcp"]
|
|
|
|
# Example: the official filesystem MCP server via npx (requires Node).
|
|
# Uncomment to expose fs.* tools scoped to a directory.
|
|
# - namespace: fs
|
|
# transport: stdio
|
|
# command: npx
|
|
# args: ["-y", "@modelcontextprotocol/server-filesystem", "${HOME}"]
|
|
|
|
# Example: a remote MCP server over Streamable HTTP.
|
|
# - namespace: remote
|
|
# transport: http
|
|
# endpoint: "http://127.0.0.1:9000/mcp"
|
|
# headers:
|
|
# Authorization: "Bearer ${REMOTE_MCP_TOKEN}"
|