MCP server¶
Autopoetic exposes a Model Context Protocol server giving LLM clients and agents a working surface over a project's conversations, messages, and knowledge repository.
The MCP server is the management surface's LLM-native form: it mirrors the platform API — the same backing operations, the same error envelope, the same pagination tokens — and, like the platform API, it never generates agent responses (that is the Responses API's job; see the API overview).
Single-sourced reference
The full guide below — including the per-tool reference rendered from
the live server's tools/list metadata — is maintained in one place in
the repository and included here, so it always matches the deployed
tools.
Autopoetic MCP Server — Public Guide¶
Autopoetic exposes a Model Context Protocol server giving LLM clients and agents a working surface over a project's conversations, messages, and knowledge repository. The MCP surface mirrors the REST v1 API: the same backing operations, the same error envelope, the same pagination tokens.
The full per-tool reference is embedded in this document — rendered from
the live server's tools/list metadata, so it always matches the deployed
tools.
Endpoint & transport¶
- URL:
https://app.autopoetic.ai/mcp(or your deployment's/mcppath) - Transport: MCP streamable HTTP (JSON-RPC 2.0 over HTTP POST)
- Stateless: no
Mcp-Session-Idbookkeeping — every request is handled by a fresh transport and authenticated on its own. You can use any MCP client without session management. - The handshake methods (
initialize,tools/list) are reachable without a token and reveal only the public tool metadata. Everytools/callrequires a validAuthorization: Bearer <token>header.
Authentication¶
Send a Bearer access token with every request:
Tokens are verified via Keycloak, the same way the REST API verifies them.
The token's project roles (/customer_{customer_uuid}/project_{project_uuid}/{role}
groups) determine what the tools will allow:
| Tier | Grants |
|---|---|
| viewer | all read tools (conversations, messages, knowledge) |
| editor | everything above plus writes: append messages, create/update/delete knowledge entries, record events, create relationships |
| admin | (same as editor for MCP — the MCP surface has no admin-only tools) |
Project agents typically authenticate with a project API key (a Keycloak client credential, created by a project admin via the REST API or the UI).
Tool reference¶
Autopoetic's MCP server exposes 11 project-scoped tools — every call names the project_uuid it acts on. This reference is rendered from the live server's tools/list metadata, so it always matches the deployed tools.
| Tool | Access tier |
|---|---|
list_conversations |
viewer+ |
read_conversation |
viewer+ |
read_recent_messages |
viewer+ |
append_message |
editor+ |
search_knowledge |
viewer+ |
read_knowledge_entry |
viewer+ |
upsert_knowledge_entry |
editor+ |
delete_knowledge_entry |
editor+ |
record_event |
editor+ |
create_knowledge_relationship |
editor+ |
flush_knowledge |
editor+ |
list_conversations¶
List a project's conversations, newest activity first. Pass the returned next_cursor to the next call to page through older conversations; null means no more pages. Requires viewer access or higher.
| Parameter | Type | Required | Default | Constraints |
|---|---|---|---|---|
project_uuid — The project to list conversations in. |
string | yes | ||
cursor — Opaque cursor from a previous call's next_cursor. |
string | null | no | null |
limit — Page size (max 100). |
integer | no | 25 |
1–100 |
read_conversation¶
Read a conversation: its index (title, settings) and its recent messages. Requires viewer access or higher.
| Parameter | Type | Required | Default | Constraints |
|---|---|---|---|---|
project_uuid — The project the conversation belongs to. |
string | yes | ||
conversation_uuid — The conversation to read. |
string | yes |
read_recent_messages¶
Read a page of a conversation's messages, newest first. Pass the returned next_cursor to get the next-older page; null means the beginning of the conversation. Requires viewer access or higher.
| Parameter | Type | Required | Default | Constraints |
|---|---|---|---|---|
project_uuid — The project the conversation belongs to. |
string | yes | ||
conversation_uuid — The conversation to read messages from. |
string | yes | ||
cursor — Opaque cursor from a previous call's next_cursor. |
string | null | no | null |
limit — Page size (max 100). |
integer | no | 25 |
1–100 |
append_message¶
Append a message to a conversation (user or agent role). The append is the live write path: encryption is handled internally. No inference runs — the text is written exactly as supplied, so there is no platform GPU work to meter: this tool intentionally sends zero prompt/completion/GPU usage, which under-counts and never over-counts. For platform generation, drive a turn on the Responses API instead — usage there is measured server-side and the agent message is persisted by the platform. Requires editor access or higher.
| Parameter | Type | Required | Default | Constraints |
|---|---|---|---|---|
project_uuid — The project the conversation belongs to. |
string | yes | ||
conversation_uuid — The conversation to append to. |
string | yes | ||
role — Message role: user or agent. |
string | no | "user" |
pattern ^(user|agent)$ |
content — Message body text. |
string | no | "" |
search_knowledge¶
Search the project's knowledge index by name. Returns matching entries with their types and hints. Requires viewer access or higher.
| Parameter | Type | Required | Default | Constraints |
|---|---|---|---|---|
project_uuid — The project whose knowledge to search. |
string | yes | ||
query — Name (or name prefix) to search for. |
string | yes | ||
limit — Maximum results (max 50). |
integer | no | 10 |
1–50 |
read_knowledge_entry¶
Read a single knowledge entry by UUID (name, type, hint, characteristics, relationships). Requires viewer access or higher.
| Parameter | Type | Required | Default | Constraints |
|---|---|---|---|---|
project_uuid — The project the entry belongs to. |
string | yes | ||
entry_uuid — The entry's UUID. |
string | yes |
upsert_knowledge_entry¶
Create or update a knowledge entry by name+type (upsert). Pass expected_entry_generation from your last read or write to detect concurrent edits; omit it to skip the check. Writes stage into the shared overlay and are not persisted until a flush. Requires editor access or higher.
| Parameter | Type | Required | Default | Constraints |
|---|---|---|---|---|
project_uuid — The project the entry belongs to. |
string | yes | ||
name — Entry name. |
string | yes | ||
type — Entry type: entity, place, or thing. |
string | yes | pattern ^(entity|place|thing)$ |
|
hint — Short summary (max 256 chars). |
string | null | no | null |
characteristics — Simple singular adjectives. |
list[string] | null | no | null |
date_of_origin — Free-form date string. |
string | null | no | null |
expected_entry_generation — Per-entry generation from your last read/write; omit to skip the CAS check. |
integer | null | no | null |
delete_knowledge_entry¶
Delete a knowledge entry by UUID. Pass expected_entry_generation from your last read or write to detect concurrent edits. Requires editor access or higher.
| Parameter | Type | Required | Default | Constraints |
|---|---|---|---|---|
project_uuid — The project the entry belongs to. |
string | yes | ||
entry_uuid — The entry's UUID. |
string | yes | ||
expected_entry_generation — Per-entry generation from your last read/write; omit to skip the CAS check. |
integer | null | no | null |
record_event¶
Record an immutable, hash-chained event in the project's knowledge repository (e.g. a life event, meeting, or change). Link related entries via related_entries (by UUID). Writes stage into the shared overlay and are not persisted until a flush. Requires editor access or higher.
| Parameter | Type | Required | Default | Constraints |
|---|---|---|---|---|
project_uuid — The project to record the event in. |
string | yes | ||
kind — Event kind (open vocabulary, e.g. 'meeting', 'employment'). |
string | yes | ||
occurred_at — When the event occurred (free-form date string, e.g. '2026-08-15'). |
string | yes | ||
status — Optional status qualifier (e.g. 'laid off'). |
string | no | "" |
≤ 128 chars |
hint — Short summary (max 1024 chars). |
string | no | "" |
≤ 1024 chars |
payload — Structured event details. |
object | null | no | null |
related_entries — Related entries: [{uuid, hint?}]. |
list[object] | null | no | null |
create_knowledge_relationship¶
Create (or update) a directed relationship from one entry to another, with a hint describing it (e.g. 'mentor of'). Requires editor access or higher.
| Parameter | Type | Required | Default | Constraints |
|---|---|---|---|---|
project_uuid — The project the entries belong to. |
string | yes | ||
entry_uuid — Source entry UUID. |
string | yes | ||
target_uuid — Target entry UUID. |
string | yes | ||
hint — Relationship description (max 256 chars). |
string | yes | ≤ 256 chars | |
expected_entry_generation — Source entry's generation from your last read/write; omit to skip the CAS check. |
integer | null | no | null |
flush_knowledge¶
Persist all currently-staged knowledge mutations (from this client and any other client for the same project) to durable storage. Until a flush, staged writes are in-memory only and are lost on cache eviction or restart. The agent pattern is 'agentic loop → flush at end'. Requires editor access or higher.
| Parameter | Type | Required | Default | Constraints |
|---|---|---|---|---|
project_uuid — The project whose staged knowledge writes to persist. |
string | yes |
Pagination¶
List-style tools (list_conversations, read_recent_messages) paginate with
opaque cursor tokens. The response carries next_cursor; pass it back on
the next call to get the next page. next_cursor: null means you have reached
the end. The tokens are encrypted and scoped to the resource they were minted
for — treat them as opaque strings, and never construct or modify them
yourself. (This is deliberately friendlier to LLM callers than offset paging:
there is nothing to interpret or miscount.)
Errors¶
Tool failures return tool results with isError: true whose text is a JSON
error envelope — the same shape the REST v1 API returns, so one parser
covers both surfaces:
{
"error": {
"type": "permission_error",
"code": "",
"message": "Token does not have access to project <uuid>."
}
}
type |
Meaning |
|---|---|
authentication_error |
missing or invalid Bearer token |
permission_error |
token valid, but no access to that project / tier |
not_found_error |
conversation, entry, or resource does not exist (or is deleted) |
invalid_request_error |
malformed arguments, invalid UUIDs, invalid cursor (code: "invalid_cursor"), unsupported entry type |
conflict (invalid_request_error) |
generation mismatch (concurrent write) or duplicate resource; details carries the structured body |
autopoetic_error |
internal error or service temporarily unavailable (code: "not_primary") |
Optional param and details fields appear when relevant (e.g. per-field
validation errors, or the conflicting generations on a CAS failure).
Concurrent-write protection (CAS)¶
Knowledge tools accept an optional expected_entry_generation — the
generation you observed on your last read or write of that entry. Pass it to
detect concurrent edits: if someone else wrote first you get a conflict
error; re-read the entry and retry. Omit it to skip the check (last write
wins). Message appends and event recordings have no CAS check — they are
app-only structures.
Write visibility (shared overlay)¶
Knowledge writes (upsert_knowledge_entry, delete_knowledge_entry,
record_event, create_knowledge_relationship) stage into the project's
shared overlay. They are immediately visible to subsequent reads but are not
durably persisted until a flush is performed. Flush with the
flush_knowledge tool, the knowledge REST API
(POST /api/v1/projects/{uuid}/knowledge/flush), or the application UI. An
MCP-only client should call flush_knowledge at the end of each agentic
loop; unflushed staged writes are lost on service restart.
Usage metering¶
The MCP surface runs no inference. Tools read and write data, and any text
append_message writes is exactly what the caller supplied — typically
authored by the calling agent's own model, not by a platform model. So MCP
appends meter zero usage: the tool deliberately exposes no usage
parameters and sends zeros, which under-counts and never over-counts — there
is no platform GPU work behind such a write, so zero is the truthful value.
Platform generation happens on the OpenAI-compatible Responses API turn path,
where usage is measured server-side and the agent message is persisted with
real numbers — clients driving turns that way do not need to append the
reply themselves.
What is deliberately not exposed¶
The MCP surface is a curated working surface. There are no tools for projects (create/delete/fork), members, invitations, API keys, or files: administration and access control are human/operator territory, and an agent managing its own credentials or membership would be a privilege-escalation footgun. Use the REST v1 API for those operations.
Client configuration¶
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"autopoetic": {
"type": "http",
"url": "https://app.autopoetic.ai/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}
opencode (opencode.json / opencode.jsonc):
{
"mcp": {
"autopoetic": {
"type": "remote",
"url": "https://app.autopoetic.ai/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}
To explore interactively, run the
MCP Inspector against the
endpoint with your Bearer header — initialize, browse tools/list, and make
test calls.
Versioning¶
The server advertises version in its initialize result. Changes to the
tool surface are additive: new tools and new optional parameters do not bump
the major version; removed tools or changed argument semantics will come with
a major version bump and advance notice.