Tool Surface Design

Flat tools, not facades. Each tool = one verb. {domain}_{action}. LLMs see the tool name and parameters — that is the entire advertised interface. Everything else is compiled, cold, and reached through atamaia_call.

Connection, auth, and Claude Code setup: docs-mcp-integration.md.

Canonical API host: https://api.atamaia.ai.


Design principles

  1. Flat over nested — No facade dispatch. memory_search(query) not memory_execute({cmd: "search"}). Self-documenting, zero indirection.
  2. Consistent naming{domain}_{action}. Always snake_case. Verbs from: list, get, create, update, delete, search, archive.
  3. Every response has a shape — REST returns ApiEnvelope<T> with { ok, requestId, data, error, errorCode, count, hint }. MCP returns the raw data (envelope is HTTP-only).
  4. UUID on everything — Every entity has both id (long, fast joins) and guid (UUID, external reference). Every HTTP request gets a correlation UUID.
  5. Soft delete everywheredelete = set IsDeleted = true. Never hard delete. Prune is a separate privileged operation. (Personal memory is the documented exception — see docs-memory-surfaces.md.)
  6. Hot by default for the daily path only — New [McpServerTool] methods compile cold. Adding a name to HotTools.Names is how a verb becomes first-class. A typo in that list fails startup.

Hot / cold

McpRegistration advertises only HotTools.Contains. Cold tools stay in the assembly. Reach them with:

help_search(query: "standing") → path + method
help_route(path: "/api/...", method: "POST") → body shape
atamaia_call(method, path, bodyJson)

atamaia_call loopbacks to /api/* with the caller’s Authorization header. Not an auth bypass. Paths outside /api/ are rejected.

Why: a 237-tool list is a facade by another name — the model has to discover the vocabulary before it can act. Fifty named tools plus discovery is the same idea as D12: the contract is the REST surface; MCP is a thin, curated window onto it.


Hot set (52)

From HotTools.cs. Grouped for reading; the allowlist is a flat name set.

Group Tools
Dispatch + hydration atamaia_call, hydrate, whoami
Web search web_search
Memory (work store) memory_search, memory_get, memory_recent, memory_pinned, memory_create, memory_update, memory_link
Standing rules rule_check, rule_list, rule_get, rule_propose, rule_add_evidence, rule_withdraw
Identity (reads) identity_get, identity_get_by_name, identity_list
Facts fact_search, fact_get, fact_get_by_key, fact_list, fact_upsert
Tasks task_list, task_get, task_create, task_update, task_update_status, task_add_note, task_get_notes, task_search
Projects project_list, project_get, project_get_by_key
Docs doc_list, doc_get, doc_get_by_path, doc_create, doc_update
Messages message_send, message_inbox, message_unread_count, message_thread, message_mark_read
Chat chat_send, chat_session_list
Session handoff session_save_handoff, session_get_latest
Graph graph_search, graph_neighbors

whoami is deliberately hot — its entire purpose is to stop models guessing identity.

Plus advertised help (not in HotTools, from [ExposeAsMcp]): help_list, help_route, help_routes, help_search, help_descriptors, help_enums, help_enum.


Product families

What a session actually needs. Cold siblings are listed so the “not in product surface” line is honest.

Hydration

Tool Hot? Notes
hydrate yes Presets lean (default), interactive, all, agent-minimal (agent is an alias). See docs-mcp-integration.md

Memory (work store)

Tool Hot? Notes
memory_create yes Field is type, not memoryType. Also provenance.
memory_get yes Increments access count
memory_update yes Partial; does not edit tags
memory_search yes MCP limit (default 20). REST q/topK
memory_recent yes
memory_pinned yes
memory_link yes Hebbian; LinkType enum
memory_archive cold Soft archive
memory_add_tags cold Additive
memory_strengthen_link cold Co-activation increment

Four surfaces, not one table with flavours: docs-memory-surfaces.md. Personal tools are a separate family (all cold). There are no AgentMemory MCP tools.

Standing rules

All six are hot. They are not memories. See docs-standing-rules.md.

rule_propose writes Proposed — it does not govern until a human confirms.

Facts

Tool Hot? Notes
fact_upsert / fact_get / fact_get_by_key / fact_list / fact_search yes
fact_delete cold Soft delete
fact_history cold Shipped. The 2026-03-14 page said “not in product surface yet.”
fact_as_of cold Shipped. Same.

REST paths exist too (/api/projects/{id}/facts/by-key/{key}/history, .../as-of).

Identity

Hot: list / get / get-by-name only.

Compiled and cold (not missing): create, update, presence, personality get/set, messaging-policy get/set, tool-profile get/set, effective-tools, API keys, hints, memory-config, hydration-config, soul import/export/preview. The 2026-03-14 “What’s Missing” list item 1–2 is stale.

Session

Hot: session_save_handoff, session_get_latest. Cold: session_get, session_list. Handoff stateVisible is owner-gated — docs-memory-surfaces.md.

emotionalValence is a float (−1..1), not a string like "focused".

Messaging

Hot: send, inbox, unread-count, thread, mark-read. Cold: message_get, message_sent.

Projects and tasks

Hot tasks omit task_search and task_add_dependency (both compiled). Create requires kind + subsystem at the service. Do not document title/priority alone. Full board: docs-tasks.md.

Docs

Hot: list, get, get-by-path, create, update. Cold: delete, publish, unpublish, versions, export.

Graph

Hot: graph_search, graph_neighbors. Cold: graph_drift, graph_node. See docs-code-graph.md.

Web search

Hot: web_search. Provider field tells you if SearXNG degraded. See docs-web-search.md.

Chat

Hot: chat_send, chat_session_list. Other session CRUD is cold.

Audit

system_log_list, system_log_get — both cold. REST also has /api/system-logs/summary and /api/audit-events (no dedicated MCP verbs; use atamaia_call).

Export

doc_export_identity, doc_export_tenant, doc_export_manifest — cold.

Personal memory

Nine tools in PersonalMemoryTools.cs, all cold, never registered as agent tools (borrowed identity id). See docs-memory-surfaces.md.


Gone

Old tool family Probe
experience_create_snapshot, experience_get_snapshot, experience_list_snapshots, experience_create_shape, experience_list_shapes No ExperienceTools.cs. REST snapshots/shapes HTTP 404.
cognitive_chat, cognitive_get_state, cognitive_set_state, cognitive_consolidate, cognitive_validate No CognitiveTools.cs. REST /api/cognitive/* HTTP 404.

The forge CLI still has exp snapshot|snapshots|shape|shapes subcommands that call those REST paths. They will 404. See docs-cli-integration.md.


Compiled inventory (238)

[McpServerTool] attributes in src/Atamaia.Adapters.Mcp/Tools/ on 2026-08-14:

File Count
AgentTools 29
IdentityTools 29
MirrorTools 24
OrgUnitTools 19
AIRouterTools 16
ConnectorTools 13
MemoryTools 10
DocTools 10
PersonalMemoryTools 9
ChannelTools 8
ChatSessionTools 8
FactTools 8
TaskTools 9
MessageTools 7
RoleTools 7
StandingRuleTools 6
GraphTools 4
ProjectTools 4
BillingTools 4
ExportTools 3
SessionTools 4
SystemLogTools 2
DispatchTools 1
HydrationTools 1
WebSearchTools 1
EventTools 1
Total 238

Internal-only domains (ai_*, agent_*, mirror_*, connector_*, channel_*, org_unit_*, role_*, billing_*, event_publish) remain compiled and cold unless listed in the hot set. That classification is still useful. It is no longer “not in the assembly.”


REST envelope

{
  "ok": true,
  "requestId": "550e8400-e29b-41d4-a716-446655440000",
  "data": { },
  "count": 42,
  "error": null,
  "errorCode": null,
  "hint": null
}

Error example:

{
  "ok": false,
  "requestId": "550e8400-e29b-41d4-a716-446655440001",
  "data": null,
  "error": "Identity not found: 99",
  "errorCode": "NOT_FOUND",
  "hint": "Check identity ID or use identity_list to find valid IDs"
}

Headers

Header Direction Description
Authorization Request Bearer {jwt} or Bearer atamaia_...
X-Correlation-Id Request/Response UUID correlating the request. Auto-generated if not sent.

There is no Authorization: ApiKey scheme. There is no X-Identity-Id response header in src/. Prefix is atamaia_, minted as atamaia_{Guid}{Guid}.


MCP vs REST path shape

Tool names match operations, not a global /api/{domain} prefix. The 2026-03-14 line memory_search = GET /api/memories/search is the wrong shape — that path 404s in help/route because the real route is identity-scoped.

MCP REST
memory_search GET /api/identities/{identityId}/memories/search
memory_create POST /api/identities/{identityId}/memories
hydrate GET /api/hydrate
task_create POST /api/projects/{projectId}/tasks
rule_check GET /api/standing-rules/check
web_search GET /api/system/web-search
graph_search GET /api/graph/search

Full path catalog: docs-api-reference.md.


What’s missing (honest)

Shipped since the last published page (do not list as next):

  • Personality and messaging-policy MCP tools
  • Fact history / as-of (REST + cold MCP)
  • Standing rules, graph, web search, personal memory, export, help, atamaia_call
  • Integration skills (forge skills generate) — docs-cli-integration.md
  • Official SDK folders under sdks/docs-sdk-api-guide.md (defaults are stale)

Still actually thin or absent:

  1. Agent-memory MCP tools — REST exists; no AgentMemoryTools.cs.
  2. Task list filters / delete / remove-dependency on MCP — REST-only; see docs-tasks.md.
  3. Memory bulk operations — still API-only if they exist at all (not re-catalogued here).
  4. SearchConfig on memory_search — MCP still exposes limit only.
  5. Live tools/list documentation generated from prod — this page is compiled from the repo allowlist.

Why flat

Facade Pattern Flat (Atamaia)
160+ commands in 18 tools 50 hot tools, each standalone; 237 compiled
LLM needs a command vocabulary LLM sees the tool name
DomainCommand envelope Direct parameter binding
Help system to discover commands help_* + tool schema
Error: unknown command: serach Error: tool not found (client) or help_search
Good for: one MCP connection, many ops Good for: API-first, MCP second

Flat tools are the right choice for an API-first architecture. Hot/cold is how the list stays a list.