Skip to main content
Glama

gitbook-mcp

A Model Context Protocol 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.

  • 11 tools — 7 read + 4 change-request write (write tools are hidden in read-only mode).

  • Resources — pages addressable as gitbook://{spaceId}/{pageId}.

  • Two transports — stdio (local) and streamable HTTP (multi-session, bearer-gated).

  • Resilient — request timeouts, bounded retries with full-jitter backoff, rate-limit aware.

  • Safe — read-only mode, env-only token, secret redaction, localhost-bound HTTP.

Status: the read path and the change-request write workflow are complete and tested (103 unit/protocol tests). The stdio transport is ready for local IDE/CLI use; the HTTP transport is hardened for hosted use — bearer auth, DNS-rebinding protection, a session cap + idle reaper, per-IP rate limiting, health/readiness probes, and Prometheus metrics. To publish: push to github.com/HoYongJin/gitbook-mcp, ensure your npm account owns the @hoyongjin scope, then create a GitHub release (CI publishes to npm with provenance).


⚠️ What GitBook's API can and cannot write

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:

  1. Change requests — open a draft (gitbook_create_change_request), review, then gitbook_merge_change_request to publish.

  2. Content importgitbook_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.

  3. Git Sync — for fine-grained, paragraph-level authoring, connect the space to a Git repo and edit markdown there. (Out of scope for this server; it is the right path if you need precise prose edits.)

So this server is read-rich with a coarse, review-gated write path. It cannot rewrite a specific paragraph via the API.


Related MCP server: Notion MCP Server

Install

# 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-mcp

The package is scoped to @hoyongjin/gitbook-mcp (the unscoped gitbook-mcp on npm belongs to a different project). Make sure your npm account owns the @hoyongjin scope before publishing.

Create a token at GitBook → Settings → Developer → Personal access tokens.

Configure in your MCP client

Claude Code

# 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.

Configuration

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 tools when true.

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, --port <n>.

Tools

Tool

R/W

Purpose

gitbook_whoami

read

Authenticated user.

gitbook_list_orgs

read

Organizations you can access.

gitbook_list_spaces

read

Spaces in an org.

gitbook_get_space

read

One space by id.

gitbook_list_pages

read

Page tree of a space (not paginated).

gitbook_get_page

read

A page as markdown (default) or structured document.

gitbook_search

read

Full-text search (org- or space-scoped; exactly one).

gitbook_create_change_request

write

Open a draft change request.

gitbook_import_content

write

Import a URL into a space/change-request (AI-enhanced).

gitbook_comment_change_request

write

Post a markdown comment on a change request.

gitbook_merge_change_request

write · destructive

Publish a change request into the live space.

Tools that paginate (list_orgs, list_spaces, search) accept limit + a cursor, and return nextCursor when more results exist — pass it back to fetch the next page.

Typical write flow: create_change_requestimport_content (target that CR) → review in GitBook → merge_change_request.

Resources

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.

Transports

  • stdio (default): one server per process; the token stays in-process. Best for local IDE/CLI integrations.

  • streamable HTTP (--http): one MCP session per mcp-session-id. Binds to 127.0.0.1, enables DNS-rebinding protection (Host/Origin allow-lists), and — when GITBOOK_HTTP_AUTH_TOKEN is set — requires a constant-time-compared bearer token on every request. 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. See SECURITY.md.

GITBOOK_TOKEN=… GITBOOK_HTTP_AUTH_TOKEN=… gitbook-mcp --http --port 3000
# → POST/GET/DELETE http://127.0.0.1:3000/mcp   ·   GET /healthz   ·   GET /metrics

Development

npm install
npm run typecheck   # tsc on src + test
npm run lint        # eslint
npm run format      # prettier --write   (format:check verifies)
npm test            # vitest — 103 tests across 12 files
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.

Architecture

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     SSRF guard for import sourceUrl (http(s) only, no credentials)
    errors.ts         HTTP/transport error classification → safe messages
  tools/
    read.ts write.ts  one registrar each; index.ts gates writes by read-only mode
    shared.ts         ToolContext + result/guard helpers + annotation presets
  transports/
    stdio.ts http.ts  the two transports (http: sessions, rate limit, health, metrics)

For agent-facing contributor conventions and the dependency gotchas below, see CLAUDE.md.

Notes / gotchas (pinned to @gitbook/api 0.183.0)

  • tsconfig uses moduleResolution: "Bundler", not NodeNext. @gitbook/api 0.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.

  • Import runs live under the singular client.org namespace, not the plural client.orgs (which holds list/search). They are different runtime objects.

  • gitbook_get_page markdown vs document: format=markdown returns rendered markdown; format=document returns GitBook's structured Document JSON.

  • Node ≥ 20 (global fetch, AbortSignal.any).

License

MIT

Install Server
A
license - permissive license
B
quality
B
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
3Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/HoYongJin/gitbook-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server