Service Mcp Servers - thekaveh/atlas GitHub Wiki
5.2.31. Curated MCP Servers
1. Overview
The Curated MCP Servers service exposes the first Atlas Model Context Protocol tool surface. It is intentionally small: Postgres read queries, Neo4j schema/read Cypher, and SearXNG web search.
This is not a generic one-server-per-service pattern. The package starts with tools that are useful across Open WebUI, Hermes, and future agent workflows. Its query filters and routing hints bound common requests but are not a least-privilege security boundary.
The runtime uses the standalone FastMCP 3 framework (fastmcp==3.4.4), pinned exactly to control the framework version. It serves Streamable HTTP at /mcp.
2. Access
| Surface | URL | Notes |
|---|---|---|
| Direct MCP endpoint | http://localhost:${MCP_SERVERS_PORT}/mcp |
Host publish is loopback-only; backend-network containers can call the unauthenticated service-DNS endpoint directly. |
| Kong MCP endpoint | http://mcp.localhost:${KONG_HTTP_PORT}/mcp |
Routed only when MCP_SERVERS_SOURCE=container. Kong dashboard credentials apply. |
MCP_SERVERS_SOURCE=disabled is the default. Enable it with:
./start.sh --mcp-servers-source container
3. Configuration
| Variable | Default | Purpose |
|---|---|---|
MCP_SERVERS_SOURCE |
disabled |
Enables or disables the curated MCP package. |
MCP_SERVERS_PORT |
generated | Host port assigned by Atlas topology. |
MCP_POSTGRES_DB_USER |
atlas_mcp |
Restricted read-only Postgres login used by the Postgres tool (ยง6). Its password is generated. |
MCP_POSTGRES_MAX_ROWS |
50 |
Maximum rows returned by the Postgres tool. |
MCP_NEO4J_MAX_ROWS |
empty | Maximum rows returned by the Neo4j tool. Empty uses MCP_POSTGRES_MAX_ROWS. |
MCP_SEARXNG_MAX_RESULTS |
5 |
Maximum results returned by the SearXNG tool. |
MCP_TOOL_TIMEOUT_SECONDS |
15 |
Upstream call timeout. |
4. Architecture & Wiring
mcp-servers calls:
- Supabase Postgres through
supabase-db:5432 - Neo4j through
NEO4J_URI - SearXNG through
http://searxng:8080
The runtime serves Streamable HTTP (stateless, JSON responses) at /mcp on container port 8000, published to loopback (127.0.0.1) on the host. Transport settings live on FastMCP 3's run(transport="http", โฆ) call, not the constructor.
FastMCP 3's Host/Origin protection is on. It accepts only the loopback forms (127.0.0.1, localhost, ::1), the Compose hostname mcp-servers and the Kong hostname mcp.localhost. Any other Host/Origin gets 421/403. This guard defends against DNS rebinding; it is not authentication. Kong Basic Auth + ACL protect only the Kong route. Backend-network containers can call the unauthenticated http://mcp-servers:8000/mcp with the mcp-servers Host.
Open WebUI and Hermes should consume the service directly as HTTP MCP clients where possible. LiteLLM MCP Gateway is reserved for cases where Atlas explicitly wants model-facing tool access under LiteLLM key/team/org policy.
MetaMCP, Docker MCP Gateway, and mcpo remain later or conditional tools. MetaMCP becomes attractive once Atlas needs namespaces and per-consumer policy across several MCP servers. Docker MCP Gateway fits broad vendor connector catalogs better than this internal-service-first slice. mcpo is a translator for stdio-only or OpenAPI-only cases, not the Atlas default architecture.
5. Capabilities & limitations
Support tier: experimental โ Capability contract declared; no cited cold-start, workflow, or upgrade qualification run yet (evidence at v0.1.0).
| Capability | Status | Verification | Notes |
|---|---|---|---|
| Curated Streamable HTTP tools | supported | tested | Atlas serves FastMCP tools for bounded Postgres reads, Neo4j schema/read Cypher, and SearXNG search through one stateless /mcp endpoint. |
| Database query guardrails | partial | tested | Regex filters, Postgres read-only transactions, Neo4j READ_ACCESS, and row/time caps block common direct mutation syntax. They do not prevent privileged function or procedure side effects within the rights of the connecting role. Postgres runs as the restricted atlas_mcp login; Neo4j runs with its admin credentials. |
| Tenant-scoped Postgres reads | partial | tested | MCP uses a dedicated read-only login without object ownership or BYPASSRLS and permits bounded SELECT/WITH/SHOW/EXPLAIN. It reads the public, n8n and storage schemas minus a credential deny list. There is no schema, table, or column allowlist or redaction, so access remains operator-scoped rather than tenant-scoped. |
| MCP ingress authentication | partial | tested | 127.0.0.1 protects only the host publish. Inside Docker, all backend-network containers can call unauthenticated http://mcp-servers:8000/mcp with the allowed mcp-servers Host. They bypass Kong Basic Auth and ACL. Host/Origin checks are not authentication. |
| Write and administration prevention | partial | tested | Atlas ships no dedicated write or administration tool. Accepted CALL db.* procedures run with the Neo4j admin credentials and can cause administration or write side effects. Neo4j loads APOC unrestricted, but the validator admits only argument-free apoc.meta.* calls. Accepted SELECT functions run as the restricted atlas_mcp Postgres login. |
| Per-consumer MCP authorization | not-supported | tested | Unauthenticated backend-network callers bypass Kong. All Kong dashboard consumers reach the same tool set and administrator credentials for Neo4j, and the shared atlas_mcp Postgres login. Atlas configures no application credential, OAuth scopes, tenant namespaces, or tool policy. |
6. Security & Guardrails
- Guardrail summary: consent, credential handling, namespace discipline, syntactic query filters, prompt-injection awareness, and bounded result sizes are part of the current contract. These controls do not provide tenant isolation or complete side-effect prevention.
- Consent: MCP clients should expose tools only after an operator intentionally enables
MCP_SERVERS_SOURCE=containerand registers the endpoint. - Credential handling: database credentials stay in the container environment; never paste them into client configs. The Postgres tool connects as the scoped read-only
atlas_mcprole (MCP_POSTGRES_DB_USER), not the RLS-bypassingsupabase_adminowner. The role has no superuser or BYPASSRLS rights. It can SELECT tables in thepublic,n8nandstorageschemas; RLS-enabled Atlas tables return no rows to it. - Credential deny list: these tables and columns are revoked from the role:
- Open WebUI:
auth,config,oauth_session,api_key,tool.valves,function.valves,user.api_key,user.settings. - n8n:
credentials_entity,user_api_keys, the OAuth token/client/code tables,secrets_provider_connection,deployment_key,settings,event_destinations,variables, and theuserpassword and MFA columns.
- Open WebUI:
- Deny-list gaps: a table an app adds later is readable until it is added to the list (n8n's from creation, others from the next restart). The list is applied at stack start, before n8n's first migrations. On a fresh install, n8n's listed tables (including a first-session API key) stay readable until the next
./start.sh. There is no schema, table, or column allowlist or output redaction. Use the tool only with trusted operators. - Query side effects: accepted privileged SQL functions and Neo4j procedures can still cause side effects, within the rights of the connecting role.
- Query side effects (Postgres): the validator rejects multiple statements and common mutation keywords. It does not block every function; it accepts
pg_read_fileandpg_terminate_backend. Such calls run as the unprivilegedatlas_mcprole, which has no superuser, file-read or signal privileges. - Query side effects (Neo4j): the tool connects with the Neo4j admin credentials (
GRAPH_DB_USER, defaultneo4j). The read session blocks writes such asdb.createLabel, but procedures such asdb.checkpointstill run. - APOC: Neo4j loads APOC core.
apoc.load.*sends HTTP requests to any backend-network service, andapoc.meta.*.of/apoc.cypher.*run Cypher strings, all from a read session. The Cypher validator therefore rejects:- any APOC call except exact argument-free
CALL apoc.meta.schema()/stats()/data(), optionally withYIELD โฆ RETURN โฆof plain names; - any other text that contains
apoc, including string literals (so a read that filters on a URL containingapocis refused); - any statement that contains a backslash, because Neo4j decodes
\uXXXXescapes inside names; - backtick-quoted names that spell a blocked keyword (for example
n.`set`).
- any APOC call except exact argument-free
- Unaliased
RETURN: aRETURNof an unaliased expression (RETURN n.name,count(*)) cannot run inside the server-sideLIMITwrapper. The tool runs it unwrapped and caps the rows client-side. - Namespace discipline: tool names are prefixed by their backend purpose to avoid collisions as more MCP servers arrive.
- Prompt-injection risk: treat database rows and web search results as untrusted tool output.
- Rate and size limits: use
MCP_POSTGRES_MAX_ROWS,MCP_NEO4J_MAX_ROWS,MCP_SEARXNG_MAX_RESULTS, andMCP_TOOL_TIMEOUT_SECONDSinstead of unbounded queries. - Host/Origin boundary: see ยง4. The check defends against DNS rebinding; it is not authentication. All
backend-networkcontainers bypass Kong's Basic Auth/ACL policy. - Framework pinning:
fastmcp==3.4.4andmcp==1.28.1are pinned exactly, because FastMCP permits breaking changes in minor releases. The image build runspip check. Bump both together. Before upgrading, re-runbootstrapper/tests/test_mcp_servers_framework.py; it exercises the real FastMCP client, the/mcptransport and the Host/Origin guard.
7. Troubleshooting
- If startup fails with a Neo4j or SearXNG dependency error, enable the missing service or keep
MCP_SERVERS_SOURCE=disabled. - If SearXNG search returns 403, confirm the in-stack SearXNG instance has JSON output enabled.
- If Open WebUI cannot call the Kong URL, configure the MCP server as Streamable HTTP and include the required Kong Basic Auth credentials.
8. Dependencies & Integrations
8.1. Current โ Upstream (this service calls)
| Service | Category |
|---|---|
| neo4j | data |
| supabase | data |
| searxng | media |
8.2. Current โ Downstream (services that call this)
| Service | Category | Status |
|---|---|---|
| kong | infra | current |
| trueforge | agents | current |
| jupyterhub | apps | optional: MCP_SERVERS_SOURCE=container |
8.3. Architecture diagram

Open the full-size diagram for a full-screen view.
8.4. Future โ Missing pair integrations
No high-confidence opportunities identified.
8.5. Future โ Candidate new services
- Docling MCP is the first candidate for a specialist MCP server, because upstream supports remote Docling Serve and Streamable HTTP. It needs its own disabled SOURCE and a decision on document-upload authorization.
8.6. Future โ Unused features in this service
No high-confidence opportunities identified.