MCP server by tokenscompany
pocketbase-mcp
Remote MCP server that connects any MCP client to a PocketBase instance over stateless HTTP.
Quick start
Use the hosted instance at https://pocketbase.tokenscompany.co/mcp or self-host your own.
Install with AI agent
Copy and paste this prompt into your AI agent (Claude Code, Cursor, Windsurf, etc.):
Install the PocketBase MCP server. The MCP endpoint is https://pocketbase.tokenscompany.co/mcp and the transport type is http (NOT sse). It requires X-PB-URL set to my PocketBase instance URL and either X-PB-Email + X-PB-Password (superuser credentials) or X-PB-Token (superuser auth token). Add it to my project MCP config with type "http". Then fetch https://raw.githubusercontent.com/tokenscompany/pocketbase-mcp/main/SKILL.md and save it to my project's agent instructions so you always know how to use the PocketBase tools.
Claude Code
claude mcp add --transport http pocketbase https://pocketbase.tokenscompany.co/mcp \
--header "X-PB-URL: https://your-pocketbase.example.com" \
--header "X-PB-Email: admin@example.com" \
--header "X-PB-Password: your-password"
Or add to .mcp.json in your project root:
{
"mcpServers": {
"pocketbase": {
"type": "http",
"url": "https://pocketbase.tokenscompany.co/mcp",
"headers": {
"X-PB-URL": "${PB_URL}",
"X-PB-Email": "${PB_EMAIL}",
"X-PB-Password": "${PB_PASSWORD}"
}
}
}
}
Claude Code expands ${VAR} from your environment, so set PB_URL, PB_EMAIL, and PB_PASSWORD in your shell or .env.
Cursor
Add to ~/.cursor/mcp.json:
{
"mcpServers": {
"pocketbase": {
"url": "https://pocketbase.tokenscompany.co/mcp",
"headers": {
"X-PB-URL": "https://your-pocketbase.example.com",
"X-PB-Email": "admin@example.com",
"X-PB-Password": "your-password"
}
}
}
}
OpenCode
Add to opencode.json in your project root:
{
"mcp": {
"pocketbase": {
"type": "remote",
"url": "https://pocketbase.tokenscompany.co/mcp",
"headers": {
"X-PB-URL": "https://your-pocketbase.example.com",
"X-PB-Email": "admin@example.com",
"X-PB-Password": "your-password"
},
"enabled": true
}
}
}
Self-hosting
Bun
bun install
bun run src/index.ts
The server listens on PORT (default 3000).
Docker (GHCR)
docker pull ghcr.io/tokenscompany/pocketbase-mcp:latest
docker run -p 3000:3000 ghcr.io/tokenscompany/pocketbase-mcp:latest
Or build locally:
docker build -t pocketbase-mcp .
docker run -p 3000:3000 pocketbase-mcp
Verifying the image
Every image published to GHCR includes SLSA provenance attestation. You can verify that an image was built from this repository:
gh attestation verify oci://ghcr.io/tokenscompany/pocketbase-mcp:latest \
--owner tokenscompany
Authentication
Every request to POST /mcp must include X-PB-URL and one of two auth methods:
Option 1: Email + Password (recommended)
| Header | Description |
|---|---|
| X-PB-URL | Base URL of your PocketBase instance |
| X-PB-Email | Superuser email |
| X-PB-Password | Superuser password |
The server authenticates against PocketBase on each request. No manual token management needed.
Option 2: Token
| Header | Description |
|---|---|
| X-PB-URL | Base URL of your PocketBase instance |
| X-PB-Token | Superuser auth token |
To get a token manually:
curl -X POST https://your-pb.example.com/api/admins/auth-with-password \
-H 'Content-Type: application/json' \
-d '{"identity":"admin@example.com","password":"your-password"}'
The token field in the response is your X-PB-Token. If both token and email+password are provided, the token takes priority.
Tools
| Tool | Description |
|---|---|
| pb_health | PocketBase health check |
| pb_list_collections | List all collections with full field schemas |
| pb_get_collection_schema | Get a single collection's full schema |
| pb_create_collection | Create a new collection |
| pb_update_collection | Update a collection's schema or rules |
| pb_delete_collection | Delete a collection |
| pb_import_collections | Bulk import/overwrite collection schemas |
| pb_list_records | List/search records in a collection |
| pb_get_record | Get a single record by ID |
| pb_create_record | Create a new record |
| pb_update_record | Update an existing record |
| pb_delete_record | Delete a record by ID |
| pb_list_backups | List available backups |
| pb_create_backup | Create a new backup |
| pb_delete_backup | Delete a backup by key |
| pb_get_file_url | Get download URL for a file field |
| pb_get_settings | Get app settings |
| pb_update_settings | Update app settings |
| pb_list_logs | Query request logs |
Resources
| Resource | URI | Description |
|---|---|---|
| schema | pocketbase://schema | All collection schemas as JSON |
Security & Privacy
This server is fully stateless — it does not store, log, or retain any of your data:
- No database, no disk writes — each request creates a fresh MCP server and transport in memory, processes it, and discards everything. Nothing is written to disk.
- No credential storage — your
X-PB-URL,X-PB-Token,X-PB-Email, andX-PB-Passwordheaders are used for the duration of the request and never persisted, cached, or logged. - No telemetry or analytics — the server collects zero usage data. No third-party services are contacted.
- No sessions — there are no cookies, no session IDs, and no server-side state between requests.
- Open source — the entire codebase is MIT-licensed. Every Docker image includes SLSA provenance attestation, so you can verify it was built directly from this repository with no modifications.
- Self-host it yourself — for maximum control, run your own instance. The server is a single container with no external dependencies beyond your PocketBase instance.
Hardening
When hosting a public instance, the server includes several additional measures:
-
SSRF protection —
X-PB-URLis validated: onlyhttp/httpsschemes are allowed, and hostnames that resolve to private/reserved IP ranges (127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,169.254.0.0/16,::1,fc00::/7,fe80::/10) are rejected. -
Rate limiting — in-memory token-bucket per IP. Configurable via environment variables:
| Variable | Default | Description | |---|---|---| |
RATE_LIMIT_RPM|60| Requests per minute per IP | |RATE_LIMIT_BURST|10| Max burst size | -
CORS —
Access-Control-Allow-Origin: *with preflight support on/mcp. -
Body size limit — requests larger than 1 MB are rejected with
413.
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /mcp | MCP endpoint (stateless, JSON responses) |
| GET | /health | Health check |
Troubleshooting
"Failed to reconnect" error
Your MCP client config likely uses "type": "sse". This server uses stateless streamable HTTP, not Server-Sent Events. Change the transport type to "http":
{
"mcpServers": {
"pocketbase": {
"type": "http",
...
}
}
}
For Claude Code CLI, use --transport http when adding:
claude mcp add --transport http pocketbase https://pocketbase.tokenscompany.co/mcp ...