Skip to main content
Glama

Obsidian Memory MCP

by YuNaga224
index.ts8.81 kB
#!/usr/bin/env node import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import { Entity, Relation } from './types.js'; import { MarkdownStorageManager } from './storage/MarkdownStorageManager.js'; // Create Markdown storage manager const storageManager = new MarkdownStorageManager(); // The server instance and tools exposed to Claude const server = new Server({ name: "memory-server", version: "0.6.3", }, { capabilities: { tools: {}, }, },); server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "create_entities", description: "Create multiple new entities in the knowledge graph", inputSchema: { type: "object", properties: { entities: { type: "array", items: { type: "object", properties: { name: { type: "string", description: "The name of the entity" }, entityType: { type: "string", description: "The type of the entity" }, observations: { type: "array", items: { type: "string" }, description: "An array of observation contents associated with the entity" }, }, required: ["name", "entityType", "observations"], }, }, }, required: ["entities"], }, }, { name: "create_relations", description: "Create multiple new relations between entities in the knowledge graph. Relations should be in active voice", inputSchema: { type: "object", properties: { relations: { type: "array", items: { type: "object", properties: { from: { type: "string", description: "The name of the entity where the relation starts" }, to: { type: "string", description: "The name of the entity where the relation ends" }, relationType: { type: "string", description: "The type of the relation" }, }, required: ["from", "to", "relationType"], }, }, }, required: ["relations"], }, }, { name: "add_observations", description: "Add new observations to existing entities in the knowledge graph", inputSchema: { type: "object", properties: { observations: { type: "array", items: { type: "object", properties: { entityName: { type: "string", description: "The name of the entity to add the observations to" }, contents: { type: "array", items: { type: "string" }, description: "An array of observation contents to add" }, }, required: ["entityName", "contents"], }, }, }, required: ["observations"], }, }, { name: "delete_entities", description: "Delete multiple entities and their associated relations from the knowledge graph", inputSchema: { type: "object", properties: { entityNames: { type: "array", items: { type: "string" }, description: "An array of entity names to delete" }, }, required: ["entityNames"], }, }, { name: "delete_observations", description: "Delete specific observations from entities in the knowledge graph", inputSchema: { type: "object", properties: { deletions: { type: "array", items: { type: "object", properties: { entityName: { type: "string", description: "The name of the entity containing the observations" }, observations: { type: "array", items: { type: "string" }, description: "An array of observations to delete" }, }, required: ["entityName", "observations"], }, }, }, required: ["deletions"], }, }, { name: "delete_relations", description: "Delete multiple relations from the knowledge graph", inputSchema: { type: "object", properties: { relations: { type: "array", items: { type: "object", properties: { from: { type: "string", description: "The name of the entity where the relation starts" }, to: { type: "string", description: "The name of the entity where the relation ends" }, relationType: { type: "string", description: "The type of the relation" }, }, required: ["from", "to", "relationType"], }, description: "An array of relations to delete" }, }, required: ["relations"], }, }, { name: "read_graph", description: "Read the entire knowledge graph", inputSchema: { type: "object", properties: {}, }, }, { name: "search_nodes", description: "Search for nodes in the knowledge graph based on a query", inputSchema: { type: "object", properties: { query: { type: "string", description: "The search query to match against entity names, types, and observation content" }, }, required: ["query"], }, }, { name: "open_nodes", description: "Open specific nodes in the knowledge graph by their names", inputSchema: { type: "object", properties: { names: { type: "array", items: { type: "string" }, description: "An array of entity names to retrieve", }, }, required: ["names"], }, }, ], }; }); server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (!args) { throw new Error(`No arguments provided for tool: ${name}`); } switch (name) { case "create_entities": return { content: [{ type: "text", text: JSON.stringify(await storageManager.createEntities(args.entities as Entity[]), null, 2) }] }; case "create_relations": return { content: [{ type: "text", text: JSON.stringify(await storageManager.createRelations(args.relations as Relation[]), null, 2) }] }; case "add_observations": return { content: [{ type: "text", text: JSON.stringify(await storageManager.addObservations(args.observations as { entityName: string; contents: string[] }[]), null, 2) }] }; case "delete_entities": await storageManager.deleteEntities(args.entityNames as string[]); return { content: [{ type: "text", text: "Entities deleted successfully" }] }; case "delete_observations": await storageManager.deleteObservations(args.deletions as { entityName: string; observations: string[] }[]); return { content: [{ type: "text", text: "Observations deleted successfully" }] }; case "delete_relations": await storageManager.deleteRelations(args.relations as Relation[]); return { content: [{ type: "text", text: "Relations deleted successfully" }] }; case "read_graph": return { content: [{ type: "text", text: JSON.stringify(await storageManager.readGraph(), null, 2) }] }; case "search_nodes": return { content: [{ type: "text", text: JSON.stringify(await storageManager.searchNodes(args.query as string), null, 2) }] }; case "open_nodes": return { content: [{ type: "text", text: JSON.stringify(await storageManager.openNodes(args.names as string[]), null, 2) }] }; default: throw new Error(`Unknown tool: ${name}`); } }); async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error("Knowledge Graph MCP Server running on stdio (storage: markdown)"); } main().catch((error) => { console.error("Fatal error in main():", error); process.exit(1); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/YuNaga224/obsidian-memory-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server