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 throughatamaia_call.
Connection, auth, and Claude Code setup: docs-mcp-integration.md.
Canonical API host: https://api.atamaia.ai.
Design principles
- Flat over nested — No facade dispatch.
memory_search(query)notmemory_execute({cmd: "search"}). Self-documenting, zero indirection. - Consistent naming —
{domain}_{action}. Always snake_case. Verbs from: list, get, create, update, delete, search, archive. - 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). - UUID on everything — Every entity has both
id(long, fast joins) andguid(UUID, external reference). Every HTTP request gets a correlation UUID. - Soft delete everywhere —
delete= setIsDeleted = true. Never hard delete. Prune is a separate privileged operation. (Personal memory is the documented exception — seedocs-memory-surfaces.md.) - Hot by default for the daily path only — New
[McpServerTool]methods compile cold. Adding a name toHotTools.Namesis 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:
- Agent-memory MCP tools — REST exists; no
AgentMemoryTools.cs. - Task list filters / delete / remove-dependency on MCP — REST-only; see
docs-tasks.md. - Memory bulk operations — still API-only if they exist at all (not re-catalogued here).
SearchConfigonmemory_search— MCP still exposeslimitonly.- Live
tools/listdocumentation 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.