velocms-mcp
@velocms/mcp
An MCP server for VeloCMS — draft, edit, publish, and manage your blog (posts, media, comments, members, site settings) from Claude Code, Claude Desktop, Cursor, or any other MCP client.
It's a thin, typed wrapper around the VeloCMS Public API
(https://<your-blog>/api/v1, documented at
/api/openapi on any VeloCMS site): every
tool maps to one real API call, with Zod-validated inputs and readable
errors — no scraping, no browser automation, just the platform's own
supported REST API.
What it does
Tool | What it does |
| List posts, paginated, optionally filtered by status ( |
| Fetch a single post by ID, including its full content and SEO fields |
| Create a new post (defaults to |
| Partially update an existing post — only the fields you pass change |
| Permanently delete a post |
| Set a post's status to |
| Set a post's status back to |
| List the media library, paginated, optionally filtered by MIME type |
| List comments, paginated, optionally filtered by post or moderation status |
| Set a comment's status to |
| List subscribers/readers (emails are masked, e.g. |
| Read the blog's name, description, and feature flags |
Every tool ships a description an LLM can read to figure out when and how to use it — that's the point of MCP, not just a REST proxy with extra steps. See Tool reference below for full argument lists.
Related MCP server: dustinedwards-mcp
Setup
1. Get a VeloCMS API key
In your VeloCMS dashboard: Settings → API Keys → create a key with the
scopes you need (posts:read, posts:write, media:read, comments:read,
comments:moderate, members:read, site-settings:read, etc.). API access
requires the Pro plan or higher.
2. Configure your MCP client
You don't need to clone this repo — npx fetches and runs it on demand.
Claude Code
claude mcp add velocms \
--env VELOCMS_SITE_URL=https://myblog.velocms.org \
--env VELOCMS_API_KEY=velo_your_64_char_hex_key_here \
-- npx -y -p @velocms/mcp velocms-mcpMCP servers register their tools at session start, so restart your Claude Code session after adding this.
Claude Desktop
Add to your claude_desktop_config.json (Settings → Developer → Edit
Config):
{
"mcpServers": {
"velocms": {
"command": "npx",
"args": ["-y", "-p", "@velocms/mcp", "velocms-mcp"],
"env": {
"VELOCMS_SITE_URL": "https://myblog.velocms.org",
"VELOCMS_API_KEY": "velo_your_64_char_hex_key_here"
}
}
}
}Restart Claude Desktop after editing.
Cursor / any other MCP client
Same shape as above — point the client's MCP config at
npx -y -p @velocms/mcp velocms-mcp with VELOCMS_SITE_URL and
VELOCMS_API_KEY set in its env. The server speaks standard MCP over
stdio, so any client that supports stdio MCP servers works.
3. Local install (contributing / running from source)
git clone https://github.com/VeloCMS/velocms-mcp.git
cd velocms-mcp
npm install
npm run build
cp .env.example .env
# edit .env and set VELOCMS_SITE_URL + VELOCMS_API_KEY
VELOCMS_SITE_URL=... VELOCMS_API_KEY=... node dist/index.jsConfig reference
Env var | Required | Description |
| yes | Your blog's base URL — a |
| yes | An API key from |
If either is missing, the server prints a clear message to stderr and exits
immediately (process.exit(1)) — it never starts half-configured.
Tool reference
Argument names are camelCase; the server maps them to the API's snake_case JSON fields for you.
list_posts — page?, perPage? (max 100), status? (draft |
published).
get_post — id (required).
create_post — title (required, ≤255 chars), slug?, contentHtml?,
contentJson? (TipTap ProseMirror document — prefer contentHtml unless
you need this), excerpt? (≤500), status? (draft default | published),
tags? (string array), seoTitle? (≤60), seoDescription? (≤160).
update_post — id (required) + any of the create_post fields
(all optional here). At least one field besides id is required — the tool
rejects a no-op call before making any network request.
delete_post — id (required). Permanent.
publish_post / unpublish_post — id (required). Shorthand for
update_post({ status: "published" }) / update_post({ status: "draft" }).
list_media — page?, perPage?, type? (MIME type prefix, e.g.
"image").
list_comments — page?, perPage?, postId?, status? (approved
| pending | spam).
moderate_comment — id (required), status (required: approved |
pending | spam).
list_members — page?, perPage?, tier? (free | paid).
get_site_settings — no arguments.
Error handling model
The VeloCMS API returns a consistent JSON error envelope:
{ "error": { "code": "RATE_LIMITED", "message": "...", "details": {} } }This client surfaces that message directly (never a raw stack trace), enriched with actionable hints:
401 (
UNAUTHORIZED) — the message tells you to checkVELOCMS_API_KEY.403 (
PLAN_UPGRADE_REQUIRED) — the message points at/admin/billing.403 (
INVALID_SCOPE/FORBIDDEN) — the message tells you to check the key's scopes.429 (
RATE_LIMITED) — theRetry-Afterresponse header (seconds) is parsed and included in the error message, and returned asretryAfterSecondsif you're calling the client library directly.Any other non-2xx — the API's own
code+messageare surfaced as-is.
Rate limits are plan-based (Pro: 30/min, 1,000/hr · Business: 120/min, 5,000/hr · Agency: 300/min, 20,000/hr) — this server does not retry automatically; it fails fast with the wait time so an interactive tool call never blocks silently.
Security
Your API key is a tenant-scoped credential — it can only reach the one blog it was issued for, and only the endpoints its scopes allow.
The key is read once from the environment and never logged, echoed, or included in any tool output.
Member emails returned by
list_membersare masked by the API itself (e.g.u***@example.com) — this server never sees or handles unmasked member PII.Encrypted tenant settings (Stripe keys, AI provider keys) are excluded from
get_site_settingsby the API — there is no way to read them through this server.
Notes on this MCP server
moderate_comment's body field isstatus, notaction—PATCH /api/v1/comments/{id}/moderatetakes{ "status": "approved" | "pending" | "spam" }per the API's own schema, so the tool's input is named to match.get_postandget_site_settingsreturn the record directly (not wrapped in{ "data": ... }) — only the write endpoints (create_post,update_post,moderate_comment) wrap their response, matching the API's own inconsistency here (documented inopenapi.yaml).There is currently no
upload_mediatool —POST /api/v1/mediatakesmultipart/form-data, which doesn't map cleanly onto typical MCP client transports.list_mediais available for referencing media already uploaded through the dashboard. Contributions welcome if you need this.
Development
npm install
npm run typecheck # tsc --noEmit
npm test # vitest — all tests run against a mocked fetch, no live API calls
npm run build # emits dist/The test suite covers: the Authorization: Bearer header on every request,
each tool's exact method/URL/body mapping, error-code mapping for
401/403/429/500 responses, and the missing-env-var fail-fast path. No test
in this repository makes a real network call.
License
MIT — see LICENSE.
Available Tools
12 toolscreate_postCreate a postA
Creates a new blog post. Defaults to status=draft — pass status=published to publish immediately (stamps published_at automatically), or create as a draft and call publish_post once you're ready. Requires the posts:write scope.
| Name | Required | Description | Default |
|---|---|---|---|
| slug | No | Auto-generated from title if omitted. | |
| tags | No | ||
| title | Yes | Post title. Required. | |
| status | No | draft (default) or published. Publishing here stamps published_at automatically — or create as draft and call publish_post later. | |
| excerpt | No | ||
| seoTitle | No | SEO meta title, max 60 chars. | |
| contentHtml | No | Post body as HTML. | |
| contentJson | No | TipTap ProseMirror JSON document (arbitrary structure). Prefer contentHtml unless you specifically need to write a ProseMirror document. | |
| seoDescription | No | SEO meta description, max 160 chars. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the transparency burden. It discloses the default status, auto-stamping of published_at, and the two-step draft workflow, plus the required posts:write scope. It doesn't cover error behavior or return value, but the key behavioral traits are well explained.
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?
Two sentences deliver purpose, behavior, alternatives, and prerequisites. Perfectly front-loaded, with no wasted words.
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 9 parameters and no output schema, the description works well with the schema to cover all essential inputs and the publishing workflow. The only gap is not describing what the tool returns (e.g., created post object), which would be helpful without an 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?
Schema description coverage is 78%, and the schema already details all major parameters. The description adds workflow context (default status, publish_post alternative) that partially reinforces the schema's status description but doesn't add new parameter-specific semantics beyond what's already documented.
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 uses a specific verb ('Creates') and resource ('blog post'), clearly distinguishing this from siblings like update_post, publish_post, or list_posts. It also clarifies the default status and publishing workflow.
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 states when to use publish_post vs. immediate publishing: 'create as a draft and call publish_post once you're ready.' Also names the required scope, giving clear context for when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_postDelete a postA
Permanently deletes a post by ID. Requires the posts:write scope.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | PocketBase record ID of the post to delete. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses the destructive and irreversible nature ('Permanently deletes') and the required scope, covering the most critical behavioral traits. It does not mention side effects on related data or response behavior, but the key safety profile 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 a single sentence, front-loaded with the action, and contains no extraneous words. Every phrase is necessary and informative.
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 simple, but the description omits what happens on success (e.g., return value) and any effects on related resources like comments or media. Without an output schema, this additional context would be helpful. The core behavior is clear, but some operational details 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?
The schema's parameter description already fully documents the 'id' parameter as 'PocketBase record ID of the post to delete.' The tool description only repeats 'by ID' without adding new semantic value, so it meets the baseline for high schema 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?
The description clearly states 'Permanently deletes a post by ID,' which is a specific verb+resource action. This distinguishes it from sibling tools like update_post, publish_post, and unpublish_post.
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 implies usage (for deleting a post) but does not explicitly say when to prefer this over alternatives like unpublish_post. It provides a prerequisite ('Requires the posts:write scope') but no clear when-to-use or when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_postGet a postA
Fetches a single post by its PocketBase record ID, including content_html/content_json and SEO fields. Requires the posts:read scope.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | PocketBase record ID of the post. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description adds useful context by requiring the 'posts:read' scope and noting included fields (content_html/content_json and SEO fields). However, it does not disclose behavior for non-existent IDs, error responses, or output format, leaving gaps.
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 two sentences with no redundant wording. It front-loads the main action and then adds the auth requirement in a separate concise sentence, making it efficient and easy to scan.
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 low complexity (single parameter, no output schema, simple read), the description is mostly complete: it covers the core operation, auth scope, and returned fields. It lacks explicit error handling details, but these are not critical for a simple fetch.
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 fully describes the single 'id' parameter with 100% coverage. The description repeats 'PocketBase record ID' but does not add additional semantics beyond the schema, so baseline 3 applies.
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 it 'Fetches a single post by its PocketBase record ID', which is a specific verb+resource+scope. It distinguishes from list_posts (single vs. list) and sibling mutation tools like create_post and update_post.
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?
Usage is implied for retrieving a single post by ID, but no explicit alternatives or exclusions are mentioned. The description does not say when to prefer this over list_posts or other siblings, providing only implicit context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_site_settingsGet site settingsA
Fetches the tenant's site configuration (name, description, logo, favicon, members/comments enabled flags). Encrypted fields (Stripe keys, AI API key) are always excluded by the API. Requires the site-settings:read scope.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It explicitly states which fields are returned, that encrypted fields are always excluded, and the required auth scope. This gives the agent a strong behavioral model for a simple config fetch.
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?
Two sentences with high information density. Front-loads the main purpose, then adds the critical exclusion and auth caveats. Every sentence earns its place.
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 parameterless read-only tool with no output schema, the description fully covers return contents, exclusions, and access requirements. Nothing essential 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?
Zero parameters, so baseline is 4 per rubric. Description correctly spends no space on parameters; schema already documents the empty property set.
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?
Specific verb 'Fetches' plus resource 'tenant's site configuration' with concrete examples (name, description, logo, favicon, flags). Unambiguous and clearly distinct from sibling tools like get_post or list_members.
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?
Clear context of what the tool retrieves and the required scope. No explicit 'when to use vs alternatives' is needed because no sibling tool overlaps with site settings; the purpose itself implies the usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_commentsList commentsA
Lists comments, paginated. Optionally filter to a specific post (postId) and/or by moderation status (approved, pending, spam). Requires the comments:read scope.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (1-based). Default: 1. | |
| postId | No | Filter to comments on a specific post. | |
| status | No | Filter by moderation status. | |
| perPage | No | Records per page, max 100. Default: 20. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It discloses pagination, optional filters, and authentication requirements (comments:read scope). It does not detail response shape or ordering, but for a read-only listing tool this is adequate.
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?
Two concise sentences front-load the primary action, pagination, filters, and scope. Every clause earns its place with no redundancy or 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 moderately simple listing tool with no output schema and no annotations, the description covers purpose, filters, pagination, and auth. It lacks return-format details, but the schema covers parameters and the tool is not behaviorally complex, so it is adequately 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 description coverage is 100%, so the schema already documents all parameters. The description adds minimal semantic value beyond restating the filter options and pagination. It does not introduce new parameter meaning, so baseline 3 applies.
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 ('Lists') and resource ('comments'), with clear scope markers: pagination, optional filters, and required scope. It distinguishes itself from siblings like moderate_comment (which alters comment state) and list_posts (which lists posts).
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 clearly implies when to use this tool: to retrieve comments, optionally filtered by post or moderation status, and requires the comments:read scope. It does not explicitly name alternatives or exclusions, but the context makes the usage straightforward.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_mediaList mediaA
Lists items in the media library, paginated. Optionally filter by MIME type prefix (e.g. 'image'). Requires the media:read scope.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (1-based). Default: 1. | |
| type | No | Filter by MIME type prefix (e.g. 'image'). | |
| perPage | No | Records per page, max 100. Default: 20. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses key behaviors: pagination, optional filtering by MIME type, and the required 'media:read' scope. It does not detail return structure, but covers the main behavioral aspects for a list operation.
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 three concise sentences that each add value: purpose, filtering, and auth requirement. It is front-loaded and free of 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?
The description covers purpose, pagination, filtering, and scope, but omits return format details. Given no output schema, a bit more specificity about the response would improve completeness, but the essentials are present.
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 covers all three parameters with detailed descriptions (page, type, perPage). The description's mention of 'MIME type prefix (e.g. 'image')' merely repeats the schema's existing example, adding no additional semantic value.
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 'Lists items in the media library' with a specific verb and resource, and distinguishes from sibling list tools (list_posts, list_comments, list_members) by specifying 'media library' and the MIME type filter.
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 provides clear context by defining the resource as 'media library' and noting optional MIME type filtering, making its intended use obvious. It does not mention alternatives or exclusions, but none are necessary given the distinct resource.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_membersList membersA
Lists reader/subscriber records, paginated. Email local parts are masked by the API (e.g. u***@example.com). Optionally filter by tier (free or paid). Requires the members:read scope.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (1-based). Default: 1. | |
| tier | No | Filter by subscription tier (free or paid). | |
| perPage | No | Records per page, max 100. Default: 20. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses pagination, email masking (a data transformation trait), optional tier filtering, and the members:read scope requirement. It does not describe the response structure or error/rate-limit behavior, but for a list operation these are less critical. The masking and scope details go beyond the schema, providing useful behavioral transparency.
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 two sentences and efficiently conveys core functionality, pagination, masking, filtering, and auth. No redundant words; every clause adds information. It is front-loaded with the main verb and resource.
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 list tool with no output schema or annotations, the description covers purpose, pagination, filtering, masking, and auth. However, it does not describe the response format (e.g., array of members with pagination metadata), which would be helpful given no output schema exists. The description is helpful but not fully complete in this dimension.
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 provides complete descriptions for all three parameters (page, tier, perPage) with defaults, ranges, and enum values. Schema coverage is 100%. The description mentions tier filtering and pagination but does not add new parameter-specific semantics beyond the schema, so the baseline of 3 applies.
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's function: 'Lists reader/subscriber records, paginated.' It provides a specific verb (lists), resource (reader/subscriber records), and key contextual details (email masking, tier filter, required scope). The resource is unique among siblings (members vs posts/media/comments), so it distinguishes itself effectively.
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 clearly indicates this is for listing reader/subscriber records, implying use when member data is needed. It mentions the optional tier filter and required scope, giving context. However, it does not explicitly compare to sibling list tools (e.g., 'for posts use list_posts'), so it lacks explicit exclusions or alternatives. Usage context is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_postsList postsA
Lists blog posts for the authenticated tenant, paginated (default 20/page, max 100). Optionally filter by status (draft or published). Requires the posts:read API key scope.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (1-based). Default: 1. | |
| status | No | Filter by post status (draft or published). | |
| perPage | No | Records per page, max 100. Default: 20. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It discloses pagination behavior (default 20/page, max 100), optional status filtering, and the required API key scope. This goes well beyond a simple 'list posts' statement, providing useful operational details.
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 two sentences, front-loaded with the primary action, and every sentence adds value. It efficiently covers the core function, pagination, filter, and scope without any fluff or redundancy.
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 description is sufficiently complete for a simple list tool with three optional parameters and no output schema. It covers the essential context: what it lists, pagination limits, available filters, and authentication requirement. It does not describe response shape, but this is not critical for a list operation and no output schema exists to contradict it.
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 description coverage is 100%, so all parameters are already documented (page, status, perPage). The description mostly restates what the schema says (default 20/page, max 100, status filter) without adding new meaning or clarifications beyond the structured 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 clearly states the tool's verb and resource: 'Lists blog posts for the authenticated tenant.' It also specifies pagination and optional status filtering, which distinctly separates it from sibling tools like get_post (single post) and create_post/update_post/delete_post (mutations).
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 provides clear context for when to use the tool: to list posts with pagination and optional status filters, requiring posts:read scope. It does not explicitly mention alternatives or exclusions, but the context is sufficient for an agent to understand its typical use case compared to sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
moderate_commentModerate a commentA
Sets a comment's moderation status (approved, pending, or spam). Requires the comments:moderate scope.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | PocketBase record ID of the comment to moderate. | |
| status | Yes | Moderation status to apply: approved, pending, or spam. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses a key behavioral trait (requires the comments:moderate scope) and indicates a mutation action. However, it does not explain side effects, reversibility, or what the response looks like, which would be valuable for an agent.
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 two sentences, front-loaded with the core purpose, and includes only necessary details (allowed statuses and scope requirement). No redundancy or 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 simple two-parameter setter, the description covers purpose, statuses, and required scope. While there is no output schema and no mention of return behavior, the simplicity of the operation makes this mostly complete. A brief note on alternatives to sibling post-moderation tools would have pushed it higher.
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%, with clear descriptions for both id and status, and the status enum is also present. The description adds no additional parameter-level meaning beyond what the schema already provides, 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?
The description clearly states the tool's action ('Sets a comment's moderation status') and enumerates the allowed statuses (approved, pending, or spam). This specific verb+resource combination, along with the title 'Moderate a comment', effectively distinguishes it from sibling tools that operate on posts.
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 implies the tool is for moderating comments, and the scope requirement provides a prerequisite context. However, it does not explicitly compare to alternatives like update_post or publish_post/unpublish_post, nor does it state when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publish_postPublish a postA
Sets a post's status to published (stamps published_at). Shorthand for update_post({ status: 'published' }). Requires the posts:write scope.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | PocketBase record ID of the post to publish. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the transparency burden. It reveals that publishing changes the status to 'published' and adds a 'published_at' timestamp, plus requires the 'posts:write' scope. This provides meaningful behavioral context beyond the tool's name and helps the agent understand side effects and authorization needs.
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 two concise sentences, front-loading the action and effect in the first sentence and the shorthand relation in the second. Every word serves a purpose, with no filler or repetition.
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 simple status-change tool with one parameter and no output schema, the description covers the core action, effect, and required scope. It could add a note about what happens if the post is already published or that only the status field is affected, but the shorthand reference to update_post implies this, making it nearly 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?
The only parameter (id) is already described in the schema as 'PocketBase record ID of the post to publish', giving 100% schema coverage. The description adds no additional parameter semantics beyond what the schema provides, meeting the baseline for full 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?
The description uses a specific verb 'Sets' with an explicit resource ('a post's status') and the effect (to published, stamps published_at). It clearly distinguishes from siblings like update_post and unpublish_post by describing the exact mutation performed.
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 frames the tool as 'Shorthand for update_post({ status: 'published' })', giving clear guidance on when to use it as a specialized alternative to updating the status directly. It also mentions the required scope ('posts:write'), which helps in deciding eligibility, though it doesn't explicitly exclude using update_post for other field changes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unpublish_postUnpublish a postA
Sets a post's status back to draft, taking it off the public site. Shorthand for update_post({ status: 'draft' }). Requires the posts:write scope.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | PocketBase record ID of the post to unpublish. |
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 state transition ('back to draft'), the public-facing consequence ('taking it off the public site'), the relationship to update_post, and the required auth scope. It does not mention potential failure modes or return values, but for a simple idempotent-looking operation this is reasonably 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 two sentences long, front-loaded with the action and outcome, and every word earns its place. The shorthand reference and scope requirement are valuable additions without any fluff or redundancy.
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 (single required parameter, no output schema, no annotations), the description is complete. It explains the purpose, the effect, the scope, and its relation to a sibling tool, giving an agent sufficient context to invoke it correctly and know what to expect.
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 describes the only parameter (id) as 'PocketBase record ID of the post to unpublish,' giving 100% coverage. The description adds no additional parameter-level detail beyond confirming it's the post whose status changes. Baseline of 3 is appropriate since the schema does the heavy lifting.
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's action ('Sets a post's status back to draft') and its effect ('taking it off the public site'). It distinguishes itself from the sibling update_post by identifying itself as a shorthand for a specific update_post call, making the purpose unmistakable even among similar tools.
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 frames the tool as shorthand for update_post({ status: 'draft' }), which tells the agent when to use this tool versus the more general update_post. It also states the required posts:write scope, providing a clear prerequisite. No exclusions are needed for such a simple operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_postUpdate a postA
Partially updates an existing post — only the fields you pass are changed. Requires at least one field besides id. Requires the posts:write scope.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | PocketBase record ID of the post to update. | |
| slug | No | ||
| tags | No | ||
| title | No | ||
| status | No | draft or published. Transitioning draft -> published stamps published_at automatically. Prefer publish_post/unpublish_post for a status-only change. | |
| excerpt | No | ||
| seoTitle | No | ||
| contentHtml | No | ||
| contentJson | No | TipTap ProseMirror JSON document. | |
| seoDescription | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses the sparse-update behavior (only passed fields changed), the validation constraint (at least one field besides id), and the required scope. No annotations are provided, so these disclosures are valuable. However, it omits return-value behavior and side effects like the published_at stamp, which are covered in the schema's status description.
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?
Two sentences, front-loaded with the core action and scope. Each sentence adds information: what it does, the field requirement, and the required permission.
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 10-parameter mutation tool with no annotations and no output schema, the description covers the essential usage contract: partial update, minimum field requirement, and scope. It could explicitly advise using publish_post/unpublish_post for status-only changes, but that guidance exists in the schema's status parameter. Return-value information is missing but not critical.
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 only 30%, so the description needed to compensate. It adds the key semantic that all optional properties are updatable individually, and the 'at least one field besides id' requirement clarifies the role of the id parameter. It doesn't describe individual parameters, but the names are self-explanatory and the partial-update contract ties them together.
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?
Clearly states it partially updates an existing post, distinguishing it from create/delete. 'Only the fields you pass are changed' adds precision. Also includes the required scope.
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?
Provides clear context that it is a partial update and requires at least one non-id field, plus posts:write scope. It doesn't explicitly name alternatives like publish_post/unpublish_post, which are referenced in the schema's status description rather than the tool description.
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.
12 tool updates
v0.1.2- First observed
create_post - First observed
delete_post - First observed
get_post - First observed
get_site_settings - First observed
list_comments - First observed
list_media - First observed
list_members - First observed
list_posts - First observed
moderate_comment - First observed
publish_post - First observed
unpublish_post - First observed
update_post
TDQS
Scored across 12 tools
Each tool targets a distinct resource and action: post CRUD, publish state transitions, media listing, comment moderation, member listing, and site settings retrieval. No two tools overlap in purpose.
All tools follow a consistent snake_case verb_noun pattern (get_, create_, list_, update_, delete_, publish_, unpublish_, moderate_). The consistent use of singular/plural nouns is conventional and readable.
12 tools is well-scoped for a CMS. Post lifecycle is fully represented, and the addition of media, comments, members, and settings covers the main auxiliary resources without unnecessary bloat.
Post CRUD and publishing workflow are complete, but media only supports listing, site settings only get, and comments lack deletion. These read-only surfaces create dead ends for agents trying to manage those resources.
Maintenance
Related MCP Connectors
Create, edit, organize, publish, and configure JustBlogged blogs from MCP clients.
Create, schedule, and publish social posts, manage accounts, and read analytics as MCP tools.
Publish and manage articles, series, comments, reactions, newsletters and blog analytics.
Hosted MCP for BlogBat: read, write, generate, and publish blog articles and content.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP server for publishing to WordPress. 13 tools cover posts, categories, tags, image hosting, featured images, and SEO metadata (Rank Math, etc.) One call runs the full markdown-to-live-URL pipeline.1311 npm4AGPL 3.0
- FlicenseNot gradedqualityCmaintenanceMCP wrapper over the dustinedwards.info operator publish API, exposing five tools for managing blog posts (list, get, save, sync, delete) while containing no policy of its own.-
- AlicenseAqualityCmaintenanceAn MCP server for managing Google Blogger blogs, posts, pages, comments, and media via the Blogger API v3. Includes OAuth authentication, Base64 image embedding, and lightweight listing modes.2920 npmMIT
- AlicenseAqualityAmaintenanceEnables managing self-hosted WordPress sites from any MCP client, covering content, themes, plugins, menus, users, and SQL with credentials in Cloudflare Worker Secrets or local stdio. It provides 117 tools and adds guardrails like drafts, trash, and dry-run operations.1171MIT