ContextMCP/ContextMCP

Deployment

Deploy ContextMCP to production

ContextMCP runs on Cloudflare Workers for low-latency edge deployment.

Cloudflare Workers

Prerequisites

  • Cloudflare account (free tier works)
  • Wrangler CLI installed: npm install -g wrangler
  • Indexed documentation (run npm run reindex first)

Configure

Edit cloudflare-worker/wrangler.jsonc:

{
  "name": "contextmcp",
  "compatibility_date": "2024-01-01",
  "vars": {
    "SERVER_NAME": "my-company-docs",
    "SERVER_DESCRIPTION": "Documentation search for My Company",
  },
}

Set Secrets

cd cloudflare-worker
wrangler secret put OPENAI_API_KEY
wrangler secret put PINECONE_API_KEY
wrangler secret put API_KEY  # Optional: for authenticated access

Deploy

npm run deploy

Your server is live at: https://contextmcp.your-subdomain.workers.dev

Verify

# Health check
curl https://your-worker.workers.dev/health

# Test search
curl "https://your-worker.workers.dev/search?query=authentication&limit=3"

Custom Domain

Add a custom domain in wrangler.jsonc:

{
  "routes": [{ "pattern": "mcp.yourdomain.com", "custom_domain": true }],
}

Local Development

For testing locally without deploying:

cd cloudflare-worker
npm run dev

Server runs at http://localhost:8787.

Auto-Reindex with GitHub Actions

Keep your index fresh by reindexing on every push to main:

# .github/workflows/reindex.yml
name: Reindex Documentation

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'
      - 'content/**'

jobs:
  reindex:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Reindex
        run: npm run reindex
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          PINECONE_API_KEY: ${{ secrets.PINECONE_API_KEY }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Incremental Reindex

Full reindexing re-embeds every chunk on every run, which is slow and costly for large docs. Use --incremental to embed and upload only the chunks that changed since the last run:

npm run reindex -- --incremental

How it works:

  • After each run, a manifest (data/reindex-manifest.json) records a content hash for every chunk.
  • On the next incremental run, ContextMCP diffs the freshly parsed chunks against the manifest: new/changed chunks are embedded and upserted, removed chunks are deleted from the vector store, and unchanged chunks are skipped.
  • The manifest is written after every non-dry run, so a normal full reindex also seeds it.

To make incremental runs work in CI, persist data/reindex-manifest.json between runs (commit it, or use an actions cache).

Important: actions/cache only writes a new entry on a cache miss. With a constant key, the manifest is saved once and never updated again, so every incremental run would diff against that first, now-stale manifest forever. Use a rotating key (unique per run) plus restore-keys so each run restores the latest manifest and saves a fresh one:

- name: Restore reindex manifest
  uses: actions/cache@v4
  with:
    path: data/reindex-manifest.json
    # Unique per run -> always a miss -> the updated manifest is always saved.
    key: reindex-manifest-${{ github.run_id }}
    # Falls back to the most recent previous manifest on restore.
    restore-keys: |
      reindex-manifest-

- name: Reindex (incremental)
  run: npm run reindex -- --incremental
  env:
    OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
    PINECONE_API_KEY: ${{ secrets.PINECONE_API_KEY }}

Alternatively, commit data/reindex-manifest.json to the repo after each run — simpler and fully deterministic, at the cost of a commit per reindex.

--incremental covers all sources, so it can't be combined with --source.

Scheduled Reindex

For sources that change externally, add a cron schedule:

on:
  schedule:
    - cron: '0 2 * * *' # Daily at 2 AM UTC
  workflow_dispatch: # Manual trigger

Environment Variables

VariableRequiredDescription
OPENAI_API_KEYYesFor generating embeddings
PINECONE_API_KEYYesFor vector storage
GITHUB_TOKENFor private reposGitHub access token

Troubleshooting

"Worker failed to deploy"

Check that all required secrets are set:

wrangler secret list
  1. Verify reindex completed: check for errors in npm run reindex
  2. Confirm vectors exist in Pinecone dashboard
  3. Try a broader query

"Timeout errors"

Cloudflare Workers have a 30s CPU limit. If indexing large docs, ensure chunking produces reasonable sizes.