Vai al contenuto
Vai al contenuto
Navigazione documentazione

Questa pagina non è ancora disponibile nella lingua scelta. È mostrata la versione EN.

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;
  • conduct private Brainstorming discussions and discover, read or revise their permanent result plans, including after a discussion has ended.

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.
  • POST only.
  • Supported methods: initialize, ping, tools/list, tools/call, and notifications/*.
  • No stdio, SSE, query-string credentials, URL tokens, or session IDs.

Prerequisites

Before a client connects:

  1. The tenant must be migrated.
  2. The MCP server must be enabled from /admin/settings/mcp.
  3. The connecting user must be active.
  4. The connecting user must have mcp.use.
  5. The connecting user must also have the permissions required by each tool they should see or call, such as ticket.view, project.edit, or finance.create, todo.view, or todo.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 as ticket, project, or finance.
  • _meta.k0smos/resultShape: result envelope hint such as ticket_collection, project_detail, or finance_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.*
Brainstorming private discussion/workflow control, permanent plan discovery, full reading and revision writing brainstorming.view, brainstorming.chat; execution also needs agent.run

The exact tool list depends on the tenant's active modules and the authenticated user's permissions.

Brainstorming From Hermes Or Another MCP Client

The compact participant/worker/client setup guide is in modules/Brainstorming/src/README.Brainstorming.md. Its connection check retains runtime UI/Hermes qualification as operator guidance.

Enable Brainstorming and MCP for the tenant and grant the caller mcp.use. Reading requires brainstorming.view; writing also requires brainstorming.chat. Invoking an agent additionally requires agent.run, an active default queue worker and configured, authenticated connectors. All access is restricted to the authenticated owner's conversations and plans.

Hermes uses these tools through the same authenticated /api/mcp endpoint as other clients. It does not attach to a native CLI session. Requests return durable IDs promptly; poll for new messages and progress. The UI observes the same SQL state and can intervene while Hermes is connected or after it disconnects.

Tool Purpose
brainstorming_get With no ID, discover conversations and connector options. With conversation_id and cursor, read new messages. With execution_id, inspect workflow progress and its pinned result-plan reference.
brainstorming_create Create an owned discussion with one to eight configured connector IDs.
brainstorming_submit Send to selected recipients; during a workflow, save a pending intervention and pause advancement.
brainstorming_plan_save Save a reusable discussion sequence; this does not start it or create a result document.
brainstorming_plan_start Start a saved sequence or a hybrid/parallel-critique preset.
brainstorming_control Pause, resume, advance, stop or explicitly continue with partial results using execution_id and expected_revision. A single run_id supports stop/retry.
brainstorming_artifact_list Search permanent plans without a conversation ID; page using limit, offset and returned next_offset.
brainstorming_artifact_get Read full Markdown and an exact or latest revision, provenance, review and human approval. before_revision instead pages revision history.
brainstorming_artifact_save Write a plan or a new immutable revision as the authenticated external actor; never approve it or execute models.

Example: Independent Answers, Individual Comparison, Permanent Plan

The following are tool names and their arguments objects, passed through the client's normal tools/call operation. IDs are synthetic: use connector IDs returned by discovery and opaque conversation/execution/artifact IDs returned by the service.

  1. Call brainstorming_get with {} to discover available connector IDs. Then call brainstorming_create:

    {"title":"Release proposal","connector_ids":["connector_a","connector_b"]}
    
  2. Use the returned conversation.id in brainstorming_plan_start:

    {
      "conversation_id":"11111111111111111111111111111111",
      "body":"Write a release plan with alternatives, risks and unresolved disagreements.",
      "participants":["connector_a","connector_b"],
      "preset":"hybrid",
      "mode":"moderated",
      "synthesizer":"connector_a",
      "review":true,
      "idempotency_key":"release-discussion-001",
      "sources":[{"id":"memory-note-17","label":"Selected Memory note","revision":"3","text":"The release must preserve existing integrations."}]
    }
    

    Both agents receive the same frozen analysis context without each other's answer. Hybrid comparison then addresses them individually in participant order. parallel_critique instead gives reviewers the same completed analyses. Selecting recipients controls who answers; it does not create a private message invisible to later shared phases.

  3. Poll brainstorming_get using the returned execution id:

    {"execution_id":"22222222222222222222222222222222"}
    

    To read the chat, call brainstorming_get with conversation_id and cursor: 0, then reuse its returned cursor while has_more is true and for subsequent polls. At awaiting_user, use the current execution revision and its allowed actions with brainstorming_control:

    {"execution_id":"22222222222222222222222222222222","expected_revision":3,"action":"advance"}
    

    The number 3 is illustrative; always use the returned current revision. Failed or truncated replies block successors. Retry the affected run_id, stop, or explicitly choose continue_partial when offered. automatic mode advances the finite sequence without manual phase approval; it has the same failure barriers and limits of twelve steps, thirty-two attempts and one hour.

  4. To intervene, call brainstorming_submit:

    {"conversation_id":"11111111111111111111111111111111","body":"Include a rollback procedure.","recipients":["connector_a"],"idempotency_key":"release-intervention-001"}
    

    This pauses advancement and saves the instruction. Existing calls finish with their original prompts. Read the current execution revision, then resume to apply the pending instruction. stop also cancels active/queued work.

  5. Completed execution returns result_plan_id and result_plan_revision. Read that exact document with brainstorming_artifact_get:

    {"artifact_id":"33333333333333333333333333333333","revision":1}
    

Later, even in a new client session or after transcript deletion, discover it with brainstorming_artifact_list using {"kind":"plan","query":"release"}. Read/list operations invoke no model and need no worker. The full Markdown, trusted provenance, immutable revision history and approval status remain in tenant SQL with no completion expiry. Deleting a transcript never deletes its plans; permanent plan deletion is a separate confirmed UI action.

Hermes can also write a plan directly with brainstorming_artifact_save:

{"title":"Release plan","kind":"plan","markdown":"# Release plan\n\n1. Verify compatibility.\n2. Deploy and monitor.","idempotency_key":"external-plan-001"}

To revise it, set artifact_id to the returned id and include the current expected_revision, full replacement Markdown and a new idempotency key. Reusing a key with changed content or editing a stale version returns a conflict. Documents are limited to 240,000 UTF-8 bytes and returned whole. Revision history is paginated separately; before_revision cannot be combined with an exact revision. Document-only writes need view/chat authority, but no agent.run. Approval is a separate human UI action on an exact version; a new revision starts as a proposal.

Execution requires a bound personal token or OAuth access token, whose original scope, expiry and revocation remain effective after the initial HTTP request. Each later delegated intervention/advance can further narrow future work. Refreshing OAuth does not extend the authority of a workflow started with an expired access token. Tokens used only for document access need no execution scope. Private MCP bodies are excluded from generic diagnostics.

Permanent SQL storage requires no external Memory server. Selected Memory excerpts can be supplied explicitly in sources, with IDs and revisions, and are frozen once for all participants. Hermes can separately export a saved version using its own configured Memory tools; direct server synchronization is not implemented. Calendar scheduling and additional provider adapters are also separate from these finite discussion sequences.

Custom synthesize and review steps require context_policy: previous_steps (or its omitted default); analyses is rejected for those phases. The review must receive the synthesis before its output can be attached to that plan revision. Reusable definitions are revalidated at launch, and the MCP step schema declares the same constraint. Completion also verifies that the frozen review input contains the synthesis run identity. Legacy review input lacking it returns an invalid_output execution state without attaching a review or losing the plan; start a new execution to obtain a valid review.

Authenticated HTTP acceptance on 2026-10-03 uses disposable scoped PATs and SQL/workspaces. It covers tool discovery, reusable workflow save, idempotent automatic launch, a Codex/Claude reviewed synthesis, browser reload, and read-only plan discovery/full retrieval after transcript deletion with no worker. The native check passes on Codex 0.160.0 and Claude Code 2.1.287. This protocol client is separate from the owner's Hermes session; remote client acceptance remains open.

Safety Model

k0smos applies multiple gates before an AI client can call a tool:

  1. The tenant MCP kill switch must be enabled.
  2. The request must authenticate as an active user.
  3. The user or token must have mcp.use.
  4. The contributing module must be active for the tenant.
  5. The user or token must have the tool's required permission.
  6. 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/mcp shows 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/register returns HTTP 201 with a k0s_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_tokens table and that /oauth/token metadata advertises refresh_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_grant on 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.