k0smos MCP Project Context
This document explains the k0smos MCP service in customer-facing terms. It can be shared with AI tools or implementation partners as project context when they need to understand what the service does, how to connect to it, and which safeguards govern tool access.
What The MCP Service Is For
k0smos exposes a hosted Model Context Protocol (MCP) endpoint so approved AI clients can inspect and act on tenant data through controlled tools. The MCP service is useful when a client wants an assistant such as ChatGPT, Claude Code, Hermes, IronClaw, OpenClaw, MCP Inspector, or another HTTP MCP-compatible agent to:
- list and inspect operational tickets;
- create or update tickets through existing k0smos business rules;
- list and inspect actionable tasks, move them through their configured workflow, and add attributed comments;
- inspect projects, folders, and project document metadata;
- query finance dashboards, accounts, transactions, budgets, bills, tags, categories, piggy banks, and spending reports;
- record or update finance transactions when the authenticated user has the required permission.
The MCP endpoint is not a database export and not an unrestricted automation backdoor. It is a permission-gated API surface built on top of the same application services and ACL rules used by the k0smos admin UI.
Endpoint
Use the tenant API endpoint:
https://k0smos.example.com/api/mcp
Transport and protocol:
- Streamable HTTP, stateless.
- JSON-RPC 2.0.
POSTonly.- Supported methods:
initialize,ping,tools/list,tools/call, andnotifications/*. - No stdio, SSE, query-string credentials, URL tokens, or session IDs.
Prerequisites
Before a client connects:
- The tenant must be migrated.
- The MCP server must be enabled from
/admin/settings/mcp. - The connecting user must be active.
- The connecting user must have
mcp.use. - The connecting user must also have the permissions required by each tool they
should see or call, such as
ticket.view,project.edit, orfinance.create,todo.view, ortodo.edit.
Only active runtime modules contribute tools. If a module is disabled for a tenant, its MCP tools are not exposed.
Inspect and validate the exact active catalog without calling the HTTP endpoint:
php bin/console mcp:catalog --check
php bin/console mcp:catalog --check --format=json
The command and tools/list share the same catalog projection, preventing
drift in names, module ownership, permissions, annotations, and schemas.
Authentication Options
OAuth 2.1 For Interactive Clients
Use OAuth for ChatGPT and for clients that support remote MCP OAuth discovery. k0smos provides:
| Endpoint | Purpose |
|---|---|
GET /.well-known/oauth-protected-resource |
MCP protected-resource metadata for /api/mcp. |
GET /.well-known/oauth-protected-resource/api/mcp |
RFC 9728 path-aware discovery alias for /api/mcp. |
GET /.well-known/oauth-authorization-server |
OAuth authorization-server metadata. |
GET /.well-known/openid-configuration |
OIDC-compatible discovery metadata. |
POST /oauth/register |
Dynamic client registration for public clients. |
GET /oauth/authorize |
Browser login and consent. |
POST /oauth/token |
Authorization-code + PKCE exchange and rotating refresh-token grant. |
GET/POST /oauth/userinfo |
OIDC UserInfo for openid identity checks. |
The current MCP authorization specification prefers a predefined client when available, then Client ID Metadata Documents (CIMD), and uses DCR as a fallback. k0smos deliberately advertises DCR and does not advertise CIMD support: Claude and the other supported clients can use DCR, so an outbound, SSRF-sensitive metadata fetch would add risk without a required compatibility benefit.
ChatGPT should be configured with OAuth or mixed authentication for private tenant data. Do not configure private or mutating k0smos tools as no-auth.
OAuth access tokens issued by k0smos start with k0s_oat_.... They are
short-lived, opaque, bound to the public client and tenant MCP resource, and
accepted only for the MCP endpoint and OIDC UserInfo. Clients that register the
refresh_token grant (or explicitly request offline_access) also receive a
k0s_ort_... refresh token so Claude, Hermes, IronClaw, OpenClaw, and other
persistent clients can renew access without another browser login.
Refresh tokens are stored only as hashes, expire after 30 days, rotate on every
use, and revoke the whole grant family when a consumed token is replayed.
Scoped Personal API Tokens For Header-Based Clients
Clients that can send an HTTP bearer header can use a scoped personal API token:
Authorization: Bearer k0s_pat_...
Create these tokens from /admin/settings/mcp where possible. Prefer the
"MCP tools only" scope and include only the permissions the client needs:
mcp.use ticket.view project.view finance.view
A scoped token cannot exceed the live permissions of the user who created it. If the user loses a permission, the token loses that permission too. Revoke or rotate tokens from the k0smos admin UI when a client should no longer connect.
Client Examples
ChatGPT
Use the tenant MCP URL:
https://k0smos.example.com/api/mcp
If advanced OAuth fields are requested, use:
Protected resource metadata:
https://k0smos.example.com/.well-known/oauth-protected-resource
Authorization server metadata:
https://k0smos.example.com/.well-known/oauth-authorization-server
OIDC UserInfo endpoint:
https://k0smos.example.com/oauth/userinfo
The OAuth client is public, uses no client secret, and uses PKCE S256.
Claude Code With A Static Bearer Token
claude mcp add --transport http k0smos https://k0smos.example.com/api/mcp \
--header "Authorization: Bearer k0s_pat_..."
Claude Code With OAuth
claude mcp add-json k0smos \
'{"type":"http","url":"https://k0smos.example.com/api/mcp","oauth":{"scopes":"mcp.use ticket.view project.view finance.view"}}'
claude mcp login k0smos
Claude And Claude Desktop Custom Connectors
Add https://k0smos.example.com/api/mcp from Settings → Connectors → Add
custom connector, then connect with OAuth. Claude supports Streamable HTTP,
DCR, PKCE, expiring access tokens, and refresh. Its current exact callback is:
https://claude.ai/api/mcp/auth_callback
The announced future-domain callback is accepted through the same exact-URI DCR validation:
https://claude.com/api/mcp/auth_callback
The automated HTTP-kernel interoperability contract registers both callbacks
and completes the full DCR → authorization/consent → PKCE exchange → UserInfo →
scope-narrowing refresh → MCP tools flow with the current claude.ai callback.
Set scopes deliberately. openid, profile, and email describe identity.
Tool access comes from mcp.use plus k0smos permission scopes such as
ticket.view, project.edit, or finance.create.
Hermes Agent
Static token:
mcp_servers:
k0smos:
url: "https://k0smos.example.com/api/mcp"
headers:
Authorization: "Bearer k0s_pat_..."
OAuth discovery, DCR, PKCE, persistence, and refresh:
mcp_servers:
k0smos:
url: "https://k0smos.example.com/api/mcp"
auth: oauth
Hermes derives OAuth scopes from server metadata. For strict least privilege, prefer a scoped PAT when the Hermes version in use does not expose an explicit OAuth scope override.
IronClaw
Static token:
ironclaw mcp add k0smos https://k0smos.example.com/api/mcp \
--header "Authorization:Bearer k0s_pat_..."
For OAuth, first register IronClaw's exact loopback callback. The port and path below are examples and must match the callback configured in IronClaw:
curl -sS -X POST https://k0smos.example.com/oauth/register \
-H 'Content-Type: application/json' \
--data '{"client_name":"IronClaw","redirect_uris":["http://127.0.0.1:8765/callback"],"token_endpoint_auth_method":"none","grant_types":["authorization_code","refresh_token"]}'
ironclaw mcp add k0smos https://k0smos.example.com/api/mcp \
--client-id k0s_oauth_client_... \
--scopes "mcp.use,ticket.view,project.view,finance.view"
ironclaw mcp auth k0smos
ironclaw mcp test k0smos
OpenClaw
Static bearer headers are supported, but OAuth avoids embedding a token in the saved server definition:
openclaw mcp set k0smos \
'{"url":"https://k0smos.example.com/api/mcp","transport":"streamable-http","auth":"oauth","oauth":{"scope":"mcp.use ticket.view project.view finance.view"}}'
openclaw mcp login k0smos
openclaw mcp doctor k0smos --probe
Keep transport set to streamable-http; OpenClaw otherwise may select its SSE
transport for a generic HTTP URL.
Tool Discovery
Clients discover available tools with tools/list. k0smos hides tools the user
cannot call, so the list is already filtered by:
- tenant MCP enablement;
- active module status;
- route-level
mcp.use; - per-tool ACL permission.
Each tool includes standard MCP fields:
name;title;description;inputSchema.
Where possible, k0smos also exposes metadata:
annotations: read-only, destructive, idempotent, and closed-world hints for safer client behavior.outputSchema: successful structured-result schema._meta.k0smos/module: contributing module._meta.k0smos/requiredPermission: ACL permission needed to call the tool._meta.k0smos/oauthScope: OAuth scope to request for the same authority._meta.k0smos/domain: functional domain such asticket,project, orfinance._meta.k0smos/resultShape: result envelope hint such asticket_collection,project_detail, orfinance_report.
These metadata fields help an AI client explain what it can do, ask for confirmation before risky actions, and request the least-privilege scopes needed for a session.
Current Tool Areas
| Area | Typical tools | Required permission family |
|---|---|---|
| Tickets | list, get, create, add comment, change status, assign, close | ticket.* |
| Projects | list, get, create, update, delete, folder CRUD, document metadata list/search | project.* |
| Tasks | bounded list, workspace detail, workflow move, attributed comment | todo.* |
| Finance | overview, lists, reports, record/update/delete transactions, move piggy-bank money | finance.* |
The exact tool list depends on the tenant's active modules and the authenticated user's permissions.
Safety Model
k0smos applies multiple gates before an AI client can call a tool:
- The tenant MCP kill switch must be enabled.
- The request must authenticate as an active user.
- The user or token must have
mcp.use. - The contributing module must be active for the tenant.
- The user or token must have the tool's required permission.
- Mutating tools execute as the authenticated user, so writes remain attributable.
Invalid tool arguments are returned as tool errors that the AI client can correct and retry. Protocol errors are returned as JSON-RPC errors.
Operating Guidance
- Use OAuth for ChatGPT and interactive clients that persist credentials.
- Use scoped PATs for managed/unattended clients that can inject bearer headers securely.
- Prefer least-privilege scopes.
- Keep finance mutation permissions narrow.
- Review the tool list after changing a user's role or enabling/disabling a module.
- Revoke client tokens that are no longer in use.
- Do not share full-authority personal tokens with third-party AI clients.
- Treat repeated HTTP 429 OAuth responses as back-pressure and honor
Retry-After. Current per-minute limits are 30 authorize, 60 token, and 10 dynamic-registration requests per source or authenticated actor.
Troubleshooting
If the client cannot connect:
- Verify
/admin/settings/mcpshows the MCP server as enabled. - Verify the tenant migrations have run.
- Verify the user has
mcp.use. - Verify the user has the per-tool permissions expected in
tools/list. - For dynamic client registration errors, check that
/oauth/registerreturns HTTP 201 with ak0s_oauth_client_...client id. - For bearer clients, confirm the header is exactly
Authorization: Bearer k0s_pat_.... - For OAuth clients that fail after one hour, verify the tenant has the
oauth_refresh_tokenstable and that/oauth/tokenmetadata advertisesrefresh_token. - OAuth clients registered before k0smos 0.17.11 keep their original authorization-code-only registration. Clear that client's saved OAuth credentials/client registration and authorize again to opt into refresh.
- After
invalid_granton refresh, clear the client's stored OAuth credentials and authorize again; refresh-token replay intentionally revokes the grant.
If a client authenticates but sees no useful tools, the most common cause is a
missing permission scope: OAuth and scoped PAT authority must include mcp.use
plus the specific tool permissions.