Skip to main content
Glama
bong-u

mcp-server-silverbullet

by bong-u
README.md
# mcp-server-silverbullet

[![CI](https://github.com/bong-u/mcp-server-silverbullet/actions/workflows/ci.yml/badge.svg)](https://github.com/bong-u/mcp-server-silverbullet/actions/workflows/ci.yml)
[![npm](https://img.shields.io/npm/v/@bong-u/mcp-server-silverbullet)](https://www.npmjs.com/package/@bong-u/mcp-server-silverbullet)

**English** · [한국어](README.ko.md)

An MCP server that connects a [SilverBullet](https://silverbullet.md) space over
its HTTP filesystem API (`/.fs`) and exposes **only a chosen prefix** to AI
agents. It provides five tools plus resources, so you can attach your notes to an
agent without handing over the whole space. Runs with `npx` — no install needed.

## Features

- **Prefix scoping** — the agent sees only what lives under one prefix (the
  folder's contents plus its namesake page). Enforced in code, not in the prompt.
- **Scope gating** — allow `read` only, or add `write` / `delete`. Tools that
  aren't allowed are never registered in the first place.
- **Path hardening** — absolute paths, `..`, encoded traversal, and anything
  outside the prefix are all rejected.
- **Token isolation** — the SilverBullet token stays in the server environment
  and is never exposed to the LLM.

> **Note** — this is a guardrail for the *LLM*, not a multi-tenant security
> boundary. SilverBullet's `SB_AUTH_TOKEN` grants full space access (there are no
> prefix-scoped tokens), so use it only in an environment you control.

## Setup

Requires Node.js ≥ 20 and a SilverBullet instance with `SB_AUTH_TOKEN` configured.

Add the following to your MCP client (Claude Code, Cursor, Claude Desktop, etc.):

```json
{
  "mcpServers": {
    "silverbullet": {
      "command": "npx",
      "args": ["-y", "@bong-u/mcp-server-silverbullet@0.1.0"],
      "env": {
        "SILVERBULLET_MCP_BASE_URL": "https://notes.example.com",
        "SILVERBULLET_MCP_TOKEN": "<SB_AUTH_TOKEN>",
        "SILVERBULLET_MCP_PREFIX": "projects/work",
        "SILVERBULLET_MCP_SCOPES": "read"
      }
    }
  }
}
```

| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `SILVERBULLET_MCP_BASE_URL` | ✅ | — | SilverBullet instance URL. |
| `SILVERBULLET_MCP_TOKEN` | ✅ | — | `SB_AUTH_TOKEN`. Never passed to the LLM. |
| `SILVERBULLET_MCP_PREFIX` | — | whole space | Subpath the agent may access, e.g. `projects/work`. |
| `SILVERBULLET_MCP_SCOPES` | — | `read,write,delete` | Allowed operations (must include `read`). |
| `SILVERBULLET_MCP_TIMEOUT_MS` | — | `15000` | Request timeout (ms). |
| `SILVERBULLET_MCP_MAX_SEARCH_BYTES` | — | `1000000` | Max file size `search_files` will scan. |
| `SILVERBULLET_MCP_USER_AGENT` | — | `mcp-server-silverbullet/<version>` | `User-Agent` sent upstream. |

If a required variable is missing or malformed, the server exits immediately with
a clear error.

## Tools

Paths keep the prefix's top segment (`notes.md`, `notes/todo.md`). Feed a path
returned by `list_files` straight into `read_file`.

| Tool | Scope | Description |
| --- | --- | --- |
| `list_files` | `read` | List files under the prefix (optionally within a subpath). |
| `read_file` | `read` | Read a file — text as `utf8`, binary as `base64`. |
| `write_file` | `write` | Create or replace a file. |
| `delete_file` | `delete` | Delete a file. |
| `search_files` | `read` | Substring search over file names and text content. |

Files are also exposed as resources: `silverbullet://notes/todo.md`.

## Development

```bash
npm install
cp .env.example .env    # fill in instance URL + token
npm run dev             # run straight from source (tsx), loading .env

npm run lint            # biome
npm run typecheck       # tsc --noEmit
npm test                # vitest
npm run build           # compile to dist/
```

CI runs lint · typecheck · test · build on Node 20, 22, and 24.

## License

MIT