pocketbase-mcp
Provides tools for interacting with PocketBase, enabling AI agents to manage collections and records, query data, handle file operations, authenticate users, and inspect server status.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@pocketbase-mcpshow me the schema for the users collection"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
pocketbase-mcp
An MCP server that exposes PocketBase through 13 intent-first tools rather than ~50 endpoint wrappers.
Install
Requires Python >=3.11 and uv.
uv syncuv sync installs the pypocketbase client from its Git repository.
Related MCP server: PocketBase MCP Server
Environment Variables
Variable | Default | Description |
|
| PocketBase instance URL |
| (none) | Superuser email for startup auth |
| (none) | Superuser password for startup auth |
| (unset) | Set any truthy value to register |
|
| HTTP transport bind host |
|
| HTTP transport bind port |
|
| Max page size for |
|
| Max operations per |
Tools
13 intent-first tools. Each one returns {"ok": true, "data": …, "hint"?: …} on
success or {"ok": false, "error_type": …, "message": …, "hint": …} on failure.
The hint names the next tool to call or the step that fixes the error. The
Kind column marks each tool R read-only, I idempotent, or D
destructive.
Always registered (11)
Tool | Kind | Purpose | Key parameters |
| R | Inventory every collection (name, id, type, field count) |
|
| R | Full field defs, types, |
|
| R | Query/look up records — by id, or |
|
| I | Create or update one record; the server validates the payload against the cached schema first |
|
| — | Many writes as one atomic transaction |
|
| I | Create or alter a collection (base / auth / view) |
|
| — | Check or switch the process identity |
|
| — | Auth lifecycle: password reset, verification, email change, token refresh |
|
| — | File on a record: get URL, download bytes, upload local file |
|
| R | Health, settings summary, cron list, log stats (non-health sections need superuser) | (none) |
| R | Request log entries (superuser only) |
|
Destructive — opt-in only (2)
The server registers these two only when POCKETBASE_ENABLE_DESTRUCTIVE is set.
Each one requires a confirmation argument that must match the current state, so
you cannot run the call without first checking what it will affect.
Tool | Kind | Purpose | Key parameters |
| D | Permanently delete records. IRREVERSIBLE |
|
| D |
|
|
Resource & prompts
Resource
pocketbase://schema— all collections (id, name, type, field_count).Prompts:
inspect_then_query,safe_delete,create_with_validation.
Skills
skills/pocketbase-mcp-tools/SKILL.md is an agent skill that teaches an MCP
client to use these tools correctly. It covers the inspect-then-act order,
filter templates instead of string interpolation, pagination limits, the
complex-query grammar (relation traversal, ?= any-of, API-rule shapes), and
the confirmation steps for destructive tools. Point your agent at the file, or
copy it into the client's skills directory. It gives better tool use than the
tool docstrings alone.
Docker
The image runs the HTTP transport (pocketbase-mcp --http). This is the
only transport that works in a container, because the stdio transport needs the
MCP client to start the process itself. The image binds 0.0.0.0:8000, runs as
a non-root user, and contains no build tools.
Pull the published image. Every GitHub release triggers
.github/workflows/docker-release.yml, which builds linux/amd64 and
linux/arm64 and pushes to GHCR:
docker run -d --name pocketbase-mcp -p 8000:8000 --env-file .env \
ghcr.io/touexe/pocketbase-mcp:latestTags: latest, the full version (1.0.0), 1.0, and 1.
Read the logs with docker logs -f pocketbase-mcp. Stop and remove the
container with docker rm -f pocketbase-mcp.
Build it yourself:
docker build -t pocketbase-mcp .
docker run -d --name pocketbase-mcp -p 8000:8000 --env-file .env pocketbase-mcpdocker-compose has two profiles:
docker compose --profile local up --build # build from the local Dockerfile
docker compose --profile registry up # pull ghcr.io/touexe/pocketbase-mcp:latestBoth services read the variables from .env (POCKETBASE_URL,
POCKETBASE_ADMIN_EMAIL, POCKETBASE_ADMIN_PASSWORD,
POCKETBASE_ENABLE_DESTRUCTIVE, and the rest) and set
POCKETBASE_MCP_HOST=0.0.0.0 and POCKETBASE_MCP_PORT=8000.
To reach a PocketBase server on the host: inside the container, 127.0.0.1
points at the container itself, not the host. Set
POCKETBASE_URL=http://host.docker.internal:8090. On Linux, also add
--add-host=host.docker.internal:host-gateway to docker run. Or run
PocketBase in the same compose network and use its service name.
To override the default flag (for example, to bind a different port), append the arguments:
docker run -d --name pocketbase-mcp-9000 -p 9000:9000 -e POCKETBASE_MCP_PORT=9000 \
--env-file .env ghcr.io/touexe/pocketbase-mcp:latest --httpOne Identity Per Process
This server carries exactly one PocketBase identity. The pypocketbase client writes the auth token into a single shared aiohttp session. Calling connect(as_='user', ...) changes the identity for all subsequent calls in the session.
For multi-tenant use (different identities in parallel), run one server process per identity.
Destructive Tools Opt-In
delete_records and destroy_collection are not registered by default. Set POCKETBASE_ENABLE_DESTRUCTIVE=1 to make them available. The opt-in stops a deployment that must never delete data from doing so by accident, whatever the agent requests.
Running
stdio (default, for Claude Desktop / MCP clients):
uv run pocketbase-mcpHTTP transport:
uv run pocketbase-mcp --httpClient Config Snippet
For Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"pocketbase": {
"command": "uv",
"args": ["run", "--directory", "/path/to/mcp", "pocketbase-mcp"],
"env": {
"POCKETBASE_URL": "http://127.0.0.1:8090",
"POCKETBASE_ADMIN_EMAIL": "admin@example.com",
"POCKETBASE_ADMIN_PASSWORD": "your-password"
}
}
}
}Testing
The default suite is hermetic: no network, no credentials.
uv run python -m pytestLive integration suite
tests/live/ drives the in-memory FastMCP client (the surface an agent sees)
against a real PocketBase server. It is marked live and excluded from the
default run; opt in with:
uv run python -m pytest -m liveRequired environment (names only; never commit a value):
Variable | Purpose |
| instance the suite runs against (defaults to |
| superuser identity, established through the |
| superuser password |
The suite sets settings.enable_destructive for its own session, so
delete_records and destroy_collection are exercised; you do not need to
set POCKETBASE_ENABLE_DESTRUCTIVE yourself.
When the server is unreachable or either credential is missing, every live test skips with a stated reason; it never errors.
⚠️ Development instances only. The live suite creates and deletes collections. Never point
POCKETBASE_URLat production or any instance whose data you care about.
The mcptest_ prefix rule: the safety contract
Every collection a live test touches must be one it created itself, named
mcptest_<area>_<hex8> via the live_collection factory. Teardown (both the
per-test finalizer and the session-end sweep) deletes only mcptest_*
names and raises rather than deletes anything else. This, plus the rule that
no test names a collection it did not create, keeps a mis-pointed
POCKETBASE_URL from destroying real data. Anyone adding a live test must
honor it: draw collections from the factory, never hard-code a bare name.
Resolved design questions
Session-end sweep is always on (no
--no-live-sweep). The sweep runs at the start and end of the next session and removes a crashed run'smcptest_*leftovers, so a fresh run is always clean; diagnose a failure by rerunning the single test.File-upload fixture is a generated temp file, not a committed binary asset. No thumbnail behaviour is exercised, so no real image is needed.
Smoke-testing over HTTP
tests/ and tests/live/ both run in-process; neither builds an HTTP
request. scripts/curl_smoke.sh closes that gap: it drives an
already-running HTTP server with nothing but curl, jq, and sed,
completing the MCP Streamable HTTP handshake, then issuing one real tools/call
against every registered tool. It is an operator/developer
command; it is not collected by pytest and not wired into CI.
⚠️ It writes to a real instance. Point it only at a development PocketBase. Every collection and record it creates lives under an ephemeral
mcpsmoke_-prefixed collection that it drops again on exit.
1. Start the server (a second terminal), against a development instance, with the destructive tools registered so all 13 are covered:
POCKETBASE_URL=http://127.0.0.1:8090 \
POCKETBASE_ADMIN_EMAIL=admin@example.com \
POCKETBASE_ADMIN_PASSWORD=your-password \
POCKETBASE_ENABLE_DESTRUCTIVE=1 \
uv run pocketbase-mcp --httpWithout POCKETBASE_ENABLE_DESTRUCTIVE=1 the server registers only 11 tools and
the harness prints a SKIP: line saying the flag is required for full coverage.
2. Run the harness:
POCKETBASE_ADMIN_EMAIL=admin@example.com \
POCKETBASE_ADMIN_PASSWORD=your-password \
bash scripts/curl_smoke.shIt reads POCKETBASE_MCP_HOST / POCKETBASE_MCP_PORT (default
127.0.0.1:8000) to find the server. POCKETBASE_ADMIN_EMAIL /
POCKETBASE_ADMIN_PASSWORD are the superuser credentials it authenticates and
tears down with; the same names the server itself uses.
Prerequisites: bash, curl, jq, and sed on PATH. Missing any of
them, missing a credential, or an unreachable MCP port each produce a SKIP:
line and exit 0, never a failure. A genuine assertion failure prints the
request and the full response body, still runs the remaining cases, tears down,
and exits 1.
Cleanup. A clean run, a failed run, and a Ctrl-C all trigger an EXIT trap
that reconnects as superuser and drops every mcpsmoke_ collection the run
created. A hard kill (SIGKILL) can still strand mcpsmoke_* collections;
they are safe to drop by hand. If teardown's own superuser reconnect fails
(the process may be left holding an ephemeral user identity), restart the
server process before retrying.
Design Decisions (Open Questions Resolved)
Should find_records fall back to get_full_list automatically?
Decision: Explicit fetch_all=True required.
An accidental full-table read floods the context window. An agent that asks for "all records" from a 100,000-row table would silently exhaust its context budget if the fallback were automatic. Passing fetch_all=True is a deliberate signal; the default paged behavior is safe.
Expose the schema as an MCP resource in addition to describe_schema?
Decision: Deferred. Tools only for v1.
Resources require the client to know when to re-fetch them (cache invalidation). Tools give the agent explicit control: call describe_schema(refresh=True) after a schema change. Once real usage shows the schema being re-read every turn, a resource is the right fix. Adding it later is cheap; it doesn't change any tool contracts.
Available Tools
11 toolsbulk_writeA
USE WHEN you need to create/update/delete multiple records atomically.
EXAMPLES:
operations=[ {"collection": "posts", "action": "create", "data": {"title": "A"}}, {"collection": "posts", "action": "update", "record_id": "xyz", "data": {"title": "B"}}, ]
NEXT STEPS: find_records to verify results.
| Name | Required | Description | Default |
|---|---|---|---|
| operations | Yes | List of operations. Each: {collection, action: create|update|upsert|delete, data?, record_id?}. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden. It discloses that operations are atomic and implies mutation, which is useful. However, it does not state partial-failure behavior, rollback semantics, permission needs, or what happens on invalid operations, leaving some uncertainty for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded with the usage trigger, followed by a concrete example and a useful next step. Every sentence earns its place, though the formatting could be slightly cleaner.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema covers return values, and the description covers atomicity and verification. However, the prose mentions only create/update/delete while the schema includes upsert, and there is no guidance on ordering, limits, or failure behavior. Adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the operations parameter and its inner structure with 100% coverage. The description's example repeats and illustrates that structure but adds little beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (create/update/delete), the resource (multiple records), and the key qualifier 'atomically'. This clearly distinguishes it from the sibling write_record, which handles single records.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'USE WHEN you need to create/update/delete multiple records atomically', giving clear invocation context. It does not list exclusions or alternatives, but the when-to-use guidance is strong enough to route the agent correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
connectA
USE WHEN you need to authenticate or check the current session identity.
EXAMPLES:
Check identity: connect(as_="status")
Superuser: connect(as_="superuser", email="admin@x.com", password="...")
User: connect(as_="user", collection="users", email="u@x.com", password="...")
Impersonate: connect(as_="impersonate", user_id="abc123")
NEXT STEPS: All subsequent tool calls in this session use the new identity.
| Name | Required | Description | Default |
|---|---|---|---|
| as_ | No | superuser: authenticate with admin creds; user: authenticate as a collection record; impersonate: assume another user's identity (superuser required); status: report current identity. | status |
| No | Email or username for 'user' or 'superuser' auth. | ||
| user_id | No | Record id to impersonate (action='impersonate'). | |
| password | No | Password for 'user' or 'superuser' auth. | |
| collection | No | Collection name for action='user' (e.g. 'users'). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals the key side effect: 'All subsequent tool calls in this session use the new identity,' which warns the agent that the operation changes session state. It omits possible failure modes or permission checks, but the core behavioral impact is transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: a trigger sentence, four illustrative examples, and one next-steps note. Each example line earns its place by clarifying a distinct mode, and there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with five optional parameters, four modes, and no annotations, the description covers the main usage patterns, the persistent session side effect, and the status default. An output schema exists, so return-value documentation is already accounted for elsewhere; only edge cases like failed auth or privilege errors are missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all five parameters and the as_ enum. The description adds value by demonstrating valid parameter combinations per mode (superuser with email/password, user with collection/email/password, impersonate with user_id), which is genuinely useful beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'USE WHEN you need to authenticate or check the current session identity,' clearly naming the action (authenticate/check) and resource (session identity). It does not explicitly distance itself from sibling tools like manage_auth, but the examples make its session-level role evident.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE WHEN' clause gives a concrete trigger: needing authentication or identity checking. It does not name alternatives or exclusions, so it stops short of full routing guidance, but the conditions for use are clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_collectionARead-only
USE WHEN you need full field definitions, API rules, or relation targets for one collection.
EXAMPLES:
"What fields does 'posts' have?" -> describe_collection(collection="posts")
Before write_record to see required fields -> describe_collection(collection="posts")
"What are the auth rules?" -> describe_collection(collection="users")
NEXT STEPS: find_records or write_record with the correct field names.
| Name | Required | Description | Default |
|---|---|---|---|
| collection | Yes | Collection name or id. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already communicates that this is a safe read operation, lowering the bar for the description. The description adds useful scoping ('for one collection') and output content expectations, but it does not disclose additional behavioral details such as auth requirements, connection prerequisites, or limitations. No contradiction exists with the read-only annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with USE WHEN, EXAMPLES, and NEXT STEPS, and it front-loads the purpose. The examples earn their place by making the usage concrete, though there is minor redundancy between the 'before write_record' example and the NEXT STEPS line.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, read-only introspection tool with an output schema, the description covers what the tool returns, when to use it, and how to follow up with find_records or write_record. It does not mention the describe_schema sibling or any connection prerequisite, but those are not critical gaps given the annotations and output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage, the schema already documents the 'collection' parameter as 'Collection name or id.' The description reinforces this with examples like collection='posts' but does not add new semantic details such as naming conventions, identifier formats, or case sensitivity. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool provides full field definitions, API rules, and relation targets for one collection, and the examples distinguish it from find_records and write_record. However, it does not explicitly differentiate itself from describe_schema, so sibling distinction is implied rather than fully stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE WHEN' phrasing explicitly defines the intended trigger, and the examples give concrete scenarios, including using it before write_record to learn required fields. It does not mention exclusions or describe_schema as an alternative for schema-level questions, but the guidance is still clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
describe_schemaARead-only
USE WHEN you need a quick inventory of all collections before querying or writing.
EXAMPLES:
"What collections exist?" -> describe_schema()
"Does a 'posts' collection exist?" -> describe_schema()
After adding a collection -> describe_schema(refresh=True)
NEXT STEPS: describe_collection(collection="") for field details.
| Name | Required | Description | Default |
|---|---|---|---|
| refresh | No | Force reload of the schema cache before listing. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description adds useful behavioral context: the tool works from a cached schema inventory and refresh controls cache invalidation. The example 'After adding a collection -> describe_schema(refresh=True)' transparently signals that the default could serve stale data, which is exactly the kind of nuance an agent needs to invoke it safely.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a compact, front-loaded block: the when-to-use sentence comes first, examples are formatted compactly, and the next-step pointer is a single line. Every line contributes either usage guidance or routing information, with no filler or redundant restatement of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the presence of an output schema, the readOnly annotation, and the fully-documented parameter, the description covers all the operational context an agent needs. It explains what the tool does, when to use it, why the parameter might matter, and how to proceed for deeper detail. There are no meaningful gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema fully documents the refresh parameter with 100% coverage, so the baseline is 3. The description adds value by giving a concrete scenario where refresh=True is needed, making the parameter's semantic role in cache invalidation more actionable than the schema description alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('inventory') and a clear resource ('all collections'), and places it in a distinctive context ('before querying or writing'). The examples reinforce the purpose by mapping natural-language questions to the tool, and the 'NEXT STEPS' line distinguishes it from describe_collection without any ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use the tool ('USE WHEN you need a quick inventory of all collections') and provides illustrative examples including a post-add scenario with refresh=True. While it names describe_collection as the follow-up for field details, it does not provide an explicit when-not-to-use statement, so it falls just short of the highest bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_recordsARead-only
USE WHEN you need to query or look up records in a collection.
EXAMPLES:
By id: find_records(collection="posts", record_id="abc123")
By filter: find_records(collection="posts", filter_template="status = {:s}", filter_params={"s": "published"})
All records: find_records(collection="posts", fetch_all=True)
NEXT STEPS: write_record to mutate, describe_collection for field names.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (1-based). | |
| sort | No | Sort expression, e.g. '-created,title'. | |
| expand | No | Comma-separated relation fields to expand. | |
| fields | No | Comma-separated fields to return (projection). | |
| per_page | No | Records per page. | |
| fetch_all | No | Fetch every matching record across all pages. Caution: may be large. | |
| record_id | No | Fetch exactly one record by id. Mutually exclusive with filter_template. | |
| collection | Yes | Collection name or id. | |
| filter_params | No | Values for {:name} placeholders in filter_template. | |
| filter_template | No | PocketBase filter with {:name} placeholders, e.g. 'status = {:s}' |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, covering the read-only safety profile. The description adds useful invocation modes (by id, by filter, fetch_all) but does not disclose additional behavior such as pagination limits or result size beyond what the schema already notes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the use condition, followed by compact examples and a next-steps line. It is somewhat long but each section contributes; there is no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 10 parameters and an output schema, the description plus schema covers the main query modes and sibling routing. It does not spell out the record_id/filter_template mutual exclusion, but the schema documents that constraint.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The examples add extra meaning by showing how collection, record_id, filter_template, filter_params, and fetch_all combine in realistic calls.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'USE WHEN you need to query or look up records in a collection,' naming a specific action and resource. It also distinguishes the tool from siblings by pointing to write_record for mutation and describe_collection for field names.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear triggering condition ('USE WHEN you need to query or look up records') and an explicit routing hint: 'write_record to mutate, describe_collection for field names.' It does not enumerate all alternatives like bulk_write, but the guidance is sufficient for most routing decisions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
inspect_serverARead-only
USE WHEN you need an overview of server health, settings, cron jobs, and log statistics.
EXAMPLES:
"Is PocketBase running?" -> inspect_server()
"What cron jobs are registered?" -> inspect_server()
"How many requests in the last 7 days?" -> inspect_server()
NEXT STEPS: read_logs for detailed log entries; connect(as_='superuser') for full access.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description adds useful behavioral context by clarifying it returns an overview of server state rather than detailed entries or full access. It also implies no side effects through 'overview' and by directing full access to connect, which is consistent with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the critical 'USE WHEN' guidance, then gives concrete examples and next-step routing. Every section earns its place and there is no redundant filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with an output schema and read-only annotation, the description fully covers what it returns, when to use it, and how to proceed for more detailed needs. Nothing required for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is nothing to explain beyond the schema. Baseline for no-parameter tools is 4, and the description's examples correctly show calls with no arguments, reinforcing the schema's 100% coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description states a specific verb ('inspect') and resource ('server') and enumerates the scope: health, settings, cron jobs, and log statistics. It also differentiates from read_logs by positioning itself as an overview rather than detailed log access.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE WHEN' directive explicitly tells an agent when to invoke this tool, reinforced by concrete example queries. The NEXT STEPS section names alternatives (read_logs, connect) and the conditions under which they are preferable, making routing unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_authA
USE WHEN you need to manage auth lifecycle: password reset, verification, email change, or token refresh.
EXAMPLES:
Request reset: manage_auth(action="request_password_reset", collection="users", email="u@x.com")
Confirm reset: manage_auth(action="confirm_password_reset", collection="users", token="...", password="new", password_confirm="new")
Refresh token: manage_auth(action="refresh", collection="users")
NEXT STEPS: connect(as_='status') to verify identity after refresh.
| Name | Required | Description | Default |
|---|---|---|---|
| No | Email address (request_* actions). | ||
| token | No | Confirmation token from the email link (confirm_* actions). | |
| action | Yes | Auth lifecycle action. | |
| password | No | New password (confirm_password_reset) or current password (confirm_email_change). | |
| new_email | No | New email address (request_email_change only). | |
| collection | No | Collection name (required for all actions except refresh). | |
| password_confirm | No | Password confirmation (confirm_password_reset only). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It does not state whether these actions mutate state, send emails, require authentication, invalidate existing tokens, or produce side effects; the NEXT STEPS hint about verifying identity after refresh is the only behavioral clue.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with its purpose, then delivers structured examples and a next-step callout. Every section earns its place, and the format makes it easy for an agent to scan and immediately apply the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is complex with 7 parameters and 7 distinct actions, and while reset and refresh flows are well exemplified, verification and email-change flows are only named, not demonstrated. The output schema covers return values, but the behavioral gaps around email dispatch and token lifecycle keep this from being fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the examples add real value by showing valid action-specific parameter combinations (e.g., request_password_reset with email, confirm_password_reset with token/password/password_confirm, refresh without collection). This bridges the gap between the flat schema and the action enum.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (auth lifecycle) and enumerates the concrete operations it covers: password reset, verification, email change, and token refresh. It distinguishes manage_auth from sibling tools like write_record and connect by scoping it to auth lifecycle actions, though the verb 'manage' is broad.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It opens with an explicit 'USE WHEN' trigger and provides worked examples for the most common actions. It does not explicitly exclude alternatives or compare against connect, but it does give a next-step pointer to connect(as_='status') after refresh, which gives practical sequencing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_collectionAIdempotent
USE WHEN you need to create or modify a collection schema.
EXAMPLES:
Create base: manage_collection(action="create", name="posts", fields=[{"name": "title", "type": "text", "required": True}])
Create view: manage_collection(action="create", name="post_stats", collection_type="view", view_query="SELECT id, title FROM posts")
Update rules: manage_collection(action="update", name="posts", api_rules={"list": "@request.auth.id != ''"})
NEXT STEPS: describe_collection to verify, find_records or write_record to use.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Collection name. | |
| action | Yes | Whether to create a new collection or update an existing one. | |
| fields | No | Field definitions. See PocketBase schema for field shapes. | |
| indexes | No | Index definitions. | |
| api_rules | No | API rules: {list, view, create, update, delete}. | |
| view_query | No | SQL query (for type='view' only). Validated before creation. | |
| collection_type | No | Collection type (for create only). | base |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the core mutating behavior ('create or modify a collection schema') and shows example effects, but it does not explain subtler side effects such as whether an update replaces existing fields or API rules. With only idempotentHint=true in annotations and no destructive/readOnly hints, a bit more behavioral context would be valuable. There is no contradiction with the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Each section earns its place: USE WHEN gives the trigger, examples show valid parameter combinations, and NEXT STEPS gives the post-invocation workflow. The formatting is scannable and contains no redundant schema prose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with seven parameters, enums, and multiple collection types, the examples cover the main create/update paths and provide verification follow-up. Since an output schema exists, return-value explanation is unnecessary. The main minor gap is that auth collections are not exemplified, especially with manage_auth as a sibling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, but the examples add real compositional meaning: fields for base collections, collection_type/view_query for views, and api_rules for updates. This helps an agent build valid parameter sets more effectively than the bare schema descriptions alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'USE WHEN you need to create or modify a collection schema,' naming a concrete action and resource. The examples for create base, create view, and update rules clearly distinguish this from siblings like describe_collection, find_records, and write_record, especially via the NEXT STEPS guidance.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use the tool with 'USE WHEN' and gives a follow-up workflow: 'describe_collection to verify, find_records or write_record to use.' It does not explicitly say when not to use it or name alternatives for read-only schema inspection, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_filesA
USE WHEN you need to get a file URL, download a file, or upload a new file to a record.
EXAMPLES:
URL: manage_files(action="url", collection="posts", record_id="abc", field="cover", filename="img.jpg")
Thumb: manage_files(action="url", ..., thumb="200x200")
Download: manage_files(action="download", ..., filename="doc.pdf")
Upload: manage_files(action="upload", ..., field="cover", local_path="/tmp/img.jpg", filename="img.jpg")
NEXT STEPS: find_records to see the updated file field after upload.
| Name | Required | Description | Default |
|---|---|---|---|
| field | Yes | Field name that holds the file. | |
| thumb | No | Thumbnail size for image fields, e.g. '100x100'. Only for url action. | |
| action | Yes | url: get the file URL; download: fetch file bytes; upload: upload a local file. | |
| filename | No | Filename as stored in the record (required for url/download). | |
| record_id | Yes | Record id that owns the file. | |
| collection | Yes | Collection name or id. | |
| local_path | No | Absolute local path to upload (required for upload action). |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the burden of explaining behavior. It discloses action semantics (url/download/upload), notes that thumb applies only to url, and implies uploads persist by suggesting find_records to verify the updated file field. It does not detail side effects or response handling, but the output schema exists to cover return values.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the primary use statement, followed by concise examples and a single next-step note. It is slightly longer than necessary but every sentence adds practical value, especially the examples that clarify parameter combinations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, three-action tool, the description plus fully documented schema and output schema provide enough to call the tool correctly. It covers all actions, action-specific parameter requirements, and a follow-up step. It omits edge cases like upload overwrite behavior, but that is not essential for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already covers all parameters with 100% description coverage, so the baseline is 3. The description adds meaningful action-specific guidance: filename is required for url/download, local_path is required for upload, and thumb only applies to url. This goes beyond the schema by clarifying conditional requirements.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific 'USE WHEN' statement listing three concrete operations: get a file URL, download a file, or upload a file. It is clearly distinct from sibling tools like find_records or write_record because it is scoped to file-related operations on records.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'USE WHEN' statement gives explicit contexts for invoking the tool. It does not name alternatives or exclusion criteria, but the examples clearly map actions to use cases, making the intended usage unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_logsARead-only
USE WHEN you need to inspect request log entries. Superuser access required.
EXAMPLES:
Latest logs: read_logs()
Single entry: read_logs(log_id="xyz")
Filter by level: read_logs(filter_template="level >= {:l}", filter_params={"l": 4})
NEXT STEPS: inspect_server for aggregate stats; connect(as_='superuser') if unauthorized.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number. | |
| log_id | No | Fetch a single log entry by id. Mutually exclusive with filter. | |
| per_page | No | Entries per page. Clamped to the server max. | |
| filter_params | No | Values for filter placeholders. | |
| filter_template | No | PocketBase filter for log entries, e.g. 'level = {:l}' |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description adds valuable context by requiring superuser access and showing how to remediate authorization failures. It also demonstrates filter-template usage with examples, which clarifies expected invocation behavior beyond the schema. There is no contradiction with the read-only hint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized into USE WHEN, EXAMPLES, and NEXT STEPS, with no wasted words. The key purpose and access requirement are front-loaded, and each example is short and illustrative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and all parameters documented in the schema, the description supplies the missing context: access requirements, common invocation patterns, and routing to related tools. An agent has enough information to call read_logs correctly for typical scenarios.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds value by giving concrete examples that map log_id, filter_template, and filter_params to actual calls, showing the template placeholder pattern. It does not explain page or per_page semantics, but the schema already covers those adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'USE WHEN you need to inspect request log entries,' giving a specific verb and resource. It also distinguishes itself from the sibling inspect_server by pointing to it for aggregate stats, so an agent can tell the tools apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states clearly when to use the tool ('USE WHEN...') and gives concrete next steps: inspect_server for aggregate stats, and connect(as_='superuser') if unauthorized. It does not explicitly list exclusions like 'do not use for record searches,' but the context and sibling references make the intended usage clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
write_recordAIdempotent
USE WHEN you need to create or update a single record.
EXAMPLES:
Create: write_record(collection="posts", action="create", data={"title": "Hi", "body": "..."})
Update: write_record(collection="posts", action="update", record_id="abc", data={"title": "New"})
NEXT STEPS: find_records to verify, describe_collection for field names.
| Name | Required | Description | Default |
|---|---|---|---|
| data | Yes | Field values to set. For update, include only fields to change. | |
| action | Yes | Whether to create a new record or update an existing one. | |
| expand | No | Comma-separated relation fields to expand in the response. | |
| record_id | No | Required for action='update'. The id of the record to update. | |
| collection | Yes | Collection name or id. |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide idempotentHint=true, and the description adds the create/update distinction with concrete examples showing how requests are shaped. It does not explain side effects, permissions, or how create remains idempotent, but the annotation covers retry safety, so this is adequate rather than rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized into USE WHEN, EXAMPLES, and NEXT STEPS with no filler. Each section earns its place, and the examples are compact while clearly demonstrating parameter usage.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema and output schema carry the parameter and return details, while the description supplies the selection condition and useful follow-up steps such as find_records and describe_collection. It could more explicitly point to bulk_write for multi-record writes, but the single-record scope makes this easy to infer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes all parameters with 100% coverage, so the baseline is 3. The examples add value by showing how action, data, collection, and record_id combine, especially clarifying that record_id is used for updates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific trigger and names the exact operation: create or update a single record. This clearly distinguishes the tool from bulk_write, which handles multiple records, so an agent can immediately tell what this tool is for.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description uses 'USE WHEN' to state the condition for calling the tool, and 'single record' implicitly excludes bulk operations. It does not explicitly name bulk_write as the alternative or provide when-not conditions, but the routing context is clear enough for an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v1.0.0- First observed
bulk_write - First observed
connect - First observed
describe_collection - First observed
describe_schema - First observed
find_records - First observed
inspect_server - First observed
manage_auth - First observed
manage_collection - First observed
manage_files - First observed
read_logs - First observed
write_record
TDQS
Scored across 11 tools
Each tool targets a distinct resource and action. Overlapping pairs like describe_schema/describe_collection and inspect_server/read_logs are clearly differentiated by their descriptions and intended use cases.
All tool names follow a consistent snake_case style, mostly verb_noun (e.g., describe_schema, find_records, manage_collection). The only deviation, bulk_write, still fits the style and does not introduce a mixed convention.
With 11 tools, the server is well-scoped for a backend platform, covering schema, records, auth, files, logs, and server health without being over- or under-populated.
While the core workflows are covered, there are notable gaps: no dedicated tool for deleting a single record (only via bulk_write) and manage_collection does not support deleting collections. These are core CRUD operations that an agent would expect.
Maintenance
Related MCP Connectors
Manage Appwrite projects, databases, auth, storage, functions, and messaging; search Appwrite docs
Manage Supabase projects end to end across database, auth, storage, realtime, and migrations. Moni…
The Instant MCP server is a wrapper around the Instant Platform SDK that enables creating, managing, and updating InstantDB applications directly within an editor. It provides tools for fetching rules files for LLMs, retrieving and pushing app schemas, managing permission rules, and executing database queries. Key capabilities include schema management (get-schema, push-schema), permission management (get-perms, push-perms), query execution, and listing recent query history.
Butterbase MCP server — manage your backend: schemas, auth, functions, storage, RAG, deploys.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA comprehensive server that enables advanced database operations with PocketBase, providing tools for collection management, record operations, user management, and database administration through the Model Context Protocol.667 npmMIT
- AlicenseBqualityBmaintenanceEnables MCP-compatible applications to directly interact with PocketBase databases for collection management, record operations, schema generation, and data analysis.2221 npm2MIT
- AlicenseNot gradedqualityFmaintenanceEnables AI assistants and MCP clients to interact with PocketBase databases for authentication, data management, and administrative operations.2 npm65MIT
- AlicenseNot gradedqualityDmaintenanceEnables LLMs to manage PocketBase databases with comprehensive CRUD, authentication, file management, backup, and hook operations through a standardized protocol.2 npm5MIT