{
  "markdown": "# nb-mcp\n\nMCP server wrapping the [nb](https://github.com/xwmx/nb) CLI for LLM-friendly note-taking.\n\n## Motivation\n\nUsing `nb` directly via shell has two problems for LLM assistants:\n\n1. **Backtick escaping**: Markdown content with backticks triggers shell command substitution, corrupting notes.\n\n2. **Notebook context**: `nb` assumes a default notebook, making per-project use awkward.\n\nThis MCP server solves both by:\n\n- Accepting content as JSON parameters (no shell escaping needed)\n- Qualifying all commands with an explicit notebook\n\n## Quick Start\n\n### Prerequisites\n\nInstall `nb` by following the official instructions:\n[nb installation guide](https://github.com/xwmx/nb#installation).\n\n### Installation\n\nFrom [crates.io](https://crates.io/crates/nb-mcp-server):\n\n```bash\ncargo install nb-mcp-server\n```\n\nSee the [changelog](CHANGELOG.md) for release history and upgrade notes.\n\nOr download a prebuilt binary from [GitHub Releases](https://github.com/emcd/nb-mcp-server/releases).\n\n### Build from Source\n\n```bash\ncargo build --release\n```\n\n### Run\n\nWith default notebook from environment:\n\n```bash\nNB_MCP_NOTEBOOK=myproject ./target/release/nb-mcp\n```\n\nOr via CLI argument (takes precedence):\n\n```bash\n./target/release/nb-mcp --notebook myproject\n```\n\nDisable commit and tag signing in the notebook repository:\n\n```bash\n./target/release/nb-mcp --notebook myproject --no-commit-signing\n```\n\nAllow new notes at the notebook root instead of requiring a folder:\n\n```bash\n./target/release/nb-mcp --notebook myproject --allow-top-level-notes\n```\n\nPrint the installed version:\n\n```bash\n./target/release/nb-mcp --version\n```\n\nShow the resolved notebook path and state directory:\n\n```bash\n./target/release/nb-mcp --show-paths\n```\n\n### MCP Configuration\n\nAdd to your MCP client configuration (e.g., `.mcp.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"nb\": {\n      \"command\": \"/path/to/nb-mcp\",\n      \"args\": [\"--notebook\", \"myproject\"]\n    }\n  }\n}\n```\n\n## Commands\n\nThe canonical access path is the multiplexed `nb` tool with a `command`\nparameter, which reduces the token footprint of the MCP server.\nThe `args` field must be a JSON object. Stringified JSON payloads are rejected.\nUnknown `args` fields are rejected instead of ignored; use the exact command\nschema fields or documented aliases.\nReturned identifiers such as `coordination/mcp/1` or\n`myproject:coordination/mcp/1` are `nb` selectors, not filesystem paths in the\ncurrent repository. Notebook storage is managed by `nb` configuration.\nThe `notebook` argument must be a bare notebook name. Use `folder` for folder\npaths and `id` / `selector` for note selectors. Existing-item commands accept\ncopied selectors such as `myproject:coordination/mcp/1`, but reject conflicts\nwith a separate `notebook` argument.\n\n### First-Class Tools\n\nAll commands are also available as direct first-class tools with typed\nschemas: `add`, `show`, `edit`, `delete`, `move`, `list`, `search`, `todo`,\n`do`, `undo`, `tasks`, `bookmark`, `folders`, `mkdir`, `import`, `status`,\n`notebooks`. These bypass the multiplexed command dispatch. The multiplexed\n`nb` tool remains as the compact/backcompat compatibility surface.\n\n### Notes\n\n| Command | Description | Key Arguments |\n|---------|-------------|---------------|\n| `nb.add` | Create a note | `title`, `content`, `tags[]`, `folder` required by default |\n| `nb.show` | Read a note | `id` (alias: `selector`) |\n| `nb.edit` | Update a note | `id` (alias: `selector`), `content`, `mode` (required: `overwrite`, `append`, `prepend`) |\n| `nb.delete` | Delete a note | `id` (alias: `selector`) |\n| `nb.move` | Move or rename a note | `id` (alias: `selector`), `destination` |\n| `nb.list` | List notes | `folder`, `tags[]`, `limit` (`[ ]` / `[x]` indicate todo status; leading glyphs are item markers) |\n| `nb.search` | Full-text search | `queries[]` (required), `mode` (`any` default, `all`), `tags[]` |\n\n### Todos\n\n| Command | Description | Key Arguments |\n|---------|-------------|---------------|\n| `nb.todo` | Create a todo | `folder` required by default, `title`, optional `description` (alias: `content`), optional `tasks[]`, `tags[]` |\n| `nb.do` | Mark complete | `id` (alias: `selector`), optional `task_number` |\n| `nb.undo` | Reopen | `id` (alias: `selector`), optional `task_number` |\n| `nb.tasks` | List todos | optional `status` (`open` or `closed`), optional `recursive` (`true` default) |\n\n### Organization\n\n| Command | Description | Key Arguments |\n|---------|-------------|---------------|\n| `nb.bookmark` | Save a URL | `url`, `folder` required by default, `title`, `tags[]`, `comment` |\n| `nb.import` | Import file/URL | `source`, `folder` required by default, `filename`, `convert` |\n| `nb.folders` | List folders | `parent` |\n| `nb.mkdir` | Create folder | `path` |\n| `nb.notebooks` | List notebooks only | (none) |\n| `nb.status` | Notebook info | (none) |\n\n## Examples\n\nCreate a note with code:\n\n```json\n{\n  \"command\": \"nb.add\",\n  \"args\": {\n    \"title\": \"API Design Notes\",\n    \"content\": \"# API Design\\n\\nUse `GET /items` for listing.\\n\\n```python\\nresponse = client.get('/items')\\n```\",\n    \"tags\": [\"design\", \"api\"],\n    \"folder\": \"docs\"\n  }\n}\n```\n\nSearch for notes:\n\n```json\n{\n  \"command\": \"nb.search\",\n  \"args\": {\n    \"queries\": [\"API\", \"design\"],\n    \"mode\": \"any\",\n    \"tags\": [\"design\"]\n  }\n}\n```\n\n## Tagging Suggestions\n\nFor multi-LLM projects, consider using consistent tag prefixes (optional).\nExample categories and prefixes:\n\n| Category | Pattern | Examples |\n|----------|---------|----------|\n| Collaborator | `llm-<name>` | `llm-claude`, `llm-gpt` |\n| Component | `component-<name>` | `component-api`, `component-ui` |\n| Task type | `task-<type>` | `task-bug`, `task-feature` |\n| Status | `status-<state>` | `status-review`, `status-blocked` |\n\n## Edit Behavior\n\n`nb.edit` requires an explicit `mode` value. The schema advertises\n`overwrite`, `append`, and `prepend`. `overwrite` replaces every byte\nof the note body (it is destructive). The legacy input value\n`replace` is still accepted through the upstream `nb-api` serde\nalias and is interpreted as `overwrite`.\n\nOmitting `mode` is rejected before `nb` is invoked. Clients that\nrelied on the destructive default must now send `mode: \"overwrite\"`\nexplicitly.\n\n## Typed Error Surfaces\n\n`nb-api 0.2` introduces two typed failures that the MCP layer\ntranslates into actionable diagnostics on both the multiplexed\n`nb.*` surface and the first-class tool surface:\n\n- `show` on a non-text selector (folder, archive, image, ...): the\n  error names the selector and the actual non-text type, states\n  that `show` reads text notes only, and points the caller at\n  `folders`/`list`. The server never silently re-routes `show` to\n  another command.\n- `add` with both a `title` and a `content` whose first nonblank\n  line is an H1 that duplicates the title: the error names the\n  title and the detected heading and tells the caller to remove\n  the duplicate H1 or omit the separate `title`.\n\n## Configuration\n\n### Notebook Resolution\n\nPriority order:\n\n1. Per-command `notebook` argument (highest)\n2. CLI `--notebook` flag\n3. `NB_MCP_NOTEBOOK` environment variable\n4. Git-derived default from the master worktree path\n\nIf no notebook can be resolved, commands fail with a configuration error. The\nserver does not fall back to `nb`'s default notebook.\n\nIf the resolved notebook does not exist, the server creates it automatically.\nUse `--no-create-notebook` to disable automatic creation.\n\n### Logging\n\nLogs are written to `~/.local/state/nb-mcp/{project}--{worktree}.log` (XDG-compliant).\n\nFor Git worktrees, logs are named after both the master project and the\nworktree basename to avoid collisions between multiple MCP server instances.\n\nUse `--show-paths` to print the resolved notebook path and state directory.\n\n### Folder Requirement\n\nBy default, note-creating commands require a `folder` argument so agents do not\naccidentally litter project notebook roots. This applies to `nb.add`, `nb.todo`,\n`nb.bookmark`, and `nb.import`. Use `nb.mkdir` to create new folders and\n`nb.folders` to list existing folders.\n\nSet `NB_MCP_ALLOW_TOP_LEVEL_NOTES=true` or pass `--allow-top-level-notes` to\npermit root-level note creation.\n\n### Notebook Overrides\n\nMutating commands warn after successful writes when the `notebook` argument\ntargets a notebook other than the project default. Cross-notebook writes remain\nallowed for collaboration across teams, but the warning helps catch accidental\nnotebook/folder confusion.\n\nThe `notebook` argument accepts only bare notebook names, not selector syntax.\nFor example, use `notebook: \"other-team\"` with `folder: \"todos/mcp\"`, not\n`notebook: \"other-team:todos/mcp\"`.\n\nControl log level with `RUST_LOG`:\n\n```bash\nRUST_LOG=debug nb-mcp --notebook myproject\n```\n\n### Commit Signing\n\nUse `--no-commit-signing` to disable commit and tag signing in the notebook\nrepository. The server updates the notebook repository's local Git config so\nsigning prompts do not block MCP tool calls.\n\n## Related Projects\n\n- [nb-api](https://github.com/emcd/nb-api) — Typed Rust interface to the `nb` CLI. Published on [crates.io](https://crates.io/crates/nb-api). This MCP server depends on `nb-api` for all note-taking primitives; the `edit` vocabulary, typed `show`/`add` errors, and sanitized empty listings all come from `nb-api 0.2`.\n\n## Contributing\n\nSee the contribution guide and code of conduct:\n\n- [Contribution guide](https://github.com/emcd/nb-mcp-server/blob/master/documentation/contribution.md)\n- [Code of conduct](https://github.com/emcd/nb-mcp-server/blob/master/documentation/conduct.md)\n\n## License\n\n[Apache 2.0](https://github.com/emcd/nb-mcp-server/blob/master/LICENSE)\n",
  "bytes": 9661,
  "sha": "314f9d3f782aa426a5d01234707e5c9f201884062c17c79c12021a5c33b94a61",
  "repo_slug": "emcd/nb-mcp-server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_emcd_nb_mcp_server_e55768e7/readme"
}