MCP Integration
AllSource ships a Model Context Protocol (MCP) connector so AI agents — Claude Desktop, Cursor, or anything that speaks MCP — can ingest, query, and reason over your event store in natural language. This page shows how to connect to your production data securely, and how that differs from the throwaway localhost setup.
How a secure connection is shaped
The MCP connector never talks to the database (Core) directly. Every request is mediated by the authenticated gateway at https://api.all-source.xyz, which validates your API key, scopes the call to your tenant, and enforces quotas and rate limits. Core is internal-only and trusts any caller on its network — so it is never exposed to the public, and neither your agent nor the connector should ever point at it.
Claude Desktop / Cursor
│ (MCP — local, stdio or localhost SSE)
▼
AllSource MCP connector ← runs on YOUR machine / your infra
│ HTTPS + Authorization: Bearer <serviceaccount key>
▼
https://api.all-source.xyz (gateway) ← validates key, derives tenant_id
│ internal network only
▼
AllSource Core (your tenant's events only)Three properties make this safe: the key is a least-privilege, tenant-scopedcredential (a scoped key can only ever read/write its own tenant's events); the transport to the gateway is TLS; and the connector runs where you control it, so your key never leaves your environment.
1. Mint a least-privilege API key
An MCP agent needs to read and write events — nothing more. Mint a key with the serviceaccount role: it is granted read + write and is denied admin, tenant management, metrics, and schema administration. Do not use an admin JWT or an admin-role key as your connector credential.
Self-service (creates a tenant and returns a scoped key in one call):
curl -X POST https://api.all-source.xyz/api/v1/onboard/start \
-H "Content-Type: application/json" \
-d '{"name": "my-agent"}'
# →
# {
# "tenant_id": "my-agent-a1b2c3",
# "api_key": "eyJhbGciOiJIUzI1NiIs...", ← store this in a secret, shown once
# ...
# }Already onboarded? Mint a fresh, role-scoped key with an admin token:
curl -X POST https://api.all-source.xyz/api/v1/teams/agent-keys \
-H "Authorization: Bearer $ADMIN_JWT" \
-H "Content-Type: application/json" \
-d '{"name": "claude-desktop", "role": "serviceaccount"}'The role string is exactly serviceaccount — no underscore. A drifted service_account is rejected and every request silently 403s.
2. Run the MCP connector against production
Run the connector yourself and point it at the gateway with your key. The two knobs that matter: CORE_URL (the gateway, not Core) and CORE_API_KEY (your scoped key, supplied as a secret — never hard-coded).
docker run -p 3904:3904 \
-e CORE_URL=https://api.all-source.xyz \
-e CORE_API_KEY=$ALLSOURCE_API_KEY \
ghcr.io/all-source-os/chronos-mcp:latestWith those set, the connector authenticates to the gateway on every call over HTTPS; the gateway resolves your tenant from the key and returns only your tenant's data. Pass the key from your shell or a secrets manager ($ALLSOURCE_API_KEY), so it is never written into an image, a compose file, or your shell history.
3. Point your MCP client at the connector
Your AI client connects to the connector running on your machine — it never holds the API key itself. Add this to your claude_desktop_config.json:
{
"mcpServers": {
"allsource": {
"url": "http://localhost:3904/sse"
}
}
}The client → connector hop is local (loopback); the connector → gateway hop is the authenticated, TLS one. Your production credential lives only in the connector's environment, not in the client config.
4. Verify the connection is tenant-scoped
Before trusting the agent, confirm the key reaches your data and only your data. The same credential against the gateway REST API:
curl "https://api.all-source.xyz/api/v1/events/query?limit=1" \
-H "Authorization: Bearer $ALLSOURCE_API_KEY"
# → {"events": [ ... ], "count": N} ← your tenant's events onlyThen ask the agent to run a query through MCP and check the result matches. A scoped key cannot read another tenant's events — the gateway derives the tenant from the key, not from any field the caller supplies.
Production hardening checklist
- Use the gateway, never CoreAlways set CORE_URL=https://api.all-source.xyz. Core is internal-only and trusts any caller on its network — pointing an external connector at it bypasses auth, quotas, and tenant isolation entirely.
- serviceaccount role, least privilegeMint the connector key as serviceaccount (read + write). Reserve admin keys for humans; never hand an admin credential to an agent.
- Key in a secret, not in configInject CORE_API_KEY from an environment secret or secrets manager. Keep it out of images, compose files, claude_desktop_config.json, and git.
- TLS onlyCORE_URL must be https://. The connector → gateway hop carries your key — never run it over plain http in production.
- Rotate and revokeRotate the key on a schedule and immediately if a machine running the connector is lost. Revoke from the dashboard; a revoked key fails closed.
- One key per connectorGive each connector / machine its own key so you can revoke a single one without taking down the rest, and so audit trails stay attributable.
What the agent can do
Through the connector your agent gets the event-store toolset — all scoped to your tenant by the key:
ingest_eventStore a new event in a streamquery_eventsQuery events by stream, type, time range, or entitycreate_projectionBuild a materialized view over event streamsget_stream_statsEvent counts and throughput for a streamregister_schemaRegister a JSON schema for event validationhealth_checkCheck Core and system healthTroubleshooting
- 401 from the gatewayNo / invalid key. Confirm CORE_API_KEY is set in the connector's environment and the key hasn't been revoked or expired.
- 403 on every callRole drift. The key's role must be the exact string serviceaccount (no underscore). Re-mint with the correct role.
- Empty results but data existsWrong tenant or wrong base URL. Verify CORE_URL is the gateway and the key belongs to the tenant that owns the data — the gateway scopes by key, so a key from another tenant returns nothing, not an error.
- Connector can't reach the gatewayCheck egress/TLS from the machine running the connector to https://api.all-source.xyz. Do not work around it by pointing CORE_URL at Core.
Local development (no auth — never for production)
When you run the full AllSource stack locally, the connector points at your local Core with no key. This is convenient for development but has no authentication and no tenant isolation — only ever use it against a local Core, never against production:
# LOCAL ONLY — local Core, no auth. Do not use these values for production.
docker run -p 3904:3904 \
-e CORE_URL=http://host.docker.internal:3900 \
ghcr.io/all-source-os/chronos-mcp:latestThe difference between this and a secure production connection is exactly the two things above: CORE_URL pointed at the gateway instead of a local Core, and a scoped CORE_API_KEY.
A note on hosted MCP
Today you run the MCP connector yourself (locally or on your own infrastructure) and it reaches production through the gateway — there is no public, multi-tenant hosted MCP URL to point a client at directly. If you only need to store and query events and don't want to run a connector at all, the gateway REST API and the SDKs give you the same tenant-scoped access with the same serviceaccount key.
