From 7616c85b9bde11422069712cc94fc6ff81191d22 Mon Sep 17 00:00:00 2001
From: Dhravya <63950637+Dhravya@users.noreply.github.com>
Date: Sat, 12 Sep 2026 23:35:40 +0000
Subject: [PATCH] feat(mcp): use snake_case for public model tools
Claude and Codex prefix the server name, so camelCase still reads
awkwardly. Public tools are now search_memory, get_profile, add_memory,
list_documents, get_document, list_memories, list_spaces, and who_am_i.
Widget tools stay kebab-case.
---
apps/docs/supermemory-mcp/mcp.mdx | 36 +++++++++----------
apps/mcp/README.md | 16 ++++-----
apps/mcp/e2e/discovery.test.ts | 36 +++++++++----------
apps/mcp/e2e/graph.test.ts | 2 +-
apps/mcp/e2e/helpers.ts | 2 +-
apps/mcp/e2e/list-memories.test.ts | 12 +++----
apps/mcp/e2e/memory.test.ts | 18 +++++-----
apps/mcp/e2e/oauth.test.ts | 2 +-
apps/mcp/e2e/space-scope.test.ts | 16 +++++----
apps/mcp/e2e/widgets.test.ts | 2 +-
apps/mcp/src/server/analytics.test.ts | 4 +--
apps/mcp/src/server/analytics.ts | 16 ++++-----
apps/mcp/src/server/container-tag.ts | 4 +--
apps/mcp/src/server/format.ts | 6 ++--
apps/mcp/src/server/resources/profile.ts | 2 +-
apps/mcp/src/server/server.ts | 2 +-
apps/mcp/src/server/space.test.ts | 2 +-
apps/mcp/src/server/tools/add-memory.ts | 2 +-
apps/mcp/src/server/tools/get-document.ts | 6 ++--
apps/mcp/src/server/tools/get-profile.test.ts | 2 +-
apps/mcp/src/server/tools/get-profile.ts | 4 +--
apps/mcp/src/server/tools/guided-save.ts | 2 +-
.../src/server/tools/list-container-tags.ts | 2 +-
apps/mcp/src/server/tools/list-documents.ts | 4 +--
apps/mcp/src/server/tools/list-memories.ts | 4 +--
apps/mcp/src/server/tools/memory-graph.ts | 2 +-
.../src/server/tools/search-memory.test.ts | 2 +-
apps/mcp/src/server/tools/search-memory.ts | 4 +--
apps/mcp/src/server/tools/select-space.ts | 2 +-
apps/mcp/src/server/tools/who-am-i.ts | 4 +--
30 files changed, 110 insertions(+), 108 deletions(-)
diff --git a/apps/docs/supermemory-mcp/mcp.mdx b/apps/docs/supermemory-mcp/mcp.mdx
index bbdefb01..dd30856d 100644
--- a/apps/docs/supermemory-mcp/mcp.mdx
+++ b/apps/docs/supermemory-mcp/mcp.mdx
@@ -46,37 +46,37 @@ Your assistant chooses these tools automatically. Use this table when you need t
| Tool | Use it for | Inputs | Result |
| --- | --- | --- | --- |
-| `searchMemory` | Semantic recall from one space | `query` (required), `containerTag` | Matching memories |
-| `getProfile` | Stable and recent profile context for one space | `containerTag` | Profile facts |
-| `addMemory` | Save information or forget outdated information | `content` (required), `action` (`save` or `forget`), `containerTag` | Save or forget confirmation |
-| `listDocuments` | Browse stored source documents and their summaries | `page`, `limit`, `containerTag` | Document IDs, titles, types, status, dates, and summaries |
-| `getDocument` | Read the available content of one document | `documentId` (required) | Document metadata, summary, and available content |
-| `listMemories` | Browse recent extracted memory entries and their source document IDs | `page`, `limit`, `containerTag` | Memory IDs, text, versions, and source document IDs |
-| `listSpaces` | List accessible spaces and resolve a space name to its key | None | Formatted list plus structured `spaces` and `count` fields |
-| `whoAmI` | Inspect the authenticated account, permissions, scope, and active space | None | Account and access context |
+| `search_memory` | Semantic recall from one space | `query` (required), `containerTag` | Matching memories |
+| `get_profile` | Stable and recent profile context for one space | `containerTag` | Profile facts |
+| `add_memory` | Save information or forget outdated information | `content` (required), `action` (`save` or `forget`), `containerTag` | Save or forget confirmation |
+| `list_documents` | Browse stored source documents and their summaries | `page`, `limit`, `containerTag` | Document IDs, titles, types, status, dates, and summaries |
+| `get_document` | Read the available content of one document | `documentId` (required) | Document metadata, summary, and available content |
+| `list_memories` | Browse recent extracted memory entries and their source document IDs | `page`, `limit`, `containerTag` | Memory IDs, text, versions, and source document IDs |
+| `list_spaces` | List accessible spaces and resolve a space name to its key | None | Formatted list plus structured `spaces` and `count` fields |
+| `who_am_i` | Inspect the authenticated account, permissions, scope, and active space | None | Account and access context |
### Search
-`searchMemory` accepts a natural-language query and returns semantically relevant memories. It does not include the space profile. Use `getProfile` when the assistant needs stable facts or recent context that search did not return.
+`search_memory` accepts a natural-language query and returns semantically relevant memories. It does not include the space profile. Use `get_profile` when the assistant needs stable facts or recent context that search did not return.
Use the retrieval tools for different questions:
-- Use `searchMemory` to answer a question from remembered context.
-- Use `getProfile` for who-the-user-is, preferences, and recent context.
-- Use `listDocuments` to discover stored sources, then `getDocument` to read one source in full.
-- Use `listMemories` to inspect the extracted memory entries themselves, including their IDs and source document IDs.
+- Use `search_memory` to answer a question from remembered context.
+- Use `get_profile` for who-the-user-is, preferences, and recent context.
+- Use `list_documents` to discover stored sources, then `get_document` to read one source in full.
+- Use `list_memories` to inspect the extracted memory entries themselves, including their IDs and source document IDs.
-`listDocuments` and `listMemories` default to 10 results per page and accept up to 50.
+`list_documents` and `list_memories` default to 10 results per page and accept up to 50.
### Save or forget
-`addMemory` saves the supplied `content` by default. Set `action` to `forget` when a fact is outdated or should be removed. There is no separate forget tool.
+`add_memory` saves the supplied `content` by default. Set `action` to `forget` when a fact is outdated or should be removed. There is no separate forget tool.
-If the content is already final, the assistant should use `addMemory`. If you want to review, edit, or choose a space before saving, it should open the `guided-save` widget instead.
+If the content is already final, the assistant should use `add_memory`. If you want to review, edit, or choose a space before saving, it should open the `guided-save` widget instead.
### Access control
-`whoAmI` returns the current identity, role, access type, granted scope, and active space. `listSpaces` returns only spaces the authenticated account can access, with names, keys, document and memory counts, and recent activity.
+`who_am_i` returns the current identity, role, access type, granted scope, and active space. `list_spaces` returns only spaces the authenticated account can access, with names, keys, document and memory counts, and recent activity.
## Interactive widgets
@@ -140,7 +140,7 @@ Supported types include text, Markdown, PDF, Word, CSV, common images, MP3, WAV,
`memory-graph` renders the selected space as an interactive graph of source documents and extracted memories.
-When no space is named, the server automatically uses the active space or account default. If you name a specific space, the assistant calls `listSpaces` to resolve its name to a space key, then opens that space's graph.
+When no space is named, the server automatically uses the active space or account default. If you name a specific space, the assistant calls `list_spaces` to resolve its name to a space key, then opens that space's graph.
{
it("marks addMemory as mutating", async () => {
const { tools } = await s.client.listTools()
- const memory = tools.find((t) => t.name === "addMemory")
+ const memory = tools.find((t) => t.name === "add_memory")
expect(memory?.annotations).toMatchObject(MEMORY_TOOL_ANNOTATIONS)
})
@@ -95,7 +95,7 @@ describeWithAuth("MCP — discovery & identity", () => {
})
it("whoAmI resolves to the authenticated account", async () => {
- const res = await callTool(s.client, "whoAmI")
+ const res = await callTool(s.client, "who_am_i")
expect(res.isError).toBeFalsy()
const parsed = JSON.parse(textOf(res))
expect(parsed.userId).toBeTruthy()
@@ -103,7 +103,7 @@ describeWithAuth("MCP — discovery & identity", () => {
})
it("listSpaces returns content", async () => {
- const res = await callTool(s.client, "listSpaces")
+ const res = await callTool(s.client, "list_spaces")
expect(res.isError).toBeFalsy()
expect(textOf(res).length).toBeGreaterThan(0)
})
diff --git a/apps/mcp/e2e/graph.test.ts b/apps/mcp/e2e/graph.test.ts
index 5b9d45a5..9e654464 100644
--- a/apps/mcp/e2e/graph.test.ts
+++ b/apps/mcp/e2e/graph.test.ts
@@ -52,7 +52,7 @@ describeWithAuth("MCP — graph, resources & prompts", () => {
expect(res.contents[0].text).toMatch(/# Active Space Profile/)
expect(res.contents[0].text).toMatch(/Space:/)
expect(res.contents[0].text).toMatch(
- /Use `listSpaces` to find the relevant space key/,
+ /Use `list_spaces` to find the relevant space key/,
)
})
diff --git a/apps/mcp/e2e/helpers.ts b/apps/mcp/e2e/helpers.ts
index 48797503..0118106d 100644
--- a/apps/mcp/e2e/helpers.ts
+++ b/apps/mcp/e2e/helpers.ts
@@ -223,7 +223,7 @@ export async function recallUntil(
} = {},
): Promise {
for (let i = 0; i < tries; i++) {
- const res = await callTool(client, "searchMemory", {
+ const res = await callTool(client, "search_memory", {
query,
...(containerTag ? { containerTag } : {}),
})
diff --git a/apps/mcp/e2e/list-memories.test.ts b/apps/mcp/e2e/list-memories.test.ts
index 90187fa1..72c20985 100644
--- a/apps/mcp/e2e/list-memories.test.ts
+++ b/apps/mcp/e2e/list-memories.test.ts
@@ -54,7 +54,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)(
afterAll(async () => {
for (const memory of createdMemories) {
- await callTool(session.client, "addMemory", {
+ await callTool(session.client, "add_memory", {
content: memory.content,
action: "forget",
containerTag: memory.containerTag,
@@ -97,7 +97,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)(
const listedDocument = await waitForToolText(
session,
- "listDocuments",
+ "list_documents",
{ page: 1, limit: 50, containerTag },
`[${savedView.id}]`,
20,
@@ -107,7 +107,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)(
const document = await waitForToolText(
session,
- "getDocument",
+ "get_document",
{ documentId: savedView.id },
`Document ID: ${savedView.id}`,
20,
@@ -115,7 +115,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)(
)
expect(document, "saved document could not be read").not.toBeNull()
- const memoriesResult = await callTool(session.client, "listMemories", {
+ const memoriesResult = await callTool(session.client, "list_memories", {
page: 1,
limit: 10,
containerTag: "sm_project_default",
@@ -132,7 +132,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)(
throw new Error("Listed memory did not include a source document")
}
- const sourceDocument = await callTool(session.client, "getDocument", {
+ const sourceDocument = await callTool(session.client, "get_document", {
documentId: sourceDocumentId,
})
expect(sourceDocument.isError).toBeFalsy()
@@ -182,7 +182,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)(
const document = await waitForToolText(
session,
- "getDocument",
+ "get_document",
{ documentId: uploaded.id },
`Document ID: ${uploaded.id}`,
20,
diff --git a/apps/mcp/e2e/memory.test.ts b/apps/mcp/e2e/memory.test.ts
index 0602ab46..8b098441 100644
--- a/apps/mcp/e2e/memory.test.ts
+++ b/apps/mcp/e2e/memory.test.ts
@@ -18,7 +18,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)("MCP — memory behaviors", () =>
})
afterAll(async () => {
for (const { content, containerTag } of created) {
- await callTool(s.client, "addMemory", {
+ await callTool(s.client, "add_memory", {
content,
action: "forget",
...(containerTag ? { containerTag } : {}),
@@ -32,7 +32,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)("MCP — memory behaviors", () =>
const content = `e2e round-trip. token=${marker}. The test fruit is dragonfruit.`
created.push({ content })
- const save = await callTool(s.client, "addMemory", {
+ const save = await callTool(s.client, "add_memory", {
content,
action: "save",
})
@@ -44,7 +44,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)("MCP — memory behaviors", () =>
}, 120_000)
it("searchMemory does not include profile sections", async () => {
- const res = await callTool(s.client, "searchMemory", {
+ const res = await callTool(s.client, "search_memory", {
query: "dragonfruit",
})
expect(res.isError).toBeFalsy()
@@ -54,7 +54,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)("MCP — memory behaviors", () =>
}, 30_000)
it("getProfile returns profile sections", async () => {
- const res = await callTool(s.client, "getProfile", {})
+ const res = await callTool(s.client, "get_profile", {})
expect(res.isError).toBeFalsy()
const txt = textOf(res)
expect(txt).toMatch(
@@ -64,7 +64,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)("MCP — memory behaviors", () =>
// Hybrid search returns nearest matches even for unrelated queries — assert it responds gracefully, not empty.
it("recall responds gracefully for an unmatched query", async () => {
- const res = await callTool(s.client, "searchMemory", {
+ const res = await callTool(s.client, "search_memory", {
query: `zzz-no-such-memory-${randomUUID()}`,
})
expect(res.isError).toBeFalsy()
@@ -78,11 +78,11 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)("MCP — memory behaviors", () =>
const content = `e2e forget target. token=${marker}. Secret animal is axolotl.`
created.push({ content })
- await callTool(s.client, "addMemory", { content, action: "save" })
+ await callTool(s.client, "add_memory", { content, action: "save" })
const found = await recallUntil(s.client, "secret animal axolotl", marker)
expect(found, "memory should exist before forget").not.toBeNull()
- const forgotten = await callTool(s.client, "addMemory", {
+ const forgotten = await callTool(s.client, "add_memory", {
content,
action: "forget",
})
@@ -98,7 +98,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)("MCP — memory behaviors", () =>
const content = `e2e scoping. token=${marker}. Project color is teal.`
created.push({ content, containerTag: tagA })
- await callTool(s.client, "addMemory", {
+ await callTool(s.client, "add_memory", {
content,
action: "save",
containerTag: tagA,
@@ -119,7 +119,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)("MCP — memory behaviors", () =>
}, 120_000)
it("returns an error result for a missing required argument", async () => {
- const res = await callTool(s.client, "searchMemory", {})
+ const res = await callTool(s.client, "search_memory", {})
expect(res.isError).toBe(true)
expect(textOf(res).length).toBeGreaterThan(0)
})
diff --git a/apps/mcp/e2e/oauth.test.ts b/apps/mcp/e2e/oauth.test.ts
index ba2eaca0..2aa79cbb 100644
--- a/apps/mcp/e2e/oauth.test.ts
+++ b/apps/mcp/e2e/oauth.test.ts
@@ -128,7 +128,7 @@ describe.skipIf(!OAUTH_REFRESH_TOKEN || !OAUTH_CLIENT_ID)(
it("connects to /mcp with the OAuth token and resolves identity", async () => {
s = await connect({ token: accessToken })
- const res = await callTool(s.client, "whoAmI")
+ const res = await callTool(s.client, "who_am_i")
expect(res.isError).toBeFalsy()
expect(JSON.parse(textOf(res)).userId).toBeTruthy()
})
diff --git a/apps/mcp/e2e/space-scope.test.ts b/apps/mcp/e2e/space-scope.test.ts
index 7f914b0a..3b5c013b 100644
--- a/apps/mcp/e2e/space-scope.test.ts
+++ b/apps/mcp/e2e/space-scope.test.ts
@@ -21,15 +21,17 @@ describeWithAuth("MCP - space scoping", () => {
const scopedTools = (await scoped.client.listTools()).tools
const plainTools = (await plain.client.listTools()).tools
- expect(propsOf(plainTools, "addMemory")).toHaveProperty("containerTag")
- expect(propsOf(plainTools, "searchMemory")).toHaveProperty("containerTag")
- expect(propsOf(plainTools, "getProfile")).toHaveProperty("containerTag")
-
- expect(propsOf(scopedTools, "addMemory")).toHaveProperty("containerTag")
- expect(propsOf(scopedTools, "searchMemory")).toHaveProperty(
+ expect(propsOf(plainTools, "add_memory")).toHaveProperty("containerTag")
+ expect(propsOf(plainTools, "search_memory")).toHaveProperty(
"containerTag",
)
- expect(propsOf(scopedTools, "getProfile")).toHaveProperty("containerTag")
+ expect(propsOf(plainTools, "get_profile")).toHaveProperty("containerTag")
+
+ expect(propsOf(scopedTools, "add_memory")).toHaveProperty("containerTag")
+ expect(propsOf(scopedTools, "search_memory")).toHaveProperty(
+ "containerTag",
+ )
+ expect(propsOf(scopedTools, "get_profile")).toHaveProperty("containerTag")
} finally {
await scoped.close()
await plain.close()
diff --git a/apps/mcp/e2e/widgets.test.ts b/apps/mcp/e2e/widgets.test.ts
index 438d3033..13824549 100644
--- a/apps/mcp/e2e/widgets.test.ts
+++ b/apps/mcp/e2e/widgets.test.ts
@@ -62,7 +62,7 @@ describe.skipIf(!OAUTH_CREDENTIALS_AVAILABLE)(
const separateSession = await connect()
try {
- const identity = await callTool(separateSession.client, "whoAmI")
+ const identity = await callTool(separateSession.client, "who_am_i")
expect(identity.isError).toBeFalsy()
expect(JSON.parse(textOf(identity))).toMatchObject({
activeSpace: firstTag,
diff --git a/apps/mcp/src/server/analytics.test.ts b/apps/mcp/src/server/analytics.test.ts
index 7b72689d..ac016419 100644
--- a/apps/mcp/src/server/analytics.test.ts
+++ b/apps/mcp/src/server/analytics.test.ts
@@ -44,7 +44,7 @@ describe("MCP tool analytics", () => {
}))
server.registerTool(
- "searchMemory",
+ "search_memory",
{
inputSchema: z.object({ query: z.string(), containerTag: z.string() }),
},
@@ -61,7 +61,7 @@ describe("MCP tool analytics", () => {
expect(record).toHaveBeenCalledOnce()
expect(record).toHaveBeenCalledWith(
expect.objectContaining({
- toolName: "searchMemory",
+ toolName: "search_memory",
surface: "model_tool",
outcome: "success",
spaceExplicit: true,
diff --git a/apps/mcp/src/server/analytics.ts b/apps/mcp/src/server/analytics.ts
index 5c619d7d..e92cd82a 100644
--- a/apps/mcp/src/server/analytics.ts
+++ b/apps/mcp/src/server/analytics.ts
@@ -33,14 +33,14 @@ type ClientInfoResolver = (
) => { name: string; version?: string } | null
const TOOL_SURFACES: Record = {
- searchMemory: "model_tool",
- getProfile: "model_tool",
- listDocuments: "model_tool",
- getDocument: "model_tool",
- listMemories: "model_tool",
- listSpaces: "model_tool",
- whoAmI: "model_tool",
- addMemory: "model_tool",
+ search_memory: "model_tool",
+ get_profile: "model_tool",
+ list_documents: "model_tool",
+ get_document: "model_tool",
+ list_memories: "model_tool",
+ list_spaces: "model_tool",
+ who_am_i: "model_tool",
+ add_memory: "model_tool",
"select-space": "app_launcher",
"memory-graph": "app_launcher",
"guided-save": "app_launcher",
diff --git a/apps/mcp/src/server/container-tag.ts b/apps/mcp/src/server/container-tag.ts
index 5657794a..0924e758 100644
--- a/apps/mcp/src/server/container-tag.ts
+++ b/apps/mcp/src/server/container-tag.ts
@@ -4,10 +4,10 @@ export const containerTagSchema = z
.string()
.min(1, "Container tag is required")
.max(128, "Container tag exceeds maximum length")
- .describe("Space key returned by listSpaces")
+ .describe("Space key returned by list_spaces")
export const optionalContainerTagSchema = containerTagSchema
.optional()
.describe(
- "Space key to use for this call. If the user names a space, call listSpaces to resolve its key and pass it here. If no space is named, omit this field so the server uses the active space or account default.",
+ "Space key to use for this call. If the user names a space, call list_spaces to resolve its key and pass it here. If no space is named, omit this field so the server uses the active space or account default.",
)
diff --git a/apps/mcp/src/server/format.ts b/apps/mcp/src/server/format.ts
index c9bb3f11..b4dd07a5 100644
--- a/apps/mcp/src/server/format.ts
+++ b/apps/mcp/src/server/format.ts
@@ -60,12 +60,12 @@ export function formatDocumentsList(response: DocumentsListResponse): string {
"",
blocks.join("\n\n"),
"",
- "Use getDocument with a document ID to read its content.",
+ "Use get_document with a document ID to read its content.",
]
if (pagination.currentPage < pagination.totalPages) {
parts.push(
- `More available - call listDocuments with page: ${pagination.currentPage + 1}.`,
+ `More available - call list_documents with page: ${pagination.currentPage + 1}.`,
)
}
@@ -121,7 +121,7 @@ export function formatMemoryEntriesList(
if (pagination.currentPage < pagination.totalPages) {
parts.push(
"",
- `More available - call listMemories with page: ${pagination.currentPage + 1}.`,
+ `More available - call list_memories with page: ${pagination.currentPage + 1}.`,
)
}
diff --git a/apps/mcp/src/server/resources/profile.ts b/apps/mcp/src/server/resources/profile.ts
index afcac032..b203ae1b 100644
--- a/apps/mcp/src/server/resources/profile.ts
+++ b/apps/mcp/src/server/resources/profile.ts
@@ -65,7 +65,7 @@ export function registerProfileResource(
parts.push(
"",
- "Other spaces are available. Use `listSpaces` to find the relevant space key, then use that key with space-aware tools when the user asks about another space. Keep space contexts separate unless the user asks to combine them.",
+ "Other spaces are available. Use `list_spaces` to find the relevant space key, then use that key with space-aware tools when the user asks about another space. Keep space contexts separate unless the user asks to combine them.",
)
return {
diff --git a/apps/mcp/src/server/server.ts b/apps/mcp/src/server/server.ts
index 432bddd3..5498569c 100644
--- a/apps/mcp/src/server/server.ts
+++ b/apps/mcp/src/server/server.ts
@@ -26,7 +26,7 @@ import { uploadStateName } from "./space-state"
const DEFAULT_API_URL = "https://api.supermemory.ai"
const UPLOAD_SESSION_TTL_MS = 2 * 60 * 1000
const SERVER_INSTRUCTIONS =
- "Supermemory is the authenticated user's persistent memory and knowledge layer across conversations and spaces. Use these tools whenever the user wants to recall something they may have saved, inspect stored sources or extracted memories, remember or upload new information, check their Supermemory account or access, change their active space, or explore their memory graph, even if they do not mention Supermemory by name. Use the active or account-default space when none is named. Resolve a named space with listSpaces and pass its key to the relevant tool; change the active space only when the user explicitly asks."
+ "Supermemory is the authenticated user's persistent memory and knowledge layer across conversations and spaces. Use these tools whenever the user wants to recall something they may have saved, inspect stored sources or extracted memories, remember or upload new information, check their Supermemory account or access, change their active space, or explore their memory graph, even if they do not mention Supermemory by name. Use the active or account-default space when none is named. Resolve a named space with list_spaces and pass its key to the relevant tool; change the active space only when the user explicitly asks."
type ClientInfo = { name: string; version?: string }
diff --git a/apps/mcp/src/server/space.test.ts b/apps/mcp/src/server/space.test.ts
index e9034b16..0af5dfde 100644
--- a/apps/mcp/src/server/space.test.ts
+++ b/apps/mcp/src/server/space.test.ts
@@ -39,7 +39,7 @@ describe("space application state", () => {
expect(optionalContainerTagSchema.description).toContain(
"If the user names a space",
)
- expect(optionalContainerTagSchema.description).toContain("listSpaces")
+ expect(optionalContainerTagSchema.description).toContain("list_spaces")
expect(optionalContainerTagSchema.description).toContain("active space")
})
})
diff --git a/apps/mcp/src/server/tools/add-memory.ts b/apps/mcp/src/server/tools/add-memory.ts
index 041008df..c708deb5 100644
--- a/apps/mcp/src/server/tools/add-memory.ts
+++ b/apps/mcp/src/server/tools/add-memory.ts
@@ -15,7 +15,7 @@ export function register(deps: ToolDeps) {
})
deps.server.registerTool(
- "addMemory",
+ "add_memory",
{
description:
"Add (save) or forget a memory in the user's ACTIVE space. Defaults to 'save'. The target space is the one the user selected via select-space; pass containerTag only to override it. Use 'forget' when information is outdated or the user asks to remove it.",
diff --git a/apps/mcp/src/server/tools/get-document.ts b/apps/mcp/src/server/tools/get-document.ts
index 0db8c898..b6ebed04 100644
--- a/apps/mcp/src/server/tools/get-document.ts
+++ b/apps/mcp/src/server/tools/get-document.ts
@@ -13,15 +13,15 @@ export function register(deps: ToolDeps) {
.string()
.min(1, "Document ID is required")
.max(255, "Document ID exceeds maximum length")
- .describe("Document ID returned by listDocuments or a memory result"),
+ .describe("Document ID returned by list_documents or a memory result"),
})
deps.server.registerTool(
- "getDocument",
+ "get_document",
{
title: "Get Document",
description:
- "Read one stored document by ID from any space you can access, including its summary and available content. Use listDocuments to discover document IDs.",
+ "Read one stored document by ID from any space you can access, including its summary and available content. Use list_documents to discover document IDs.",
inputSchema,
outputSchema: getDocumentOutputSchema,
annotations: READ_ONLY_TOOL_ANNOTATIONS,
diff --git a/apps/mcp/src/server/tools/get-profile.test.ts b/apps/mcp/src/server/tools/get-profile.test.ts
index b101f0df..9ea21d32 100644
--- a/apps/mcp/src/server/tools/get-profile.test.ts
+++ b/apps/mcp/src/server/tools/get-profile.test.ts
@@ -38,7 +38,7 @@ function registerProfile(client: {
return handler
}
-describe("getProfile", () => {
+describe("get_profile", () => {
it("returns stable and recent profile facts for the resolved space", async () => {
const handler = registerProfile({
getProfile: async () => ({
diff --git a/apps/mcp/src/server/tools/get-profile.ts b/apps/mcp/src/server/tools/get-profile.ts
index 870b6932..70b7b437 100644
--- a/apps/mcp/src/server/tools/get-profile.ts
+++ b/apps/mcp/src/server/tools/get-profile.ts
@@ -11,11 +11,11 @@ export function register(deps: ToolDeps) {
})
deps.server.registerTool(
- "getProfile",
+ "get_profile",
{
title: "Get Profile",
description:
- "Get the stable and recent profile for one space — long-lived facts plus recent context. searchMemory does not include this. After searching, call this if matching memories are not enough and you need who-the-user-is, preferences, or recent context. When the user names a space, resolve it with listSpaces and pass containerTag; otherwise use the active space. Use whoAmI for account identity and access, not profile facts.",
+ "Get the stable and recent profile for one space — long-lived facts plus recent context. search_memory does not include this. After searching, call this if matching memories are not enough and you need who-the-user-is, preferences, or recent context. When the user names a space, resolve it with list_spaces and pass containerTag; otherwise use the active space. Use who_am_i for account identity and access, not profile facts.",
inputSchema,
outputSchema: getProfileOutputSchema,
annotations: READ_ONLY_TOOL_ANNOTATIONS,
diff --git a/apps/mcp/src/server/tools/guided-save.ts b/apps/mcp/src/server/tools/guided-save.ts
index 7eb1d793..c3f3c042 100644
--- a/apps/mcp/src/server/tools/guided-save.ts
+++ b/apps/mcp/src/server/tools/guided-save.ts
@@ -11,7 +11,7 @@ export function register(deps: ToolDeps) {
{
title: "Add Memory",
description:
- "Open an interactive form when the user wants to draft, review, edit, or choose the target space before saving information to Supermemory. Use this when the user wants to add a memory but has not supplied final content, or explicitly wants to review supplied content before saving. If the user provides the exact content and asks to save it immediately, use addMemory instead.",
+ "Open an interactive form when the user wants to draft, review, edit, or choose the target space before saving information to Supermemory. Use this when the user wants to add a memory but has not supplied final content, or explicitly wants to review supplied content before saving. If the user provides the exact content and asks to save it immediately, use add_memory instead.",
inputSchema: z.object({
prefill: z
.string()
diff --git a/apps/mcp/src/server/tools/list-container-tags.ts b/apps/mcp/src/server/tools/list-container-tags.ts
index 8f9aeb27..30bf2c89 100644
--- a/apps/mcp/src/server/tools/list-container-tags.ts
+++ b/apps/mcp/src/server/tools/list-container-tags.ts
@@ -5,7 +5,7 @@ import { textContent, type ToolDeps } from "./types"
export function register(deps: ToolDeps) {
deps.server.registerTool(
- "listSpaces",
+ "list_spaces",
{
description:
"List the spaces available to the user. Returns each space's name, key, emoji, document/memory counts, and last activity. Use this first to resolve a named space before calling a space-aware tool, or when the user asks which space may contain something. The list is auto-filtered to spaces the user can access.",
diff --git a/apps/mcp/src/server/tools/list-documents.ts b/apps/mcp/src/server/tools/list-documents.ts
index 20f8b59b..10285793 100644
--- a/apps/mcp/src/server/tools/list-documents.ts
+++ b/apps/mcp/src/server/tools/list-documents.ts
@@ -29,11 +29,11 @@ export function register(deps: ToolDeps) {
})
deps.server.registerTool(
- "listDocuments",
+ "list_documents",
{
title: "List Documents",
description:
- "List documents in one space with their IDs, titles, types, processing status, dates, and summaries. This does not return full document content; use getDocument with an ID from this result to read one document. When the user names a space, resolve it with listSpaces and pass containerTag; otherwise use the active space.",
+ "List documents in one space with their IDs, titles, types, processing status, dates, and summaries. This does not return full document content; use get_document with an ID from this result to read one document. When the user names a space, resolve it with list_spaces and pass containerTag; otherwise use the active space.",
inputSchema,
outputSchema: listDocumentsOutputSchema,
annotations: READ_ONLY_TOOL_ANNOTATIONS,
diff --git a/apps/mcp/src/server/tools/list-memories.ts b/apps/mcp/src/server/tools/list-memories.ts
index e5eafd22..79ccee16 100644
--- a/apps/mcp/src/server/tools/list-memories.ts
+++ b/apps/mcp/src/server/tools/list-memories.ts
@@ -29,11 +29,11 @@ export function register(deps: ToolDeps) {
})
deps.server.registerTool(
- "listMemories",
+ "list_memories",
{
title: "List Memories",
description:
- "List the latest extracted memory entries in one space, including stable memory IDs, version information, and source document IDs. This lists memories directly, not documents. When the user names a space, resolve it with listSpaces and pass containerTag; otherwise use the active space. Use searchMemory instead for semantic recall.",
+ "List the latest extracted memory entries in one space, including stable memory IDs, version information, and source document IDs. This lists memories directly, not documents. When the user names a space, resolve it with list_spaces and pass containerTag; otherwise use the active space. Use search_memory instead for semantic recall.",
inputSchema,
outputSchema: listMemoriesOutputSchema,
annotations: READ_ONLY_TOOL_ANNOTATIONS,
diff --git a/apps/mcp/src/server/tools/memory-graph.ts b/apps/mcp/src/server/tools/memory-graph.ts
index 173c0ed3..3a5385ce 100644
--- a/apps/mcp/src/server/tools/memory-graph.ts
+++ b/apps/mcp/src/server/tools/memory-graph.ts
@@ -15,7 +15,7 @@ export function register(deps: ToolDeps) {
{
title: "Memory Graph",
description:
- "Render a space's memory graph directly as an interactive MCP App. This tool is the final visualization; do not create another graph, file, or artifact unless the user explicitly asks for one. If the user names a space, call listSpaces to resolve its key and pass it as containerTag. If the user does not name a space, call this tool directly and omit containerTag; the server uses the active space or account default. Do not open the space picker unless the user asks to change their active space.",
+ "Render a space's memory graph directly as an interactive MCP App. This tool is the final visualization; do not create another graph, file, or artifact unless the user explicitly asks for one. If the user names a space, call list_spaces to resolve its key and pass it as containerTag. If the user does not name a space, call this tool directly and omit containerTag; the server uses the active space or account default. Do not open the space picker unless the user asks to change their active space.",
inputSchema,
outputSchema: graphViewSchema,
annotations: READ_ONLY_TOOL_ANNOTATIONS,
diff --git a/apps/mcp/src/server/tools/search-memory.test.ts b/apps/mcp/src/server/tools/search-memory.test.ts
index fe36ecde..7ebd2800 100644
--- a/apps/mcp/src/server/tools/search-memory.test.ts
+++ b/apps/mcp/src/server/tools/search-memory.test.ts
@@ -50,7 +50,7 @@ function registerSearch(client: {
return handler
}
-describe("searchMemory", () => {
+describe("search_memory", () => {
it("returns matching memories without fetching or including profile", async () => {
const getProfile = vi.fn()
const handler = registerSearch({
diff --git a/apps/mcp/src/server/tools/search-memory.ts b/apps/mcp/src/server/tools/search-memory.ts
index 1f0ec520..9818cb20 100644
--- a/apps/mcp/src/server/tools/search-memory.ts
+++ b/apps/mcp/src/server/tools/search-memory.ts
@@ -18,10 +18,10 @@ export function register(deps: ToolDeps) {
})
deps.server.registerTool(
- "searchMemory",
+ "search_memory",
{
description:
- "Search memories in one space with a natural-language query. Returns matching memories only — not the space profile. If you need who-the-user-is, preferences, or recent context after searching, call getProfile. When the user names a space, resolve it with listSpaces and pass containerTag; otherwise use the active space.",
+ "Search memories in one space with a natural-language query. Returns matching memories only — not the space profile. If you need who-the-user-is, preferences, or recent context after searching, call get_profile. When the user names a space, resolve it with list_spaces and pass containerTag; otherwise use the active space.",
inputSchema,
outputSchema: searchMemoryOutputSchema,
annotations: READ_ONLY_TOOL_ANNOTATIONS,
diff --git a/apps/mcp/src/server/tools/select-space.ts b/apps/mcp/src/server/tools/select-space.ts
index 0eadeb3b..c25f2ce3 100644
--- a/apps/mcp/src/server/tools/select-space.ts
+++ b/apps/mcp/src/server/tools/select-space.ts
@@ -11,7 +11,7 @@ export function register(deps: ToolDeps) {
{
title: "Select Space",
description:
- "Open an interactive picker to choose or change the active Supermemory space used for future actions. Use this only when the user asks to switch, select, or change their active or default space. Do not use it merely because the user names a space for a search, list, graph, save, or upload; resolve that space with listSpaces and pass containerTag to the relevant tool instead.",
+ "Open an interactive picker to choose or change the active Supermemory space used for future actions. Use this only when the user asks to switch, select, or change their active or default space. Do not use it merely because the user names a space for a search, list, graph, save, or upload; resolve that space with list_spaces and pass containerTag to the relevant tool instead.",
inputSchema: z.object({}),
outputSchema: pickerViewSchema,
_meta: appToolMeta(),
diff --git a/apps/mcp/src/server/tools/who-am-i.ts b/apps/mcp/src/server/tools/who-am-i.ts
index 83d33040..af570b7e 100644
--- a/apps/mcp/src/server/tools/who-am-i.ts
+++ b/apps/mcp/src/server/tools/who-am-i.ts
@@ -5,10 +5,10 @@ import { textContent, type ToolDeps } from "./types"
export function register(deps: ToolDeps) {
deps.server.registerTool(
- "whoAmI",
+ "who_am_i",
{
description:
- "Get the current Supermemory account context, including user identity, role, access type, permissions, scope, and active space. Use this when the user asks who they are, what access they have, or which space is currently active. Use listSpaces instead when the user asks which spaces are available.",
+ "Get the current Supermemory account context, including user identity, role, access type, permissions, scope, and active space. Use this when the user asks who they are, what access they have, or which space is currently active. Use list_spaces instead when the user asks which spaces are available.",
inputSchema: z.object({}),
outputSchema: whoAmIOutputSchema,
annotations: READ_ONLY_TOOL_ANNOTATIONS,