supermemory/apps/mcp/src/server/tools/get-document.ts
Dhravya e2a3349300
fix(mcp): only hand out IDs and spaces the caller can use
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-16 05:48:33 +00:00

69 lines
2.2 KiB
TypeScript

import { z } from "zod"
import { formatDocument, getDocumentContent } from "../format"
import { optionalNamespaceSchema } from "../namespace"
import {
legacyNamespaceInput,
namespaceArg,
withLegacyNamespace,
} from "./compat"
import { READ_ONLY_TOOL_ANNOTATIONS } from "./annotations"
import {
getDocumentOutputSchema,
type GetDocumentOutput,
} from "./output-schemas"
import { textContent, type ToolDeps } from "./types"
export function register(deps: ToolDeps) {
const inputSchema = z.object({
documentId: z
.string()
.min(1, "Document ID is required")
.max(255, "Document ID exceeds maximum length")
.describe(
"Document ID from list_documents, or the document ID shown on a search_memory or list_memories result. Memory IDs are not document IDs.",
),
namespace: optionalNamespaceSchema,
...legacyNamespaceInput,
})
deps.server.registerTool(
"get_document",
{
title: "Get Document",
description:
"Read one stored document by ID from one space, including its summary and available content. Get document IDs from list_documents or from the document shown on a search_memory result. When the document is in a named space, resolve it with list_spaces and pass namespace; otherwise use the active space.",
inputSchema,
outputSchema: getDocumentOutputSchema,
annotations: READ_ONLY_TOOL_ANNOTATIONS,
},
async (args) => {
try {
const namespace = await deps.resolveNamespace(namespaceArg(args))
const client = deps.getClient(namespace)
const document = await client.getDocument(args.documentId)
const { content, truncated } = getDocumentContent(document)
const structuredContent: GetDocumentOutput = withLegacyNamespace({
namespace,
document: {
id: document.id,
title: document.title,
type: document.type,
status: document.system.status,
createdAt: document.system.createdAt,
updatedAt: document.system.updatedAt,
summary: document.summary,
content,
contentTruncated: truncated,
},
})
return {
content: [textContent(formatDocument(document))],
structuredContent,
}
} catch (error) {
return deps.errorResult(error)
}
},
)
}