Skip to content

feat(mcp): read-only MCP server (search_notes, list_notes, get_note)#25

Merged
shahid-io merged 1 commit into
mainfrom
feature/mcp-server
Jun 14, 2026
Merged

feat(mcp): read-only MCP server (search_notes, list_notes, get_note)#25
shahid-io merged 1 commit into
mainfrom
feature/mcp-server

Conversation

@shahid-io

Copy link
Copy Markdown
Owner

What

Adds inode mcp — runs inode as a read-only Model Context Protocol server over stdio, so MCP-aware clients (Claude Code, Cursor, …) can read the knowledge base mid-task.

Three tools:

  • search_notes — natural-language vector search → grounded answer + source notes
  • list_notes — metadata-only listing, filterable by category/tag
  • get_note — fetch one note by ID prefix

Safety model

  • Read-only by design. Writing notes from an agent stays out of v1 — an agent silently filling or wiping the KB with no reviewable trail is a bad default.
  • Sensitive notes are protected. By default they're excluded from search candidates entirely (the LLM can't quote secrets) and masked in get_note. Opt in with inode config set mcp.reveal_sensitive true.
  • Tools advertise honest annotations (readOnly, idempotent, not destructive) so clients don't warn users about safe lookups.

Testing

  • Unit tests cover masking, formatting, and the read-only annotations (internal/mcp).
  • Smoke-tested live over stdio: initializetools/listtools/call list_notes against a real local DB.
  • search_notes requires Ollama (query embedding + grounded answer); list_notes/get_note are pure SQLite.

Wiring it up

claude mcp add inode -- inode mcp

or inspect interactively with npx @modelcontextprotocol/inspector inode mcp.

Commits

  • feat(mcp) — server + three tools + tests
  • fix(mcp) — advertise tools as read-only (mark3labs defaults were destructive=true)

🤖 Generated with Claude Code

search_notes, list_notes and get_note never mutate the KB, but
mark3labs/mcp-go's default tool annotations report readOnlyHint=false /
destructiveHint=true. MCP clients use these hints to decide whether to
auto-approve a call, so safe lookups were being flagged as destructive.

Set ReadOnly + Idempotent true and Destructive + OpenWorld false on each
tool, and add a regression test asserting the annotations via ListTools().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@shahid-io
shahid-io merged commit 52ead41 into main Jun 14, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant