# MCP Protocol Contract **Purpose**: Define the JSON-RPC communication contract between AI assistants and the Obsidian MCP server ## Transport **Protocol**: JSON-RPC 2.0 over stdio **Direction**: Bidirectional (client ↔ server) ### Stdio Requirements - **stdin**: Server reads JSON-RPC requests line-by-line - **stdout**: Server writes JSON-RPC responses line-by-line (one message per line) - **stderr**: Server logs debugging information (never JSON-RPC messages) ### Message Format All messages are single-line JSON objects ending with `\n`: ```json {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{...}}\n ``` ## Initialization Handshake ### Request: initialize Client sends capabilities and version information: ```json { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": { "name": "Claude Desktop", "version": "1.0.0" } } } ``` ### Response: initialize Server responds with its capabilities: ```json { "jsonrpc": "2.0", "id": 1, "result": { "protocolVersion": "2024-11-05", "capabilities": { "tools": {} }, "serverInfo": { "name": "obsidian-mcp", "version": "1.0.0" } } } ``` ## Tool Discovery ### Request: tools/list Client requests available tools: ```json { "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} } ``` ### Response: tools/list Server returns tool definitions with schemas: ```json { "jsonrpc": "2.0", "id": 2, "result": { "tools": [ { "name": "obsidian_create_note", "description": "Create a new note in the vault", "inputSchema": { "type": "object", "properties": { "name": { "type": "string", "description": "Note name (without .md extension) or exact path" }, "content": { "type": "string", "description": "Initial note content (markdown)" }, "overwrite": { "type": "boolean", "description": "Overwrite if file exists" } }, "required": ["name"] } } // ... more tools ] } } ``` ## Tool Invocation ### Request: tools/call Client invokes a tool: ```json { "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "obsidian_create_note", "arguments": { "name": "Meeting Notes", "content": "# Meeting Notes\n\n- Agenda item 1" } } } ``` ### Response: Success Tool execution succeeded: ```json { "jsonrpc": "2.0", "id": 3, "result": { "content": [ { "type": "text", "text": "{\"success\":true,\"data\":{\"path\":\"Meeting Notes.md\",\"created\":true}}" } ] } } ``` ### Response: Error Tool execution failed: ```json { "jsonrpc": "2.0", "id": 3, "error": { "code": -32000, "message": "Obsidian application is not running. Please start Obsidian and try again.", "data": { "errorCode": "OBSIDIAN_NOT_RUNNING" } } } ``` ## Error Codes ### JSON-RPC Standard Errors | Code | Message | Meaning | |------|---------|---------| | -32700 | Parse error | Invalid JSON | | -32600 | Invalid Request | Invalid JSON-RPC structure | | -32601 | Method not found | Unknown method | | -32602 | Invalid params | Parameter validation failed | | -32603 | Internal error | Server internal error | ### Application Errors | Code | Message | When | |------|---------|------| | -32000 | Server error | Generic application error | | -32001 | Obsidian not running | Obsidian app not detected | | -32002 | Vault not found | Invalid vault name | | -32003 | File not found | Note doesn't exist | | -32004 | Ambiguous name | Multiple files match name | | -32005 | Permission denied | Filesystem permission issue | | -32006 | Timeout | Operation exceeded 30s | ## Shutdown ### Notification: exit Client notifies server of shutdown (no response expected): ```json { "jsonrpc": "2.0", "method": "exit" } ``` Server should: 1. Complete any in-flight operations 2. Close file handles 3. Flush logs 4. Exit process ### EOF on stdin If stdin closes without `exit` notification, server should gracefully shutdown. ## Performance Requirements - **initialize response**: <100ms - **tools/list response**: <200ms - **tools/call response**: <3s for file ops, <5s for search (per SC-001, SC-002) ## Compliance Checklist - [x] JSON-RPC 2.0 format for all messages - [x] Stdio transport (stdin for requests, stdout for responses) - [x] Line-by-line message format (newline-delimited) - [x] Initialize handshake before tool calls - [x] Tool schemas in tools/list response - [x] Structured error responses with codes - [x] Graceful shutdown on exit notification - [x] No stdout pollution (logs to stderr only) - [x] Immediate stdout flushing after responses - [x] EOF handling (graceful shutdown)