Last updated: Nov 17, 2025, 05:25 PM UTC

DocBuilder MCP Server – Technical Notes

Deep dive on how Sasha wraps @knowcode/doc-builder inside an MCP runtime. Pair this with the operator playbook (docbuilder-mcp-vercel-playbook.md) for day-to-day usage.

1. Runtime Shape

  • Repo location: claudecodeui/integrations/mcp/docbuilder
  • Entry point: server.js (plain ESM, no build step)
  • Launcher: run-docbuilder-mcp.js (Node shebang wrapper that sets DOCBUILDER_PROJECT_ROOT and spawns the server)
  • Transport: Model Context Protocol over stdio (@modelcontextprotocol/sdk/server/stdio)
  • Bundled tools:
    • docbuilder_status – summarises config + directories + auth
    • docbuilder_build – runs doc-builder build with optional clean
    • docbuilder_deploy – toggles auth, runs build (unless skipped), deploys to Vercel
    • docbuilder_set_auth – flips Supabase/public mode without a build

2. Config Loading Strategy

  • The server always resolves the project root from DOCBUILDER_PROJECT_ROOT (default /app inside Docker) and then points to doc-builder.config.js.
  • loadMergedConfig() delegates to @knowcode/doc-builder.loadConfig with a command hint (status, build, or deploy).
  • After load, applyVercelEnvFromConfig() copies deployment.vercel.* into env vars if they’re not set, so downstream CLI calls inherit known project IDs without interactive prompts.
  • All writes go through writeRawConfig(), emitting canonical JSON into doc-builder.config.js; we avoid mutating the merged config object directly to keep CLI + MCP behaviour consistent.
  • Secrets (Vercel token, smoke-test metadata) live in config/mcp/docbuilder.json and are encrypted via the shared encrypt/decrypt helpers. The Settings UI only writes the token when vercelTokenDirty is true, which keeps inadvertent blanks from wiping the stored secret.

3. Authentication Toggle

  • setAuthenticationMode(mode) clones the raw config, updates features.authentication + features.privateDirectoryAuth, and guards Supabase mode by checking auth.supabaseUrl and auth.supabaseAnonKey.
  • When the MCP tool flips the mode it persists the updated config to disk, so subsequent CLI/manual invocations see the same state.
  • The doc-builder build step will generate js/auth.js, login.html, logout.html automatically when Supabase auth is enabled; the MCP server doesn’t touch those assets directly.

4. Vercel Project Handling

  • deployment.vercel in doc-builder.config.js stores projectName, projectId, orgId, teamSlug.
  • productionUrl captures the canonical live URL (shown in status responses and tool output).
  • The MCP server snapshots html/.vercel/project.json before destructive operations (clean=true builds) and restores it afterwards. That file contains the Vercel IDs the CLI uses when deploying.
  • Environment requirements at runtime:
    • VERCEL_TOKEN – always required
    • Optional overrides: VERCEL_PROJECT_ID, VERCEL_ORG_ID, VERCEL_TEAM_SLUG, VERCEL_PROJECT_NAME (automatically set from config if unset)
    • DOCBUILDER_PRODUCTION_URL gets set from config to keep the deploy response consistent.

5. Docker Integration

  • Dockerfile.sliplane copies the integration folder into the build stage, runs npm ci && npm prune --omit=dev, then copies the runtime directory alongside the executable wrapper. The container sets DOCBUILDER_CONFIG_PATH=doc-builder.config.cjs so Node treats the published configuration as CommonJS even though the app default is ESM.
  • Runtime container exports:
    • DOCBUILDER_PROJECT_ROOT=/app
    • DOCBUILDER_CONFIG_PATH=doc-builder.config.js
    • The docs/, html/, and doc-builder.config.js trees so builds/deploys run against the same content as the local repo.
  • Claude CLI is pre-installed globally within the image, so registering the MCP server inside the container just needs the standard claude mcp add command with --env VERCEL_TOKEN=….

6. Command Flow (Happy Path)

  1. Host issues JSON-RPC request (e.g., docbuilder_deploy).
  2. Server optionally updates config (docbuilder_set_auth, docbuilder_deploy with password mode).
  3. If a build is required:
    • Output directory cleaned (on clean=true)
    • Build executed via docBuilder.buildDocs
    • .vercel/project.json restored if clean removed it
  4. Deploy validated (assertVercelToken), then docBuilder.deploy runs (respecting prod flag).
  5. Response includes text summary for UI + structured payload (deploy URLs, auth status, file counts, timestamps).

7. Error Handling Notes

  • Missing Supabase credentials throws before touching the config, so we don’t end up in a half-enabled state.
  • If VERCEL_TOKEN is absent we fail fast with a targeted error message.
  • Underlying doc-builder exceptions bubble up (e.g., Vercel misconfiguration); the MCP server surfaces them verbatim so the UI can present actionable guidance.
  • Build/deploy commands run in the project root; any non-fatal stderr logging should go to stderr (stdout corruption would break MCP messaging).

8. Extensibility Hooks

  • Add new tools by calling mcpServer.registerTool in server.js; ensure input schemas use zod for validation and respond with { content, structuredContent }.
  • For richer logging/telemetry, wrap the doc-builder calls with additional instrumentation before returning.
  • If we introduce additional per-env configs, extend applyVercelEnvFromConfig() (or create similar helper) so the MCP runtime mirrors CLI expectations.
  • Keep Docker build parity (install/build/prune) any time dependencies change; otherwise the runtime image will lack required modules.

9. Related References

  • Operator playbook: docs/technical/docbuilder-mcp-vercel-playbook.md
  • MCP onboarding runbook: docs-developer/tech/add-new-mcp-server.md
  • Original doc-builder package docs: node_modules/@knowcode/doc-builder/README.md

This document lives alongside the playbook so engineers can understand the plumbing before making protocol or deployment changes. Update both whenever the tool surface area or config contract changes.