Skip to content

Production Setup Guide

Updated: 23/03/2026

Step-by-step guide for deploying Knowledge Hub to production.

  • Vercel Pro account ($20/month) — required for function durations > 10s
  • Supabase account with capacity for a new project
  • GitHub repository access (private, ai-solution-hub/knowledge-hub)
  • API keys: Anthropic (Claude), OpenAI (embeddings)
  • Domain name (optional — Vercel provides a default URL)
  • Current deployment: https://knowledge-hub-seven-kappa.vercel.app
  1. Go to supabase.com/dashboard
  2. Click New Project
  3. Select your organisation
  4. Configure:
    • Name: knowledge-hub-production (or client-specific name)
    • Database password: Generate a strong password and store securely
    • Region: London (eu-west-2) — closest to UK clients
    • Plan: Free tier is sufficient for pilot; upgrade if needed
  5. Wait for project to initialise (~2 minutes)
  6. Note the Project ID, URL, and Anon Key from Settings > API
  7. Note the Service Role Key from Settings > API (needed for batch scripts and MCP server)

Reference project: rovrymhhffssilaftdwd (eu-west-2, London)

From your local machine with the Supabase CLI (/opt/homebrew/bin/supabase):

Terminal window
# Link to the new production project
/opt/homebrew/bin/supabase link --project-ref <PROJECT_ID>
# Push all migrations
/opt/homebrew/bin/supabase db push
# Verify migration count matches
/opt/homebrew/bin/supabase migration list

Expected: 92 migration files (as of S108). Verify with supabase migration list that all migrations have been applied successfully.

Note: The Supabase CLI may occasionally fail with TLS certificate errors. Use the Supabase MCP apply_migration tool as a fallback.

RLS requires a user_roles entry before any user can write data. New users who sign up via Supabase Auth are automatically assigned a viewer role (via the auto_create_viewer_role trigger), but the first admin must be seeded manually.

  1. Create a user via Supabase Auth (Dashboard > Authentication > Users > Add User)
  2. Note the user’s UUID
  3. Insert the admin role via SQL Editor:
INSERT INTO user_roles (user_id, role)
VALUES ('<USER_UUID>', 'admin');

The taxonomy is DB-driven via taxonomy_domains and taxonomy_subtopics tables. The application uses TaxonomyProvider (React context) to serve taxonomy data to the frontend. A hardcoded fallback exists in lib/taxonomy.ts for the Python pipeline.

-- Example: Insert domains for a bid management client
INSERT INTO taxonomy_domains (name, description, colour, display_order) VALUES
('Technical', 'Technical capabilities and methodologies', '#4A90D9', 0),
('Commercial', 'Pricing, contracts, and commercial terms', '#D4A574', 1),
('Compliance', 'Regulatory compliance and certifications', '#7AB648', 2),
('Case Studies', 'Past project evidence and references', '#9B8EC4', 3),
('Company', 'Company information and credentials', '#E8976C', 4);
-- Insert subtopics under each domain
INSERT INTO taxonomy_subtopics (domain_id, name, description, display_order)
SELECT d.id, s.name, s.description, s.display_order
FROM taxonomy_domains d
CROSS JOIN (VALUES
('Data Security', 'Information security policies and practices', 0),
('Cloud Infrastructure', 'Cloud hosting, platforms, and services', 1),
('Software Development', 'Development methodologies and tools', 2)
) AS s(name, description, display_order)
WHERE d.name = 'Technical';

Also seed the layer_vocabulary table if using content layers:

INSERT INTO layer_vocabulary (name, description, display_order) VALUES
('Fact', 'Verifiable factual claims', 0),
('Evidence', 'Proof, case studies, references', 1),
('Method', 'Processes, methodologies, approaches', 2),
('Policy', 'Rules, guidelines, standards', 3),
('Narrative', 'Persuasive or contextual writing', 4);
Terminal window
python3 scripts/import_bid_library.py \
.planning/client-documentation/ \
--batch-tag "initial-import"

Note: Ensure client .docx files have Track Changes accepted before import. The import_bid_library.py script uses open_document_safe() from scripts/docx_utils.py which resolves tracked changes via pandoc.

Terminal window
python3 scripts/ingest.py https://client-website.com
Terminal window
python3 scripts/ingest_markdown.py docs/ \
--tag "internal-docs" \
--author "Client Name"

After import, content is automatically classified, summarised, embedded, and scored. Verify via:

Terminal window
# Semantic search to confirm embeddings work
bun run scripts/kb-search.ts "project management" --limit 5
# Batch generate AI summaries for items without one
bun run scripts/batch_generate_summaries.ts
  1. Go to vercel.com/new
  2. Import ai-solution-hub/knowledge-hub from GitHub
  3. Framework: Next.js (auto-detected)
  4. Build command: bun run build (configured in vercel.json)
  5. Install command: bun install --frozen-lockfile (configured in vercel.json)
  6. Region: London (lhr1) — configured in vercel.json

In Vercel Dashboard > Project > Settings > Environment Variables:

VariableValueNotes
NEXT_PUBLIC_SUPABASE_URLhttps://<project-id>.supabase.coFrom step 1
NEXT_PUBLIC_SUPABASE_ANON_KEYeyJ...From step 1
SUPABASE_URLhttps://<project-id>.supabase.coFor Python scripts
SUPABASE_ANON_KEYeyJ...For Python scripts
SUPABASE_SECRET_KEYService role keyFor batch scripts and MCP server
ANTHROPIC_API_KEYsk-ant-...Claude API key
OPENAI_API_KEYsk-...OpenAI embeddings (text-embedding-3-large)
AI_SUMMARY_MODELclaude-sonnet-4-6Optional, defaults to Sonnet
CRON_SECRETRandom secretVercel cron authentication
NEXT_PUBLIC_SENTRY_DSNSentry DSNOptional — Sentry error tracking
SENTRY_ORGSentry org slugOptional — required with DSN
SENTRY_PROJECTSentry project slugOptional — required with DSN
SENTRY_AUTH_TOKENSentry auth tokenOptional — enables source maps
Terminal window
# Push to main triggers automatic deployment
git push origin main

Or trigger a manual deployment from the Vercel dashboard.

The following cron jobs are configured in vercel.json and run automatically:

CronSchedulePurpose
/api/cron/freshness-transitions03:15 dailyTransition content freshness states
/api/cron/classification-quality04:00 SundaysAudit classification quality
/api/cron/coverage-alerts05:00 MondaysAlert on coverage gaps
/api/cron/content-gaps05:30 MondaysIdentify content gaps
/api/cron/quality-score05:00 SundaysRecalculate quality scores

All times are UTC.

Key function timeout overrides in vercel.json:

FunctionMax Duration
Summary generation30s
Digest generation60s
Question extraction, matching, drafting120s
CopilotKit120s
Classification quality cron120s
Quality score cron50s
Terminal window
curl https://<your-domain>/api/health
# Expected: {"status":"ok","supabase":true,"env":true,"timestamp":"..."}
  1. Visit the login page — should show Supabase Auth UI
  2. Log in with the admin user created in step 3
  3. Dashboard — should show content health strip, active bids, Reorient Me section
  4. Browse page — should show imported content with quality score badges
  5. Search — should return semantic results with similarity scores
  6. Create a test bid — verify the full flow:
    • Create bid
    • Upload tender document
    • Extract questions
    • Match KB content
    • Draft a response
    • Export to Word/Excel
  7. Q&A Library — should show imported Q&A pairs
  8. Coverage dashboard — should show domain coverage overview
  9. Review queue — should show items pending review
  10. MCP server — verify at /.well-known/oauth-protected-resource
  • robots.txt returns Disallow: / (verified in public/robots.txt)
  • Security headers present (configured in vercel.json):
    • X-Content-Type-Options: nosniff
    • X-Frame-Options: DENY
    • Strict-Transport-Security with includeSubDomains; preload
    • Content-Security-Policy restricting scripts, connections, frames
    • Referrer-Policy: strict-origin-when-cross-origin
    • Permissions-Policy denying camera, microphone, geolocation, payment
  • All non-API routes require authentication (via proxy.ts)
  • Public routes: /login, /auth/callback, /oauth/consent, /.well-known

The MCP server exposes 41 tools, 12 resources, and 5 prompts for Claude Desktop and Claude.ai integration. See docs/generated/mcp-inventory.md for the canonical current counts.

  • Endpoint: https://<your-domain>/api/mcp/mcp (Streamable HTTP transport)
  • Auth: OAuth 2.0 — discovery at /.well-known/oauth-protected-resource
  • Plugin: The Knowledge Hub plugin bundle is committed at lib/mcp/plugin-bundle.ts. Run bun run build:plugin after changing plugin files, or bun run sync:taxonomy to also refresh the classification prompt and taxonomy snapshot before rebuilding.

MCP App UIs live in mcp-apps/ and are built as inline single-file bundles for deployment:

Terminal window
bun run build:mcp-apps

This generates the app bundles that are served from Vercel.

For the client pilot, invite users via the admin settings:

  1. Navigate to /settings > Team section
  2. Click “Invite User”
  3. Enter email address
  4. Assign role (editor for most users, admin for client leads)

The invited user will receive an email with a magic link to set up their account. New users are auto-assigned a viewer role; admins can upgrade roles from the Team section.

Roles:

  • Viewer: Read-only access to all content
  • Editor: Can create/edit content, manage bids, run reviews
  • Admin: Full access including team management, taxonomy, governance settings
  • Vercel Dashboard: Deployment logs, function logs, function duration metrics
  • Sentry: Error tracking, performance monitoring (if configured)
  • Vercel Analytics: Page view analytics (via @vercel/analytics)
  • /api/health: Automated health check endpoint
  • Supabase Dashboard: Table data, query performance, storage usage
  • Connection pooling: Enabled by default on Supabase
  • pgvector HNSW indexes: Monitor via pg_stat_user_indexes
  • Schema: 30 tables, 92 migrations — see docs/reference/SCHEMA-QUICK-REFERENCE.md

Check Vercel function logs for cron execution. Each cron endpoint validates the CRON_SECRET header and returns structured JSON responses.

ServicePlanCostNotes
VercelPro$20/monthRequired for function durations > 10s and cron jobs
SupabaseFree$0/month500 MB database, 1 GB storage
AnthropicPay-per-use~$0.20/questionSonnet for analysis, Opus for complex drafting
OpenAIPay-per-use~$0.01/embeddingtext-embedding-3-large (1024-dim via Matryoshka)
SentryFree$0/monthOptional — 5K errors/month on free tier

Estimated pilot cost: $20/month (Vercel) + API usage (variable, ~$5-20/bid depending on question count).