npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wiki-viewer-mcp

v0.2.0

Published

MCP filesystem adapter for wiki-viewer agent API

Readme

wiki-viewer-mcp

MCP filesystem adapter for wiki-viewer.

Maps standard MCP filesystem tools onto the wiki-viewer agent HTTP API so Claude Code, Cursor, and Codex get native-feeling file tools against a remote wiki-viewer instance.

First-time setup (register)

Before connecting an agent, register it with your wiki-viewer instance. The human operator approves the request in the wiki-viewer AI Panel.

Using the built-in CLI (recommended):

# Once published to npm:
npx wiki-viewer-mcp register \
  --url https://notes.example.com \
  --id ai:myagent \
  --name "My Agent" \
  --scope-paths "**/*" \
  --ops read,mutate,delete \
  --timeout 300

# Or from a local build (after cd packages/wiki-viewer-mcp && npm run build):
node ./dist/index.js register \
  --url http://localhost:3000 \
  --id ai:myagent \
  --name "My Agent"

The CLI will:

  1. POST the registration to wiki-viewer and print the registration ID.
  2. Print ⏳ Waiting for approval. Open the wiki-viewer AI Panel and approve agent "ai:myagent".
  3. Poll every 3 s until the human approves (or timeout).
  4. On approval, print your WIKI_VIEWER_TOKEN and WIKI_VIEWER_AGENT_ID, then print a ready-to-paste mcp.json snippet.
✅ Approved!

Agent ID : ai:myagent
Token    : wv_tok_…

Paste this into your mcp.json:

{
  "servers": {
    "wiki-viewer": {
      "command": "npx",
      "args": ["wiki-viewer-mcp"],
      "env": {
        "WIKI_VIEWER_URL": "https://notes.example.com",
        "WIKI_VIEWER_TOKEN": "wv_tok_…",
        "WIKI_VIEWER_AGENT_ID": "ai:myagent"
      }
    }
  }
}

CLI options:

| Flag | Required | Default | Description | | --------------- | -------- | ------------- | --------------------------------------------------------- | | --url | yes | — | Base URL of wiki-viewer, e.g. https://notes.example.com | | --id | yes | — | Agent ID, must match ai:[a-z][a-z0-9-]{0,30} | | --name | yes | — | Human-readable display name | | --scope-paths | no | **/* | Comma-separated path globs the agent can access | | --ops | no | read,mutate | Comma-separated: read, mutate, delete | | --timeout | no | 300 | Seconds to wait for approval before giving up |


Installation

# Once published to npm:
npx wiki-viewer-mcp
# or install globally
npm i -g wiki-viewer-mcp

# From a local build:
cd packages/wiki-viewer-mcp
npm run build
node dist/index.js   # start MCP server

Configuration

Set three environment variables before starting the MCP server (the register command prints them for you after approval):

| Var | Description | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | WIKI_VIEWER_URL | Base URL of your wiki-viewer instance, e.g. https://notes.example.com | | WIKI_VIEWER_TOKEN | Bearer token obtained via wiki-viewer-mcp register | | WIKI_VIEWER_AGENT_ID | Your agent ID (e.g. ai:myagent), sent as X-Agent-Id on every request | | WIKI_VIEWER_WORKSPACE | Optional. Workspace id, sent as X-Workspace on every request. Targets one root directory when the instance serves several. Omit for single-workspace instances (the server uses its default). |

Usage in Claude Code / Cursor / Codex

Add to your mcp.json (or equivalent):

{
  "servers": {
    "wiki-viewer": {
      "command": "npx",
      "args": ["wiki-viewer-mcp"],
      "env": {
        "WIKI_VIEWER_URL": "https://notes.example.com",
        "WIKI_VIEWER_TOKEN": "<your-token>",
        "WIKI_VIEWER_AGENT_ID": "<your-agent-id>"
      }
    }
  }
}

Available tools

| Tool | Maps to | Description | | ---------------- | ---------------------------------- | ----------------------------------------------- | | read_file | GET /api/agent/fs/file/<path> | Read file bytes; captures sha256 + collab state | | write_file | PUT /api/agent/fs/file/<path> | Atomic whole-file write with If-Match | | edit_file | read → str-replace → PUT | Client-side exact-string replacement | | list_directory | GET /api/agent/fs/ls/<path> | Scope-filtered directory listing | | search | POST /api/agent/fs/search | Server-side grep or glob | | move_file | POST /api/agent/fs/move | Rename/move; sidecar handled by server | | delete_file | DELETE /api/agent/fs/file/<path> | Delete; requires delete scope |

Working mode vs Collaborating mode (important)

wiki-viewer has two tiers for .md files:

  • Tier 1 (raw fs) — fast, all file types, light audit. Use for code, config, non-prose, or whole-file rewrites.
  • Tier 2 (collab) — block-ops + proof-spans, review/accept/revert by humans. Use for prose that a human is co-editing.

The shim enforces this automatically in three layers:

Layer 1 — discoverable (headers)

Every read_file response includes:

X-Collab-State: active | tracked | untracked | not-markdown
X-Collab-Revision: <n>
X-Collab-Snapshot: /api/agent/files/<path>.md

| State | Meaning | You should | | -------------- | ------------------------------------------------------------ | -------------------------------------- | | active | Human has the doc open OR there are pending review artifacts | Use Tier-2 block-ops | | tracked | Sidecar exists, no active review | Prefer Tier-2 for prose/semantic edits | | untracked | Plain .md, no collaboration history | Raw ok | | not-markdown | Not a .md file | Raw only |

Layer 2 — client-side guard

If the shim's last-known X-Collab-State for a .md is active, write_file and edit_file are blocked before any HTTP request is made. The tool returns a clear error with the Tier-2 snapshot URL.

Layer 3 — server-side enforcement (409)

Even if the cache is stale, the server re-checks collab state atomically inside the write mutex. A raw PUT to an active .md is rejected with 409 COLLAB_ACTIVE and the Tier-2 snapshot URL. The shim surfaces this as a clear error message.

Rule

Before editing a .md, run read_file and check X-Collab-State.
If active, use wiki-viewer block-ops (Tier 2).
For everything else, use raw fs tools.

If-Match concurrency

The shim caches the sha256 from every read_file response (ETag header). write_file, edit_file, and delete_file automatically send this as If-Match. If the file changed since your read, you get a 412 error with instructions to re-read.

edit_file always reads fresh before writing, so it's naturally atomic per-op.

Use force: true to bypass If-Match (audited by the server).

Scope

Your token's scope.paths (set during registration) governs what paths you can touch. Paths outside scope, and internal paths (.proof/, .locks/, the app db), are rejected by the server. Scope supports **, *, ? glob patterns.

The delete op is a separate scope permission from mutate — an agent can be granted "edit but never delete."

Development

cd packages/wiki-viewer-mcp
pnpm install
pnpm test      # runs unit tests with tsx --test
pnpm build     # compiles to dist/

Tests use a mock fetch — no real wiki-viewer instance needed.