-
Notifications
You must be signed in to change notification settings - Fork 2
MCP Tools
Matt Dula edited this page Apr 18, 2026
·
1 revision
Nakatomi exposes 21 tools over streamable HTTP at /mcp. Same auth as
REST: Authorization: Bearer nk_<key> in the MCP client config.
This page catalogs every tool with a worked example. For how the MCP server is wired internally, see Architecture.
| Tool | Purpose |
|---|---|
describe_schema |
Returns the full entity / field / event manifest. Call this first in any new session. |
> describe_schema()
{
"version": "0.1.0",
"entities": [{"entity":"contact","fields":{"id":"uuid","email":"email?",...},"endpoints":{...}},...],
"event_types": ["contact.created", "deal.stage_changed", ...]
}
| Tool | Signature |
|---|---|
search_contacts |
query? email? company_id? tag? limit=25 |
get_contact |
contact_id |
create_contact |
first_name? last_name? email? phone? title? company_id? tags? external_id? data? |
update_contact |
contact_id, updates: dict |
> search_contacts(query="ada")
[{"id":"...","first_name":"Ada","last_name":"Lovelace","email":"ada@example.com",...}]
> create_contact(first_name="Grace", last_name="Hopper", email="grace@example.com")
{"id":"new-uuid","first_name":"Grace",...}
> update_contact(contact_id="...", updates={"title":"Rear Admiral"})
{"id":"...","title":"Rear Admiral",...}
| Tool | Signature |
|---|---|
search_companies |
query? domain? tag? limit=25 |
create_company |
name, domain?, website?, industry?, employee_count?, annual_revenue?, description?, tags?, external_id?, data? |
| Tool | Signature |
|---|---|
list_pipelines |
() — returns every pipeline with its stages |
create_deal |
name, amount?, currency="USD", pipeline_id?, stage_id?, primary_contact_id?, company_id?, expected_close_date?, tags?, data? |
move_deal_stage |
deal_id, stage_slug — auto-sets status on won/lost stages |
> list_pipelines()
[{"id":"...","name":"Sales","slug":"sales","stages":[
{"id":"...","slug":"lead","name":"Lead","position":0,"probability":10.0},
{"id":"...","slug":"won","name":"Won","is_won":true,...}
]}]
> create_deal(name="Acme Big Deal", amount=12345.67, primary_contact_id="...", company_id="...")
{"id":"...","name":"Acme Big Deal","stage_id":"<lead>","status":"open",...}
> move_deal_stage(deal_id="...", stage_slug="won")
{"id":"...","status":"won","closed_at":"2026-..."}
| Tool | Signature |
|---|---|
log_activity |
kind, subject?, body?, entity_type?, entity_id?, occurred_at?, data? |
add_note |
entity_type, entity_id, body, data? |
create_task |
title, description?, due_at?, assignee_user_id?, entity_type?, entity_id?, data? |
list_tasks |
status? assignee_user_id? limit=50 |
> log_activity(kind="call", subject="intro", body="talked for 20 min about roadmap",
entity_type="contact", entity_id="...")
{"id":"...","kind":"call","occurred_at":"..."}
> add_note(entity_type="deal", entity_id="...", body="Willing to pay $15k if ...")
{"id":"...","entity_type":"deal","entity_id":"...",...}
> create_task(title="Send proposal", due_at="2026-04-20T17:00:00Z",
entity_type="deal", entity_id="...")
{"id":"...","title":"Send proposal","status":"open",...}
> list_tasks(status="open")
[...]
| Tool | Signature |
|---|---|
relate |
source_type, source_id, target_type, target_id, relation_type, strength=1.0, data? |
timeline |
entity_type, entity_id, limit=50 |
> relate(source_type="contact", source_id="ada-uuid",
target_type="company", target_id="acme-uuid",
relation_type="works_at")
{"id":"...","relation_type":"works_at","strength":1.0,...}
> timeline(entity_type="deal", entity_id="...")
[{"event_type":"deal.created","occurred_at":"..."},
{"event_type":"deal.stage_changed","payload":{"from_stage_id":"...","to_stage_id":"..."}},
{"event_type":"deal.won","payload":{"amount":12345.67}}]
| Tool | Signature |
|---|---|
memory_list_connectors |
() |
memory_recall |
query, entity_type?, entity_id?, limit=10, connectors? |
memory_link |
connector, external_id, crm_entity_type, crm_entity_id, note?, data? |
memory_trace |
entity_type, entity_id |
> memory_list_connectors()
["docdeploy", "supermemory"]
> memory_recall(query="what did we promise Acme about delivery?",
entity_type="company", entity_id="acme-uuid")
[{"connector":"docdeploy","external_id":"mem_abc","text":"...","score":0.81,
"crm_links":["company:acme-uuid","deal:big-deal-uuid"]}, ...]
> memory_link(connector="supermemory", external_id="mem_xyz",
crm_entity_type="deal", crm_entity_id="...",
note="call transcript 2026-04-18")
{"id":"...","connector":"supermemory",...}
> memory_trace(entity_type="contact", entity_id="...")
[{"connector":"docdeploy","external_id":"...","note":"..."}]
See Memory-Connectors for setting up providers.
| Tool | Signature |
|---|---|
ingest |
source, format, payload, mapping?, dry_run=False |
format ∈ csv | json | vcard | text. Payload shape depends on format —
see Ingest.
> ingest(source="apollo", format="json",
payload=[{"external_id":"apollo-1", "first_name":"A", "email":"a@ex.com"}])
{"run_id":"...","created":1,"updated":0,"errors":0,"created_ids":["..."],
"diagnostics":[]}
> ingest(source="paste", format="csv",
payload="name,domain\nAcme,acme.example\n",
mapping={"_entity":"company"})
{...}
> ingest(source="test", format="json",
payload=[{"external_id":"a1","email":"a@ex.com"}],
dry_run=True)
{"run_id":"...","created":1,"diagnostics":[{"level":"info","message":"would create contact"}]}
-
Call
describe_schemaonce per session before any writes. -
Always set
external_idwhen syncing from an upstream system. -
Read
timelinebefore mutating to avoid redundant updates. -
Use
relateliberally — the graph makes downstream reasoning cheap. - Link memories after writing long content so recall finds them.
- Prefer MCP tools to raw REST when your harness supports MCP — the response shapes are already trimmed for agent consumption.
Full anti-pattern list: AgentLab.md#anti-patterns.
Repository · Issues · MIT licensed · maintained by Matt Dula