Connect a client¶
An MCP client talks to Artek-MCP over MCP Streamable HTTP at one URL on the gateway, authenticated with an API key (or an OAuth token, if you enable it). The server is stateless: there is no session to open and no event stream.
Endpoints¶
| Route | Method | Auth | Purpose |
|---|---|---|---|
/data/artek-mcp/mcp |
POST | API key or OAuth token | MCP JSON-RPC 2.0 (protocol 2025-06-18; also accepts 2025-03-26 and 2024-11-05) |
/data/artek-mcp/mcp |
GET | none | returns 405 (stateless server, no SSE stream) |
/data/artek-mcp/status |
GET | none | liveness and diagnostics summary, no secrets |
/data/artek-mcp/.well-known/oauth-protected-resource |
GET | none | OAuth protected-resource metadata (RFC 9728); 404 while the auth mode is apiKey |
/app/artek-mcp |
gateway web session | the settings and status page (Home → Artek MCP) | |
/data/artek-mcp/web/status |
GET | web session, READ | full diagnostics snapshot for the settings page |
/data/artek-mcp/web/config |
GET | web session, READ | current settings with tokens masked, plus a CSRF token |
/data/artek-mcp/web/config |
POST | web session, WRITE, plus X-CSRF-Token |
save settings (applies live, no restart) |
/data/artek-mcp/web/db-connections |
GET | web session | the gateway's database connections (name, vendor, status) for the Database access card |
The /web/* routes and the settings page authenticate with the gateway web session (cookie plus the gateway's READ or WRITE permission). They never accept an API key.
Authenticating¶
Send the key on every POST to the MCP endpoint, in either header:
Authorization: Bearer <token>
X-Artek-MCP-Token: <token>
The MCP URL is:
http://<gateway>:<port>/data/artek-mcp/mcp
Use https and the gateway's HTTPS port when the gateway serves TLS.
Claude Code¶
Register the gateway as an HTTP MCP server:
claude mcp add --transport http artek-mcp http://<gateway>:<port>/data/artek-mcp/mcp \
--header "Authorization: Bearer <token>"
Start a new Claude Code session and ask it to call mcp_status to confirm the connection.
Other MCP clients¶
Any client that supports the Streamable HTTP transport and custom request headers can connect. Configure:
- Transport: Streamable HTTP
- URL:
http://<gateway>:<port>/data/artek-mcp/mcp - Header:
Authorization: Bearer <token>(orX-Artek-MCP-Token: <token>)
Reconnect after the tool list changes
A client caches the tool list for the life of its connection, and this server does not push list-change notifications. After you change a key's tool profile, enable a provider, or add a script endpoint (which also needs a gateway restart), reconnect the client to see the new list.
Checking what your key can do¶
Two diagnostics tools describe the calling key, and are useful as a first call from any client:
mcp_status: the provider inventory, the policy and the key list, narrowed to what your key's profile can reach, plus your effective rate limits (caller.rate), name-echo state (caller.nameEcho) and read-scope coverage (caller.readScopeCoverage).policy_explain: give it atoolandargumentsand it walks the authorization chain gate by gate for your own key, without running the call.
The artek-mcp://tools resource lists every tool your key can call, grouped by provider, with each tool's risk level and whether it changes anything.
OAuth mode¶
auth.mode selects how the MCP endpoint authenticates:
| Value | Behavior |
|---|---|
apiKey |
API keys only (default) |
oauth |
OAuth bearer JWTs only |
both |
API keys are tried first, then a JWT |
The OAuth modes validate RS256 or ES256 bearer JWTs against auth.oauth:
"auth": {
"mode": "both",
"keys": [ { "name": "default", "token": "…" } ],
"oauth": {
"issuer": "https://idp.example.com",
"jwksUrl": "https://idp.example.com/.well-known/jwks.json",
"audience": "artek-mcp",
"requiredScopes": ["mcp:read"],
"cacheSeconds": 300
}
}
A token is accepted when all of these hold:
- its signature verifies against the JWKS (keys are cached for
cacheSeconds, refreshed when an unknownkidarrives, and the last good set is kept if a refresh fails); issmatchesissuerexactly;audcontainsaudience;expandnbfare valid, with 60 seconds of clock skew allowed;- every
requiredScopesentry is present in the token'sscopestring orscparray.
The audit log records an OAuth caller as oauth:<sub>.
audience is required, and issuer and jwksUrl must use https
- Without a usable
issuer,jwksUrland a non-blankaudience, the module refuses to enable OAuth, logs a WARN naming the missing field, and falls back toapiKey. Without an audience check, any valid token your identity provider issued for any other application would be accepted as full MCP access. - A plain
httpissuer or JWKS URL is refused (401), because the signing keys would cross the network in the clear. Plainhttpis allowed only to a loopback host, for local development. requiredScopesis optional, but an empty list means no scope restriction.
401 responses carry a WWW-Authenticate: Bearer realm="Artek-MCP", resource_metadata="…/.well-known/oauth-protected-resource" header, so MCP clients that follow the specification can discover your authorization server. The JWKS response is read with a 512 KB limit.
An OAuth caller is not one of the configured API keys, so the per-key mutation, database and read lists do not narrow it. The gateway-wide policy (read-only flag, mutation allowlist, database connection list) applies in full. See Configuration.