Gitbook Mcp — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Gitbook Mcp (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A [Model Context Protocol](https://modelcontextprotocol.io) server for GitBook. It lets an MCP host (Claude Code, Claude Desktop, Cursor, …) read your GitBook content and drive a change-request write workflow, over stdio or streamable HTTP.
Built on the official @gitbook/api client and @modelcontextprotocol/sdk 1.x.
core + change-requests) keeps the surface small; write and destructive tools are gated by read-only mode plus an opt-in.gitbook://{spaceId}/{pageId}.Status: published as @hoyongjin/gitbook-mcp (v2.0.0), with the original 11 tools enabled by default. Covered by unit, MCP-protocol, and manifest-contract tests. The stdio transport suits local IDE/CLI use. The HTTP transport adds bearer auth, DNS-rebinding protection, a session cap with idle reaper, per-IP rate limiting, health/readiness probes, and Prometheus metrics for hosted use.GitBook's public API has no direct "edit this page body" endpoint (createPage/updatePage exist only as the GitBook Assistant's _internal_ tool names, not as REST methods). Content authoring goes through:
gitbook_create_change_request), review, then gitbook_merge_change_request to publish.gitbook_import_content imports a web page URL into a space/change-request/page, AI-enhanced by default. This is the supported "write content" primitive. Imports are asynchronous, and GitBook exposes no status-poll endpoint.So the server exposes many reads and a single coarse, review-gated write path. It cannot rewrite a specific paragraph through the API.
# From source (local use):
cd gitbook-mcp && npm install && npm run build
# → run with: node dist/index.js (or `npm start`)
# Or, once published:
npx @hoyongjin/gitbook-mcpThe package is scoped to@hoyongjin/gitbook-mcp(the unscopedgitbook-mcpon npm belongs to a different project). Make sure your npm account owns the@hoyongjinscope before publishing.
Create a token at GitBook → Settings → Developer → Personal access tokens.
# Local build:
claude mcp add gitbook \
--env GITBOOK_TOKEN=gb_api_xxx \
-- node /absolute/path/to/gitbook-mcp/dist/index.js.mcp.json / Claude Desktop config{
"mcpServers": {
"gitbook": {
"command": "node",
"args": ["/absolute/path/to/gitbook-mcp/dist/index.js"],
"env": { "GITBOOK_TOKEN": "gb_api_xxx" }
}
}
}(After publishing, replace command/args with "command": "npx", "args": ["@hoyongjin/gitbook-mcp"].)
Run read-only (recommended unless you need writes) by adding "--read-only" to args, or "GITBOOK_READONLY": "true" to env.
All configuration is via environment variables (see .env.example). The token is never taken from a CLI argument.
| Variable | Default | Description |
|---|---|---|
GITBOOK_TOKEN | — | Required. Personal access token (account-wide privileges). |
GITBOOK_ENDPOINT | https://api.gitbook.com | API base URL. |
GITBOOK_READONLY | false | Hide all write/destructive tools when true. |
GITBOOK_TOOLSETS | core,change-requests | Comma-separated toolsets to enable, or all. Unset/empty → the default two. Unknown key fails closed. See Toolsets. |
GITBOOK_ALLOW_DESTRUCTIVE | false | Opt-in to register new destructive ops (deletes, unpublish, admin removals). The legacy merge tool is exempt. |
GITBOOK_TRANSPORT | stdio | stdio or http. |
GITBOOK_HTTP_HOST | 127.0.0.1 | HTTP bind host. |
GITBOOK_HTTP_PORT | 3000 | HTTP port. |
GITBOOK_HTTP_AUTH_TOKEN | — | Bearer token required on the HTTP transport. |
GITBOOK_HTTP_MAX_SESSIONS | 256 | Concurrent-session cap; new initializes past it get 503 (1–100000). |
GITBOOK_HTTP_SESSION_TTL_MS | 300000 | Idle-session reaper TTL (1 000–86 400 000). |
GITBOOK_HTTP_SESSION_MAX_LIFETIME_MS | 3600000 | Absolute session lifetime; reaped regardless of activity. |
GITBOOK_HTTP_TRUST_PROXY | false | Trust X-Forwarded-* (enable only behind a trusted reverse proxy). |
GITBOOK_HTTP_ALLOWED_HOSTS | — | Comma-separated hosts appended to the DNS-rebinding allow-list. Required for proxied/non-loopback access (e.g. mcp.example.com). |
GITBOOK_HTTP_ALLOWED_ORIGINS | — | Comma-separated origins appended to the allow-list (e.g. https://mcp.example.com). |
GITBOOK_HTTP_RATE_LIMIT_WINDOW_MS | 60000 | Rate-limit window per client IP. |
GITBOOK_HTTP_RATE_LIMIT_MAX | 120 | Max /mcp requests per window per IP; 0 disables. |
GITBOOK_LOG_LEVEL | info | debug/info/warn/error (logs → stderr). |
GITBOOK_TIMEOUT_MS | 30000 | Per-request timeout (1 000–120 000). |
GITBOOK_MAX_RETRIES | 5 | Max retries on 429/5xx/transport errors (0–10). |
GITBOOK_MAX_CONCURRENCY | 8 | Max concurrent outbound GitBook HTTP requests per instance (1–256). |
CLI flags: --stdio / --http (transport), --read-only, --toolsets <csv|all>, --allow-destructive, --port <n>.
The server covers the full GitBook API (~345 tools), organized into toolsets you enable with GITBOOK_TOOLSETS. By default only core + change-requests are on (~89 tools), so tools/list stays small and tool selection stays accurate. Set GITBOOK_TOOLSETS=all for everything, or list the ones you need (e.g. GITBOOK_TOOLSETS=core,change-requests,sites).
Every tool is one API endpoint with its own input schema. Read tools are always available, write tools need !readOnly, and new destructive tools (deletes, unpublish, admin removals) also need GITBOOK_ALLOW_DESTRUCTIVE=true.
| Toolset | Default | Scope |
|---|---|---|
core | ✅ | Identity, orgs/spaces/pages reads, search, content + import_content. |
change-requests | ✅ | Full CR loop: create, list/diff, reviews, reviewers, comments, merge. |
collections | Collections + collection permissions. | |
sites | Sites, structure, customization, redirects, share links, permissions. | |
site-ai | Ask AI, agent settings, questions, glossary-adjacent AI. | |
site-insights | Analytics/insights, context connections, channels, site MCP servers. | |
integrations | Integration install/configure/token + space integrations. | |
data | OpenAPI specs, translations, glossary, custom fonts, storage. | |
git | Git Sync: import/export, provider installations, repo/branch listing. | |
public | URL→content resolution, subdomains, custom hostnames. | |
org-admin | Org members, teams, invites, SSO, permissions (highest privilege). |
The 11 original tools keep their exact names and live in core / change-requests, so existing setups are unchanged. Per-tool parameters are delivered live via each tool's MCP description + input schema.
Excluded carve-outs: 5 streaming (SSE) AI endpoints, 2 ephemeral PDF-URL generators, and a few trivial auth/heartbeat ops are not exposed as tools (the non-streaming AI equivalents are).
List tools (*_list_*, search) accept a body with limit/page and return nextCursor when more results exist. Typical write flow: create_change_request → import_content (target that CR) → review/diff → merge_change_request.
Pages are exposed as resources at gitbook://{spaceId}/{pageId} (rendered as markdown). Enumeration is intentionally not provided; discover page ids via gitbook_list_pages / gitbook_search, then read by URI.
for local IDE/CLI integrations.
--http): one MCP session per mcp-session-id. Binds to127.0.0.1 and enables DNS-rebinding protection (Host/Origin allow-lists). When GITBOOK_HTTP_AUTH_TOKEN is set, every request needs a constant-time-compared bearer token. Binding to a non-loopback host without an auth token is refused (fail-closed). Sessions are capped and idle-reaped; the /mcp endpoint is per-IP rate-limited. Operational endpoints: GET /healthz /livez /readyz (unauthenticated probes) and GET /metrics (Prometheus; bearer-gated when an auth token is set). Behind a TLS-terminating reverse proxy, set GITBOOK_HTTP_TRUST_PROXY=true and GITBOOK_HTTP_ALLOWED_HOSTS=<your-public-host>: DNS-rebinding protection matches the exact Host header, so a proxied or non-loopback deployment (including the Docker image, which binds 0.0.0.0) must add its public host(s) or every request is rejected with 403 Invalid Host. A Dockerfile is provided.
GITBOOK_TOKEN=… GITBOOK_HTTP_AUTH_TOKEN=… gitbook-mcp --http --port 3000
# → POST/GET/DELETE http://127.0.0.1:3000/mcp · GET /healthz · GET /metricsnpm install
npm run typecheck # tsc on src + test
npm run lint # eslint
npm run format # prettier --write (format:check verifies)
npm test # vitest: unit + protocol + manifest-contract tests
npm run generate:manifest # regenerate src/tools/manifest.ts from @gitbook/api (CI checks drift)
npm run test:coverage # + v8 coverage with an 80% gate
npm run build # tsc → dist/ (+ chmod the bin)CI (.github/workflows/ci.yml) runs npm audit → typecheck → lint → format:check → build → coverage on Node 20 & 22, then asserts a clean git diff. CodeQL and Dependabot run separately.
src/
index.ts launcher: load config → pick transport → graceful shutdown
config.ts zod-validated env + CLI overrides (frozen Config)
logger.ts structured stderr logging + secret redaction + correlation
request-context.ts AsyncLocalStorage requestId/tool (log correlation)
metrics.ts in-process Prometheus registry (served at /metrics)
limiter.ts async concurrency semaphore (outbound rate control)
server.ts createServer(): McpServer factory (tools + resources)
resources.ts gitbook://{spaceId}/{pageId}
version.ts stable SERVER_NAME + runtime SERVER_VERSION (from package.json)
gitbook/
client.ts typed wrapper over @gitbook/api (cursor pagination → {items,nextCursor})
resilient-fetch.ts timeouts + retry/backoff + concurrency cap; injected as the client's fetch
import-url.ts URL guard for server-side-fetch ops (http(s) only, no credentials)
errors.ts HTTP/transport error classification → safe messages
tools/
manifest.ts GENERATED tool surface (one row per API op; source of truth)
toolsets.ts toolset keys + defaults
index.ts manifest-driven registration under toolset/read-only/destructive gates
factory.ts generic handler factory (every non-bespoke op)
bespoke.ts the 11 grandfathered tools (hand-written handlers)
shared.ts ToolContext + result/guard helpers + annotation presets
transports/
stdio.ts http.ts the two transports (http: sessions, rate limit, health, metrics)NodeNext. @gitbook/api0.183 ships a .d.ts that re-exports with extensionless relative specifiers (export * from './client'); under NodeNext those don't resolve and the entire client surface (and the GitBookAPI namespace members) silently disappears. Bundler resolution accepts them, giving full typing with no facade. Internal imports use explicit .js extensions so the emitted ESM runs on Node.
client.orgs (which holds list/search). They are different runtime objects.
format=markdown returns renderedmarkdown; format=document returns GitBook's structured Document JSON.
fetch, AbortSignal.any).~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.