Docs

Search docs

Search pages and tools

Reference

Architecture

How the namespaces are wired onto one mux, and why adding one never touches main.go.

Namespaces self-register through internal/mcpx. Each package calls mcpx.Register from its init(); the mux mounts every registered namespace on the next start.

Request lifecycle

Every request passes global middleware — panic recovery, then logging — hits the stdlib mux, and is admitted by the auth that belongs to that route: X-API-Keyfor the MCP namespaces, Clerk for the dashboard’s key API, nothing for the liveness probe.

MCP client
sends X-API-Key header
Recover
panic → 500
LogRequests
logs arrival + completion
net/http mux
match route
GET /healthz
200 ok
no auth — liveness only
/*/mcp
RequireAPIKey
key in api_keys? else 401
5 namespaces
memory · skills · gsc · producthunt · event
/api/keys
Clerk RequireUser
signed-in human? else 401
keysapi
list · create · delete (owner-scoped)

Admission is enforced per route, not globally — so a namespace can’t forget it, and /healthz never needs a credential. memory also resolves the same key to an api_key_id to scope every row — identity, not admission.

Self-registration

Each package calls mcpx.Register from its init(), so importing it is enough to enroll the namespace. mcpx.Handler then builds every registered server, failing fastif any can’t — rather than mounting a half-working server that only breaks on the first tool call.

package init()
memoryskillsgscproducthuntevent
mcpx.Register(ns)
mcpx registry
collects every self-registered namespace
mcpx.Handler(opts)
cmd/server/main.go calls this once
ns.Server(deps)
build each server — fail fast on bad config
mux.Handle(path, RequireAPIKey(server))
mounted over Streamable HTTP

Adding a namespace is a new package plus a blank import — main.go never enumerates them.

Layout

internal/
cmd/server/main.go     # config, graceful shutdown
internal/
  mcpx/                # registry, Handler(), Chain()
  memory/              # per-user memories, hybrid RAG (pg + pgvector)
  skills/              # skills_find agent + skills_download + web tools
  gsc/                 # Google Search Console (analytics, inspection, sitemaps)
  producthunt/         # Product Hunt v2 GraphQL API
  event/               # Kafka publish/consume + topic admin (Confluent Cloud)

Adding a namespace

  1. 1
    Create the package
    Add internal/<name>/register.go that calls mcpx.Register from init().
  2. 2
    Blank-import it
    Add the package to cmd/server/main.go imports. The mux picks it up on the next start.
One boundary
Router is stdlib net/http; a domain never reaches across another domain except through internal/mcpx.