@xylex-group/athena-mcp
v1.0.0
Published
MCP server adapter for Athena JS 5
Maintainers
Readme
@xylex-group/athena-mcp
current version: 1.0.0
Embedded MCP adapter for an Athena JS application. The package runs Athena in the same Node process as the MCP server: PostgreSQL is direct, Auth is embedded, and request identity is scoped to each tool call.
Application binding
When MCP is hosted by an Athena application, bind the application's existing root. This is the preferred integration and keeps Auth, Billing, Storage, notifications, lifecycle hooks, and diagnostics on one runtime authority:
import { athena } from "@/lib/athena/root";
import {
createAthenaMcpApplicationBinding,
createAthenaMcpNextHandler,
} from "@xylex-group/athena-mcp/next";
const binding = createAthenaMcpApplicationBinding({
root: athena,
source: "application-instance",
ownership: "borrowed",
});
// `config` is the existing Athena MCP server configuration.
export const POST = createAthenaMcpNextHandler({ binding, config });MCP never closes a borrowed root. Application-owned tools, topology projections, sanitized canonical inspection, and principal resolvers can be attached to the same binding. Capabilities are declared on each tool with Athena capability keys and checked against the current Capabilities IR at invocation time.
For standalone stdio or cloudflared development, declare an application-owned
factory in athena.config.ts:
tooling: {
runtime: "src/lib/athena/mcp-runtime.ts",
}The module must export exactly one createAthenaToolingRoot or
createAthenaMcpRoot function. The path is project-relative and load failures
are fatal; MCP does not fall back to a partial database runtime.
Database-only compatibility
$env:DATABASE_URL = "postgres://localhost/athena"
$env:ATHENA_MCP_PROJECT_ROOT = "C:\path\to\application"
npx @xylex-group/athena-mcpDATABASE_URL is required. The server rejects gateway URLs, API keys, and
client-selector configuration instead of silently switching to a remote
runtime.
Projects without an application binding remain supported in explicitly
degraded database-only mode. The server reports binding_source=mcp-database
and application_aware=false; it does not claim to reconstruct the full
application runtime. When athena.config.ts is present, static compatibility
discovery and generated model registry loading remain available.
Ownership
There is one Athena root authority per MCP process:
createClient({ databaseUrl, auth: { mode: "local" } })
-> AthenaRuntime.root
-> root.withContext(requestContext)
-> borrowed tool viewThe root owns the PostgreSQL pool and embedded Auth lifecycle. Borrowed request views cannot close the root. Stdio and stateless Streamable HTTP share this same runtime; MCP transports do not create additional Athena roots.
Canonical IR resources
Bound servers expose read-only, sanitized application resources:
athena://app
athena://app/topology
athena://app/runtime
athena://app/configuration
athena://app/capabilities
athena://app/schema
athena://app/models
athena://app/migrations
athena://app/auth
athena://app/billing
athena://app/storage
athena://app/policy
athena://app/diagnostics
athena://app/principal
athena://app/traces
athena://app/ir
athena://app/ir/{id}
athena://app/ir/docs-apiThe /app/capabilities, /app/schema, and /app/policy resources remain
compatibility aliases over the canonical registry. Resources are observational
and protected application resources require a verified principal or trusted
MCP ingress authorization. Mutations remain MCP tools and application tools
receive only a request-scoped Athena view, principal, request id, and abort
signal.
The MCP tool inventory is intentionally stable. Each capability-dependent tool
publishes its requiredCapabilities metadata, while the current Athena
Capabilities IR is checked again at invocation time. Unknown or unavailable
capabilities therefore reject execution without changing the registered MCP
catalog.
Configuration
| Variable | Purpose | Default |
| --- | --- | --- |
| DATABASE_URL | Direct PostgreSQL connection string | required |
| ATHENA_MCP_PROJECT_ROOT | Application project directory | current directory |
| ATHENA_MCP_CONFIG | Project config path | discovered athena.config.* |
| ATHENA_MCP_AUTH_AUTO_MIGRATE | Apply embedded Auth migrations at startup | false |
| READ_ONLY | Disable mutating tools | true |
| ATHENA_MCP_TOOL_TIMEOUT_MS | Deadline for each tool invocation | 30000 |
| ATHENA_MCP_TRANSPORT | stdio or http | stdio |
| ATHENA_MCP_HTTP_HOST | Streamable HTTP bind host | 127.0.0.1 |
| ATHENA_MCP_HTTP_PORT | Streamable HTTP port | 8787 |
| ATHENA_MCP_HTTP_AUTH_TOKEN | Bearer token for HTTP POST requests | unset |
| ATHENA_MCP_ALLOW_UNAUTHENTICATED_HTTP | Permit non-loopback HTTP without a token | false |
| ATHENA_MCP_PROFILES | Comma-separated tool profiles | core,database,docs |
All command-line options are listed by athena-mcp --help.
Security
Keep the MCP process on a trusted host. HTTP binds to loopback by default and
rejects unauthenticated non-loopback binds. The HTTP ingress token is separate
from Athena request credentials and is never forwarded as a bearer token.
Request identity is held in async-local storage or an individual
withContext() view; no process-global user or organization is maintained.
Development
npm install
npm run typecheck
npm test
npm run buildGenerated tool contracts are updated with:
npm run contracts:generateTool telemetry records a normalized outcome for every invocation. The
totalErrors counter is limited to unavailable, dependency, and internal
failures; read-only, validation, and authorization rejections are tracked
separately in the outcome counters. Billing tools are registered only when
their required methods exist on the embedded Athena runtime.
The docs tools consume the Athena JS Docs API manifest in docs/generated and
package the declared artifact into a stable dist/assets/docs-api/athena-js.json
path. Published MCP runtimes do not resolve Docs IR from a sibling checkout.
