diff --git a/packages/mcp/server.ts b/packages/mcp/server.ts index 0884a39..bf348ea 100644 --- a/packages/mcp/server.ts +++ b/packages/mcp/server.ts @@ -1,7 +1,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { getLogger } from "@logtape/logtape"; import { z } from "zod"; -import type { Consumer } from "@cistern/consumer"; +import type { Consumer, DecryptedMemo } from "@cistern/consumer"; export function createServer(consumer: Consumer) { const logger = getLogger("cistern-mcp"); @@ -10,23 +10,68 @@ export function createServer(consumer: Consumer) { version: "1.0.0", }); + let iterator: + | AsyncGenerator + | undefined; + + server.registerTool( + "next_memo", + { + title: "Next memo", + description: "Retrieve the next outstanding memo", + outputSchema: { tid: z.string(), text: z.string() }, + }, + async () => { + if (!iterator) { + logger.trace("creating iterator"); + iterator ??= consumer.listMemos(); + } + + const res = await iterator.next(); + + if (res.done) { + logger.trace("iterator done; cleaning up"); + iterator = undefined; + } + + return { + content: [{ + type: "text", + text: res.value?.text ?? "no memos remaining", + }], + structuredContent: { + tid: res.value?.tid ?? "", + text: res.value?.text ?? "no memos remaining", + }, + }; + }, + ); + server.registerTool( - "add", + "delete_memo", { - title: "Addition Tool", - description: "Add two numbers", - inputSchema: { a: z.number(), b: z.number() }, - outputSchema: { result: z.number() }, + title: "Delete memo", + description: + "Delete a memo by record key, after it has been handled as instructed by the user", + inputSchema: { key: z.string() }, + outputSchema: { success: z.boolean() }, }, - ({ a, b }) => { - logger.trace("Addition Tool called", { a, b }); + async ({ key }) => { + try { + await consumer.deleteMemo(key); - const output = { result: a + b }; + return { + content: [{ type: "text", text: "delete successful" }], + structuredContent: { success: true }, + }; + } catch (error) { + logger.error("failed to delete memo: {error}", { error }); - return Promise.resolve({ - content: [{ type: "text", text: JSON.stringify(output) }], - structuredContent: output, - }); + return { + content: [{ type: "text", text: "delete unsuccessful" }], + structuredContent: { success: false }, + }; + } }, );