Skip to content

Architecture

flowchart LR
  client[MCP client] -->|stdio / Streamable HTTP| transport[transport/]
  transport --> adapter[server.py\nNeonServer]
  adapter --> registry[registry.py\nvalidate · auth · budget]
  registry --> tools[tools/*]
  tools --> resolve[neon/resolve.py]
  tools --> catalog[neon/catalog.py]
  tools --> proj[projections/*]
  catalog --> client2[neon/client.py]
  tools --> client2
  client2 --> limiter[neon/ratelimit.py]
  client2 --> cache[neon/cache.py]
  client2 -->|X-API-Token only where required| neon[(NEON REST + GraphQL)]
Module Role
__main__.py CLI: flags → config → logging → serve; --check, --print-config
config.py pydantic settings; flag > NEON_MCP_* env > YAML > defaults; token fallbacks
server.py the only SDK-coupled module: tools/list (sorted, 2020-12 schemas, cache hints), tools/call (text + structuredContent + upstream _meta), MRTR, resources, prompts
registry.py @register_tool, argument validation, fail-fast auth_required, result budget (fit_to_budget), requestState codec
context.py ToolContext handed to handlers; request-scoped context variables
errors.py ToolError codes and the NEON error mapping (400 "not found" → not_found)
neon/client.py one httpx client: token placement, retries, redirects via the host allow-list, envelope unwrapping
neon/ratelimit.py, neon/cache.py per-identity token buckets; TTL cache with single-flight, refresh-ahead, stale-if-error
neon/catalog.py GraphQL-first product/site indexes (REST fallback, circuit breaker), availability, batched locations
neon/resolve.py code-or-name resolution with an acceptance margin
neon/filenames.py, neon/downloads.py NEON file-name grammar; confined plan-before-transfer downloads
projections/ NEON payloads → compact output models (NEON camelCase keys, month ranges, paging)
tools/ one module per family; each handler is async (args, ctx) -> Model
resources.py, prompts.py, resources_static/ neon:// resources, templates and prompts
transport/ stdio; stateless Streamable HTTP with /healthz, /readyz and a request-context middleware

Design decisions and their reasons are recorded in DESIGN.md and RESEARCH.md at the repository root.