Deployment Guide
Run Pathfinder anywhere — single container, full stack, or bare metal.
Docker (single container, bash-only)
The quickest Docker setup. No database needed — agents explore docs with shell commands only.
This mounts your config and local docs into the container. Agents get read-only access to your documentation via bash tools.
Docker Compose (full stack)
For semantic search, you need Postgres with pgvector. The production
docker-compose.yml sets up everything:
Create a .env file with your secrets, then start:
Persistent volume required for workspaces
Without a persistent volume mounted at /data, agent
workspaces are lost on every container restart. If you use
workspaces, always mount a volume. The
workspaces volume in the compose file above handles
this.
Railway
Deploy to Railway with a Postgres plugin and persistent volume:
- Create a new project on Railway and add a PostgreSQL database (use the pgvector template if available).
-
Add a new service from the Pathfinder GitHub repo or Docker image
(
ghcr.io/copilotkit/pathfinder:latest). -
Set environment variables:
DATABASE_URL(from Railway's Postgres),OPENAI_API_KEY,GITHUB_TOKEN(if needed). -
Add a persistent volume mounted at
/datafor workspace storage. -
Set
WORKSPACE_DIR=/data/workspacesin the service environment. - Deploy. The first boot auto-indexes your configured sources.
Generic VPS
Run Pathfinder directly on any Linux server with Node.js 20+.
systemd service
nginx reverse proxy
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL |
For search tools | - | PostgreSQL connection string (with pgvector) |
MCP_JWT_SECRET |
Required in production | - |
HMAC secret for signing OAuth access/refresh tokens. Generate
with openssl rand -hex 32. Rotating this
invalidates all issued tokens — clients will re-authenticate
transparently. In any non-production environment (any
NODE_ENV other than production) a
random secret is generated per process and logged as a warning.
|
PATHFINDER_CONSENT_HMAC_KEY |
Required in production | - |
HMAC secret for signing the consent-screen nonce on the OAuth
/authorize → /authorize/consent flow.
Generate with openssl rand -hex 32. Comma-separated
values are accepted for rotation — the first key signs, all keys
verify; rotate by prepending a new key. Rotating invalidates
only in-flight consent nonces (10-minute TTL) — issued
access/refresh tokens are unaffected. In any non-production
environment (any NODE_ENV other than
production) a random ephemeral key is generated per
process and logged as a warning.
|
OPENAI_API_KEY |
When embedding.provider is "openai" (default) | - | OpenAI API key for computing embeddings. Not needed for ollama or local providers. |
GITHUB_TOKEN |
For private repos | - | GitHub PAT for cloning private repositories |
GITHUB_WEBHOOK_SECRET |
For webhooks | - | Secret for validating GitHub webhook payloads |
SLACK_BOT_TOKEN |
When slack sources configured | - | Slack bot OAuth token (xoxb-...) |
SLACK_SIGNING_SECRET |
When using emoji-trigger | - | For Slack webhook signature verification |
DISCORD_BOT_TOKEN |
When discord sources configured | - | Discord bot token |
DISCORD_PUBLIC_KEY |
When discord sources configured | - | For Discord webhook Ed25519 verification |
NOTION_TOKEN |
When notion sources configured | - | Notion internal integration token |
PORT |
No | 3001 |
HTTP port the server listens on |
PATHFINDER_CONFIG |
No | pathfinder.yaml |
Path to the config file |
WORKSPACE_DIR |
No | /tmp/pathfinder-workspaces |
Directory for agent workspace storage |
NODE_ENV |
No | development |
Set to production for deployed instances |
LOG_LEVEL |
No | info |
Logging verbosity (debug, info, warn, error) |
CLONE_DIR |
No | /tmp/mcp-repos |
Directory for git repo clones |
ANALYTICS_TOKEN |
For privileged surfaces | - |
Shared admin-access bearer token for all privileged surfaces —
analytics (/api/analytics/*), Atlas ratification
(/api/atlas/*), and admin ops
(/admin/*). See
Admin control surface.
|
MCP_JWT_SECRET must be set in production
MCP_JWT_SECRET MUST be set before
NODE_ENV=production — the server will throw on startup
if it's missing. See
Authentication for how the
OAuth flow uses this secret.
Optional dependencies
Some features require extra packages that are not bundled by default. Install only the ones your config needs:
| Package | When required | Install |
|---|---|---|
pdf-parse |
Any source has type: document with
*.pdf file patterns
|
npm install pdf-parse |
mammoth |
Any source has type: document with
*.docx file patterns
|
npm install mammoth |
@xenova/transformers |
embedding.provider is local |
npm install @xenova/transformers |
Run pathfinder validate to detect missing optional
dependencies and get install instructions.
Docker images: optional peer deps are not bundled
The default ghcr.io/copilotkit/pathfinder image (tags
:latest / :<version>) is built with
npm ci --omit=dev, which intentionally omits these
optional peer dependencies to keep the image lean. For
local embeddings (embedding.provider: local —
transformers.js, the zero-API-key in-process provider), use the
prebuilt
ghcr.io/copilotkit/pathfinder:latest-local image (also
tagged :<version>-local), which ships
@xenova/transformers preinstalled. If you run the
default image with embedding.provider: local and the
peer is absent, the server now
fails loudly at startup with an actionable message
(rather than booting and throwing later at first embed). For
type: document sources (PDF/DOCX), or to bake any
optional peer into a derived image, uncomment the matching
RUN npm install … line in the
Dockerfile
and rebuild (the -local variant is built from the same
Dockerfile via
--build-arg INCLUDE_LOCAL_EMBEDDINGS=true).
Health endpoint
Pathfinder exposes GET /health for monitoring. It returns
JSON with uptime, indexing status, chunk counts per source, and index
state (last indexed time, commit SHA, errors). Use it for load
balancer health checks and deployment verification.
Webhook URLs
GitHub: Set your GitHub webhook's Payload URL to
https://your-domain/webhooks/github.
Slack: Set your Slack app's Event Subscriptions
Request URL to https://your-domain/webhooks/slack.
Discord: Set your Discord application's Interactions
Endpoint URL to https://your-domain/webhooks/discord.
Admin control surface
Pathfinder exposes an authenticated control plane for operational tasks that would otherwise require database surgery and a redeploy — forcing a reindex, inspecting index state, and so on.
Authentication
All privileged surfaces — analytics (/api/analytics/*),
Atlas ratification (/api/atlas/*), and admin ops
(/admin/*) — share one admin-access
bearer token: the ANALYTICS_TOKEN environment variable.
Authenticate every request with an
Authorization: Bearer $ANALYTICS_TOKEN header.
- 401 Unauthorized — the token is missing or does not match.
-
503 Service Unavailable — no token is configured.
These surfaces fail closed: with no
ANALYTICS_TOKENset, they reject every request rather than running unauthenticated.
Force a reindex — POST /admin/reindex
Queues an indexing job and returns 202 Accepted. The body selects the scope:
-
{ "scope": "full" }— reindex every configured source. -
{ "scope": "source", "source": "<configured-source-name>" }— reindex a single named source. -
{ "scope": "repo", "repo": "<configured-repo-url>" }— incrementally reindex a single git-backed source by repo URL.
An unknown source name or repo URL returns 400 Bad Request so a typo fails loud instead of silently no-op-ing.
Inspect index state — GET /admin/index-stats
Returns 200 OK with current index statistics (a
POST /admin/index-stats alias is also accepted):
The response body has the shape:
Volume Mounts
What you mount depends on your source configuration:
-
Local docs — If your source uses a
pathwithout arepo, you need to mount the docs directory into the container (e.g.,-v ./docs:/app/docs:ro). -
Git-backed sources — If your source specifies a
repo, Pathfinder clones it automatically. No volume mount needed for the docs themselves. -
Config file — Always mount your
pathfinder.yaml(e.g.,-v ./pathfinder.yaml:/app/pathfinder.yaml:ro). -
Workspace persistence — If agents use writable
workspaces (
workspace: truein bash tools), mount a persistent volume at theWORKSPACE_DIRpath. Without this, workspace files are lost on restart. - Database persistence — The Postgres data directory should always be on a persistent volume.