Skip to main content
Glama
micropage-sh

@micropage-sh/mcp

Official

@micropage-sh/mcp

MCP server for micropage.sh. It lets an AI assistant (Claude Code, Claude Desktop, Cursor, VS Code) create, edit and publish micropages and posts from markup.

Documentation: https://docs.micropage.sh/docs/mcp/overview/

Install

The server needs Node.js 20 or later and a Pro or Pro+ account. It uses the session from the micropage CLI:

npm install -g @micropage-sh/cli
micropage login
claude mcp add micropage -- npx -y @micropage-sh/mcp

For other clients, run npx -y @micropage-sh/mcp over stdio:

{
  "mcpServers": {
    "micropage": {
      "command": "npx",
      "args": ["-y", "@micropage-sh/mcp"]
    }
  }
}

Emailing subscribers, deleting projects and reading form submissions are off by default. Turn them on with MICROPAGE_MCP_ALLOW_SEND=1, MICROPAGE_MCP_ALLOW_DELETE=1 and MICROPAGE_MCP_SUBMISSIONS=1. For headless use, set MICROPAGE_DEPLOY_TOKEN and MICROPAGE_DEPLOY_PROJECT instead of logging in. See Install and Safety.

Related MCP server: hubspot-mcp-server

Hosted server

micropage also hosts this server at https://mcp.micropage.sh/mcp. Clients connect over streamable HTTP and sign in with OAuth through the micropage account, so nothing is installed locally. Clients register themselves on first connect; in claude.ai just add a custom connector with the URL. Claude Code:

claude mcp add --transport http micropage https://mcp.micropage.sh/mcp

The setup for claude.ai and Claude Desktop, the per-connection permissions, and the deploy-token headers for headless use are in Hosted server.

Development

See DEVELOPMENT.md for working on the server and PUBLISHING.md for releases.

License

MIT

Available Tools

20 tools
create_projectCreate a micropage projectAInspect

Create a new, empty micropage project in the signed-in account and return it together with a complete starter .page file (one of the bundled examples) to adapt.

Use it when the user wants a new site. Each call creates another project and counts against the plan's project limit (Pro: 5, Pro+: 20), so check list_projects first when the user may mean an existing site. Nothing is published: write the page, call save_page, and publish only on request.

It does not write local files (it is not micropage projects create) and cannot set a custom domain; that is done in the editor.

NameRequiredDescriptionDefault
nameYesProject name shown in the editor, e.g. "Acme waitlist".
domainNoOptional micropage subdomain: "acme" serves at https://acme.micropage.sh. Lowercase letters, digits and hyphens, up to 58 characters. Omit it to get one derived from the name plus a short random suffix.

Output Schema

NameRequiredDescription
projectYes
starterYes
next_stepsYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare it as a non-read-only, non-idempotent, non-destructive open-world write, but the description adds material context beyond that: each call counts against plan project limits (Pro: 5, Pro+: 20), nothing is published as a side effect, and it does not write local files. This is exactly the value-add expected when annotations exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight paragraphs, front-loaded with the core action, then usage/routing, then exclusions. Every sentence carries distinct information; none is redundant with the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be re-explained, and annotations cover the safety profile. The description still fills remaining gaps (quota impact, publication behavior, non-local-file scope, domain limitation), making it complete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both 'name' and 'domain' are already well documented, giving a baseline of 3. The description adds little parameter-level detail, though 'cannot set a custom domain' usefully clarifies that the schema's 'domain' is only a subdomain, not a custom domain.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create a new, empty micropage project in the signed-in account') and even describes what is returned (the project plus a starter .page file). This clearly distinguishes it from siblings like list_projects, get_project, and save_page.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use it ('when the user wants a new site'), names the alternative to check first (list_projects) with the condition that selects it ('when the user may mean an existing site'), and lays out the follow-on workflow (write the page, call save_page, publish only on request).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_postDelete a micropage postA
DestructiveIdempotent
Inspect

Delete a post for good, removing it from the site if it was published. There is no undo; to only take it off the site use unpublish_post. Same as micropage posts rm <slug>.

Needs confirm: true, which you should only pass after the user has agreed. Deleting a slug that does not exist is not an error (deleted: false). Queues a site rebuild when a post was removed and the project has been published. The site rebuild redeploys the live build, so an unpublished page draft left by save_page or the editor stays a draft. It returns build_id and after_event_id to follow the rebuild with get_deploy_status.

NameRequiredDescriptionDefault
slugYesThe post's slug, as list_posts shows it (e.g. "launching-new-dashboard"). Normalised like the CLI does.
confirmNoMust be true. Ask the user first: the post is deleted for good and leaves the live site.
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.

Output Schema

NameRequiredDescription
slugYes
deletedYesFalse when no post had that slug (nothing to delete).
projectYes
build_idYesThe build the site rebuild redeploys: the live one, not an unpublished page draft. Pass to get_deploy_status; null when nothing was rebuilt.
after_event_idYesPass to get_deploy_status with build_id to see only events from this rebuild.
rebuild_queuedYesTrue when a site rebuild of the live build was queued to take the post down.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations covering destructiveness/idempotency, the description adds substantial context: no undo, confirm must be true and only after user agreement, deleting a nonexistent slug is not an error (deleted:false), a site rebuild is queued and redeploys the live build while leaving drafts intact, and it returns build_id/after_event_id. This far exceeds the annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the destructive nature and the sibling alternative, then flows into confirmation, edge-case behavior, and rebuild/return details. Every sentence carries distinct, load-bearing information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation with an output schema already present, the description covers reversibility, confirmation protocol, error-free misses, and side effects (rebuild + follow-up tool). Nothing an agent needs to call it safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description nonetheless adds genuinely new semantics beyond the schema — that confirm should only be passed after user agreement, and that a nonexistent slug yields deleted:false rather than an error. These nuance the slug and confirm parameters beyond their schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ('delete a post for good, removing it from the site if it was published') with clear scope, and it explicitly names the sibling it is not (unpublish_post). An agent can distinguish it from unpublish_post without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use this instead of unpublish_post ('to only take it off the site use unpublish_post'), notes the CLI equivalent, and gives the precondition for confirm. Alternatives and conditions are spelled out, not implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_deploy_statusFollow a micropage deployA
Read-onlyIdempotent
Inspect

Report the progress of a publish: the build status, the deploy events since after_event_id (queued, built, uploaded, domain wiring, completed or failed), whether it is done, and the live URL.

Call it after publish_build or publish_post, passing the build and after_event_id they returned, and keep calling it with the returned after_event_id until done is true. With after_event_id, only a deploy event after it ends the wait: a site rebuild after a post change is queued (up to about 3 minutes unless the account is Pro+) and reports waiting_for_start until it begins. It waits up to wait_seconds (default 20, max 45) per call, sending progress notifications meanwhile. possibly_stuck flags a publish with no events for far longer than a deploy takes. When a newer build of the project takes the deploy over (build.superseded), it follows that build and returns it as build; keep calling with that build from then on.

When it reports success: Right after deployment.completed the URL can still serve the previous version for up to a minute while Cloudflare's edge caches refresh, and page paths redirect (308) to a trailing slash, so fetch with redirects followed (curl -L). Read-only; it never starts or cancels a deploy.

NameRequiredDescriptionDefault
buildNoThe build being published (publish_build returns it as "id:<id>"). Defaults to the project's active build.
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.
wait_secondsNoHow long to wait for the deploy to finish before returning, 0-45 (default 20). 0 returns a snapshot at once.
after_event_idNoOnly report events after this id: pass publish_build's after_event_id, then the after_event_id this tool returned on the previous call. Omit it to see the build's whole event history; completion is then judged from the build status alone.

Output Schema

NameRequiredDescription
doneYesTrue when the publish finished (deployed or failed). With after_event_id only a deploy event after it counts; without, true also when the build is simply not publishing.
nextYes
buildYes
eventsYesNew events since after_event_id, oldest first.
live_urlYes
succeededYesTrue when deployed, false when failed, null while still running.
project_idYes
supersededYesBuilds whose deploy was taken over by a newer build during this call, in order. When a newer build of the project took over, this call followed it, so `build` is the last one followed; empty when nothing was superseded.
after_event_idYesCursor for the next call.
possibly_stuckYesTrue when the build has been publishing with no deploy events for much longer than a deploy takes.
events_truncatedYesTrue when older events were left out to keep the reply short.
waiting_for_startYesTrue when after_event_id was given but the deploy has not started yet: a site rebuild after a post change is queued (up to about 3 minutes unless the account is Pro+) and only then shows events.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnly, idempotent, openWorld, non-destructive), but the description adds real behavioral context beyond them: per-call wait up to wait_seconds with progress notifications, possibly_stuck detection, build supersession handling, and the read-only guarantee ('never starts or cancels a deploy'). It also warns that the URL may serve a stale version for up to a minute after completion and that paths 308-redirect, which an agent cannot infer from annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then usage, then the post-success caveat, so an agent can stop reading early. It is long for a 4-parameter tool and the enumerated event states (queued, built, uploaded, domain wiring...) overlap with output schema detail, but nearly every sentence carries actionable information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, the description need not restate return values, yet it still covers the polling contract, wait semantics, supersession, stuck detection, and post-deploy caching/redirect caveats. Nothing an agent needs to call and correctly interpret this tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 description goes further than the schema by explaining the re-call loop for after_event_id and the consequence of omitting it (whole event history, completion judged from build status alone). It also reinforces wait_seconds defaults and the 0 = snapshot behavior, adding operational meaning beyond the field descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('report the progress of a publish') and enumerates exactly what it returns: build status, deploy events, done flag, live URL. An agent can distinguish it from publish_build/publish_post, which it explicitly names as predecessors rather than equivalents.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit sequencing: call after publish_build or publish_post, pass the build and after_event_id they returned, and re-call with the returned after_event_id until done is true. It also explains the after_event_id contract (only events after it end the wait) and the waiting_for_start/rebuild case, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_file_urlGet a stored file's URLA
Read-onlyIdempotent
Inspect

Get the URL a stored project file is served from, by its filename (as list_files reports it).

Use it when the user wants a link to an uploaded image, or a full URL is needed somewhere a bare filename does not work (for example a post's hero image or an external page). Inside .page markup, prefer the bare filename (img: <- hero.webp), which survives re-uploads.

It does not upload or list files (use upload_asset / list_files). Read-only.

NameRequiredDescriptionDefault
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.
filenameYesStored filename exactly as list_files reports it, e.g. "hero.webp".

Output Schema

NameRequiredDescription
urlYes
file_idYes
filenameYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful behavioral context: that it neither uploads nor lists files, and that returned URLs are not re-upload-safe in markup. The trailing 'Read-only.' merely repeats the annotation, but the rest earns credit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then usage, then exclusions — a sensible order with no filler. It is slightly longer than needed because 'Read-only' duplicates the annotation and the alternative-markup point is repeated in spirit, but nothing is wasted on noise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained. For a 2-parameter read tool the description covers purpose, invocation trigger, exclusions, and the markup caveat — everything an agent needs to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already fully documented, including the filename-must-match-list_files-output constraint and the flexible project identifier formats. The description adds no syntax or format detail 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.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Get the URL a stored project file is served from') and immediately binds it to an input key ('by its filename, as list_files reports it'). It is clearly distinguishable from siblings like upload_asset, list_files, and get_page_source.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use context (user wants a link to an uploaded image; a bare filename won't work) plus an explicit when-not-to-use alternative inside .page markup (prefer the bare filename, which survives re-uploads). It also names the adjacent tools for upload/list so the agent can route correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_markup_referenceGet the .page markup referenceA
Read-onlyIdempotent
Inspect

Return micropage reference text: the .page grammar, the full reference, the posts format, the agent editing guide, the example index, or one complete example file.

Call this before writing or editing .page markup (and before drafting a post), unless you already have the grammar in context. The vocabulary is closed: tags that are not in the grammar are not rendered, so never guess. Start with topic "grammar"; use "examples_index" then "example" to copy a layout close to what the user wants.

This mirrors the micropage://grammar, micropage://grammar/full, micropage://posts/format, micropage://agent-guide and micropage://examples/{name} resources, for hosts that do not read resources. Local and read-only: no network call, no account needed.

NameRequiredDescriptionDefault
topicNoWhat to return. grammar: the short .page grammar (start here). grammar_full: the complete reference. posts_format: post fields and lifecycle. agent_guide: editing rules. examples_index: example names. example: one example file (set `example`). Defaults to grammar, or to example when `example` is set.
exampleNoExample name, used with topic "example". One of: agency-portfolio, blog-publication, components-colors, components-hero-variants, components-pricing-and-forms, devtool-docs, event-conference, mobile-app-landing, portfolio, restaurant-landing, startup-landing.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/openWorld=false, but the description adds genuinely new context: it is local, needs no network or account, and mirrors specific micropage:// resources for hosts that cannot read resources. It also discloses a hard constraint (unlisted tags are not rendered) that the agent cannot infer from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the return value, then usage conditions, then the topic workflow, then the local/read-only note. Every sentence carries distinct information; nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by enumerating exactly what each topic returns. Combined with the closed-vocabulary warning, the local/read-only note, and the resource-mirroring explanation, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the enum values and defaults are already documented and the baseline is 3. The description still adds selection guidance beyond the schema by prescribing a workflow order ('grammar' first, then 'examples_index' -> 'example' to copy a nearby layout), which clarifies which topic to pick in practice.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb (return) plus an enumerated resource set: the .page grammar, full reference, posts format, agent guide, example index, or a single example file. This is clearly distinguishable from every sibling, which are project/page/post/build/asset operations rather than a documentation lookup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use: 'Call this before writing or editing .page markup (and before drafting a post), unless you already have the grammar in context.' It also prescribes a sequence ('Start with topic "grammar"; use "examples_index" then "example"') and warns against guessing because the vocabulary is closed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_page_sourceRead a project's .page sourceA
Read-onlyIdempotent
Inspect

Return the raw .page markup of a micropage project's active build (or of a given build number), plus its stored llms.txt and the filenames uploaded to the project.

Call it before editing an existing site: change the returned source and send the whole file back with save_page as landing.page. Pass version to read an older build, e.g. to restore it. The source was merged from all .page files when saved, so it comes back as one file.

Read-only; it does not show what is live (get_project tells you which build is deployed) and does not download images.

NameRequiredDescriptionDefault
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.
versionNoWhich build's source to read: a build number ("v12" or 12) or id ("id:4567"). Defaults to the active build (the draft or published build the editor and CLI work on), else the latest build.

Output Schema

NameRequiredDescription
buildYesNull when the project has no builds yet.
assetsYesFilenames uploaded to the project, usable as `img: <- filename`. Null if the list could not be read.
sourceYesThe raw .page markup. Several files were merged into one when saved; edit it as landing.page.
projectYes
llms_txtYesThe site's /llms.txt as stored on this build, if any.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only, idempotent, non-destructive profile, so the description's value is in the extra behavioral detail: the source is merged from all .page files when saved and returns as one file, it does not reveal what is live, and it does not download images. These are genuinely useful, non-obvious traits; only return-format/pagination behavior is left unstated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight paragraphs, front-loaded with what is returned, then the workflow, then the explicit exclusions. Every sentence carries distinct information and nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and the description still covers the merge behavior, version defaulting, and the two things it deliberately does not surface. Nothing an agent needs before calling it is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 both parameters thoroughly, including the accepted project identifier forms and the version build-number/id syntax. The description only adds that version can be used to restore an older build, which is marginal beyond the schema and leaves the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Return the raw .page markup of a micropage project's active build') and enumerates the full payload (source, stored llms.txt, uploaded filenames). It is clearly distinguishable from get_project and save_page, which it names by contrast.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to call it ('Call it before editing an existing site: change the returned source and send the whole file back with save_page') and when its sibling is the right tool instead ('get_project tells you which build is deployed'). The version parameter's use case (restoring an older build) is also stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_projectShow one micropage projectA
Read-onlyIdempotent
Inspect

Show one micropage project in detail: live URL, editor URL, the active build (the default publish target), the latest build, the build that is live now, the failure reason if a build failed, and read-only custom-domain status (Cloudflare hostname and certificate state, and the CNAME target).

Use it to check what is live versus drafted before publishing, to explain why a build failed, or to answer "is my custom domain working?". Accepts the project's uuid, numeric id, micropage domain ("acme" or "acme.micropage.sh") or custom domain.

It does not return the page source (use get_page_source) or follow a deploy in progress (use get_deploy_status), and it cannot change the custom domain; that is done in the micropage editor.

NameRequiredDescriptionDefault
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.

Output Schema

NameRequiredDescription
projectYes
active_buildYesThe build the editor and CLI work on; publish_build's default.
latest_buildYesThe highest-numbered build.
custom_domainYes
failure_reasonYesWhy the active or latest build failed, when it did.
last_deployed_buildYesWhat is live right now, if anything was ever deployed.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered; the description still adds useful behavior by flagging that custom-domain status is read-only and that it will not follow an in-progress deploy. Much of the remaining text restates what the output schema already returns, so it stops short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight paragraphs are front-loaded with the payload and then move to usage and exclusions, with no filler sentences. Minor redundancy in listing three separate build fields (active/latest/live) inflates the first sentence slightly, but each clause carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with an output schema and rich annotations, this is complete: identifier formats, return contents, use cases, and explicit non-capabilities are all covered. Nothing an agent needs to call it correctly or interpret a failure is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the sole parameter's schema text already documents uuid, numeric id, micropage hostname and custom domain plus 'get valid values from list_projects'. The description repeats these accepted forms but adds no new syntax, defaults, or constraints, so the baseline 3 for schema-documented parameters applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (show one micropage project in detail) and enumerates the concrete payload: live URL, editor URL, active/latest/live build, failure reason, and read-only custom-domain status. It is immediately distinguishable from siblings like get_page_source and get_deploy_status because it names them as the wrong tool for those needs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives three concrete scenarios (check live vs drafted before publishing, explain a failed build, answer 'is my custom domain working?') plus explicit exclusions routing to get_page_source and get_deploy_status. It also notes the mutating action (changing the custom domain) must happen in the editor, so an agent knows when this tool is and is not the right call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_buildsList a project's buildsA
Read-onlyIdempotent
Inspect

List a micropage project's builds, newest first: number, id, status (draft, publishing, deployed, failed), created and updated times, failure reason, and which build is active.

Use it to find a build to roll back to with publish_build, to see why a publish failed, or to check whether a publish is still running. Each save_page that cannot overwrite a draft adds a build; publishing reuses the build.

Read-only. To read a build's source use get_page_source with its number; for what is live right now use get_project.

NameRequiredDescriptionDefault
limitNoHow many builds to return, newest first (default 20, max 100).
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.

Output Schema

NameRequiredDescription
countYes
buildsYes
project_idYes
active_build_idYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, and the description confirms 'Read-only'. It goes further by explaining the build lifecycle — each save_page that cannot overwrite a draft adds a build while publishing reuses it — which is real context not present in annotations or schema. It stops short of describing pagination or ordering guarantees beyond 'newest first'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight paragraphs: what it returns, when to use it plus lifecycle semantics, then explicit navigation to alternatives. Front-loaded with the verb and resource, no filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema exists so return-format explanation is optional, yet the field list is still summarized. Combined with usage routing, lifecycle context, and full schema coverage, an agent has everything needed to select and invoke this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters (limit, project) are fully documented in the schema itself, including accepted project identifier forms and the default/max for limit. The description adds no parameter-level detail, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List a micropage project's builds') and immediately enumerates the returned fields (number, id, status values, timestamps, failure reason, active flag), which distinguishes it from sibling list tools like list_projects and get_deploy_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives three concrete use cases (find a build to roll back to with publish_build, diagnose a failed publish, check whether a publish is still running) and explicitly routes elsewhere when appropriate: get_page_source for a build's source, get_project for what is live now.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_filesList a project's filesA
Read-onlyIdempotent
Inspect

List the files stored in a micropage project (images uploaded by upload_asset, the editor or the CLI), newest first: filename, type, size, SHA-256 and upload date, plus storage used and the plan's storage limit.

Use it to see which filenames .page markup can reference with img: <- name, to check whether an image is already uploaded, or to check remaining storage before uploading large images.

It does not return file URLs (use get_file_url for one) or upload anything (use upload_asset). Read-only.

NameRequiredDescriptionDefault
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.

Output Schema

NameRequiredDescription
countYes
filesYesNewest first.
limit_mbYesThe plan's storage limit for this project.
used_bytesYes
limit_bytesYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the full safety profile (read-only, idempotent, non-destructive), so the trailer 'Read-only' is somewhat redundant. However, the description adds genuinely useful behavioral context beyond the annotations: the ordering (newest first), the metadata fields returned, storage accounting versus the plan limit, and what is NOT returned (no file URLs, no uploads).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The primary purpose and returned fields are front-loaded, followed by use cases and then explicit exclusions. Three short paragraphs, each sentence carrying information, no padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be explained, yet the description still summarizes them. Combined with annotations covering safety and the schema covering the parameter, an agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There is a single `project` parameter at 100% schema description coverage, so the schema already documents the accepted identifier forms and points to list_projects. The description adds no parameter-level detail beyond restating the project context, matching the baseline 3 when schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource — listing files in a micropage project — plus the scope (newest first) and the returned fields. It explicitly distinguishes itself from siblings like get_file_url and upload_asset, so an agent can identify it without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives three concrete when-to-use cases (finding referencable filenames for .page markup, checking whether an image is uploaded, checking remaining storage) and names explicit alternatives for the excluded behaviors (get_file_url for one URL, upload_asset for uploading). Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_formsList a project's formsA
Read-onlyIdempotent
Inspect

List the forms on a micropage project's site (registered when the page markup is saved): form uuid, name, page, whether it is the site footer form, and how many submissions each has, not counting spam.

Use it to answer "how many signups/messages did my site get?", to find a form's uuid or name before reading its submissions, or to check that a form added in the markup was registered after save_page.

It returns counts only, never what visitors typed (that is list_submissions, which the user must enable). Read-only.

NameRequiredDescriptionDefault
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.

Output Schema

NameRequiredDescription
countYes
formsYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotentHint/destructiveHint, so the safety profile is covered. The description adds genuinely new behavior: only registered forms appear (registered at markup save), spam is excluded from counts, and nothing visitor-typed is ever returned. The closing "Read-only" merely restates the annotation, keeping this just short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight paragraphs, front-loaded with the resource and returned fields, then usage, then the count-only caveat. Every sentence carries information, though the trailing "Read-only." duplicates the annotation and is minor waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, yet the description still usefully summarizes what comes back (counts, not visitor content) and warns about spam exclusion and the registration prerequisite. For a one-parameter read tool, nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single `project` parameter is fully documented in the schema, including accepted formats and the pointer to list_projects. The description adds no parameter-level meaning beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (list the forms on a project's site) and enumerates the exact fields returned: uuid, name, page, footer-form flag, and non-spam submission counts. It explicitly distinguishes itself from list_submissions, so an agent can separate it from its siblings without reading any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives three concrete triggering scenarios (answering "how many signups/messages did my site get?", finding a form's uuid/name before reading submissions, verifying a markup-added form registered after save_page) and names the alternative tool (list_submissions) with the requirement that the user enable it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_postsList or read micropage postsA
Read-onlyIdempotent
Inspect

List a project's posts (blog posts and newsletter emails), or read one in full.

Without slug: every post, newest first, with slug, title, visibility, whether it is published and when, whether publishing emails it, and the newsletter list name. With slug: that post in full, including body_markdown and every field under the same names upsert_post takes (title, description, visibility, hero, email, list, subject, preview).

Call it with a slug before editing a post: upsert_post replaces every field, so start from the current values, and pass the post's revision back to upsert_post. It does not say who will receive an email; preview_post_send does that. Read-only.

NameRequiredDescriptionDefault
slugNoOmit to list every post. Pass a slug to get that one post in full, including body_markdown and every field upsert_post takes.
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.

Output Schema

NameRequiredDescription
postNoThe one post asked for (slug mode).
countNoNumber of posts (list mode).
postsNoEvery post, newest first (list mode).
projectYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotent/non-destructive, so the description's "Read-only" is partly redundant. However, it adds real behavioral context: the default sort (newest first), the exact fields returned in list vs. full mode, and the critical warning that upsert_post overwrites all fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core duality in the first sentence, then conditional return details, then the workflow warning. Dense but each sentence carries information, though the second sentence enumerating returned fields is somewhat heavy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite an output schema existing, the description is complete: an agent knows the two modes, the default ordering, the returned fields, and the prerequisite workflow before editing. Nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 both `slug` and `project` thoroughly. The description's explanation of the slug toggle (list vs. full read) largely restates the schema, adding only the workflow note about passing the revision back.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific dual purpose: list a project's posts (blog posts and newsletter emails) or read one in full, tied directly to presence/absence of `slug`. It clearly distinguishes itself from siblings like upsert_post, preview_post_send, and delete_post.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides explicit when-to-use guidance: call with a slug before editing, because upsert_post replaces every field and you must pass the current revision back. It also names the alternative for a related need (preview_post_send for who receives an email).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_projectsList micropage projectsA
Read-onlyIdempotent
Inspect

List every micropage project in the signed-in account: uuid, numeric id, name, micropage domain, custom domain, live URL, editor URL, and the status and number of each project's active build.

Use it to find the project value other tools need (uuid, id or domain all work), or when the user refers to a site by name and you do not know which project it is. The active build is the one the editor and CLI work on; it can be a draft newer than what is live, so call get_project for what is actually deployed, failure reasons and custom-domain status.

Read-only. Not available with a deploy token, which is limited to its one project.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
countYes
projectsYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile, but the description adds genuinely new context: the active build may be a draft newer than what is live, and the tool is unavailable to deploy tokens. It stops short of describing pagination or account-scale behavior, which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then usage, then caveats, with no filler. The long enumeration of returned fields is partly redundant given an output schema exists, which is the only mild inefficiency.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read tool with an output schema and rich annotations, nothing an agent needs is missing: it knows what comes back, when to call it, when to prefer get_project, and the auth limitation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, so there is nothing for the description to disambiguate; the baseline of 4 applies. The note that 'uuid, id or domain all work' is useful cross-tool semantics even though it is not a formal parameter here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('List every micropage project') and enumerates exactly what comes back, which lets an agent distinguish it from get_project and list_builds without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names two use cases (resolving a `project` value for other tools; identifying a project from a user-supplied site name) and routes the agent elsewhere when it needs deploy truth: 'call get_project for what is actually deployed, failure reasons and custom-domain status.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

preview_post_sendPreview publishing a postA
Read-onlyIdempotent
Inspect

Show what publish_post would do for one post, and get the confirmation_token publish_post requires. Call it before every publish and show the user the result.

Reports whether publishing emails the newsletter list, the list name, the number of active subscribers it would go to, whether publishing is a re-send (the post is already published, or was emailed before and has since been unpublished; either way publishing emails the whole list again), and whether this server is allowed to send email (MICROPAGE_MCP_ALLOW_SEND).

The token is tied to the post as it is now: any edit to the post (upsert_post) or to its list invalidates it, and it expires after 15 minutes or when the server restarts. Read-only: nothing is published or sent.

NameRequiredDescriptionDefault
slugYesThe post's slug, as list_posts shows it (e.g. "launching-new-dashboard"). Normalised like the CLI does.
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.

Output Schema

NameRequiredDescription
listYes
postYes
projectYes
will_emailYesTrue when publishing emails the list (email enabled and a list set).
send_allowedYesMICROPAGE_MCP_ALLOW_SEND is set, so this server may email subscribers.
blocked_reasonYes
resend_warningYesSet when publishing would email a post that is already published or was emailed before: a RE-SEND to the whole list.
already_emailedYesTrue when the post has been emailed before, even if it was unpublished since. Unpublishing does not recall or reset a send.
publish_allowedYesWhether publish_post will go ahead for this post on this server.
recipient_countYesActive subscribers on the list right now; 0 when nothing is emailed.
already_publishedYes
confirmation_tokenYesPass to publish_post. Invalid once the post changes, or after expires_in_seconds.
expires_in_secondsYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false), but the description adds substantial behavioral detail beyond them: token lifetime (15 minutes, invalidated on restart or any edit via upsert_post/list change), re-send detection logic (already-published or emailed-then-unpublished re-emails the whole list), and the MICROPAGE_MCP_ALLOW_SEND gate. This is meaningful context an agent needs before calling publish_post, though return-value specifics are left to the output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and the token, then a dense but useful second paragraph on token semantics. Each sentence earns its place, though the run-on sentence about re-send detection is slightly heavy and could be tightened.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only preview tool with an output schema, the description covers the decision-relevant facts: what the preview reports, the token's lifecycle and invalidation triggers, and the send-permission gate. Nothing an agent needs to call it correctly or interpret the result is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters (project, slug) are already fully documented in the schema, including accepted formats and the normalisation behaviour. The description adds nothing param-specific, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Show what publish_post would do') and resource (one post), plus the concrete artifact it returns (confirmation_token). It distinguishes itself cleanly from the sibling publish_post by framing itself as the preview/token-acquisition step rather than the action itself.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit directive: 'Call it before every publish and show the user the result.' It also implies the relationship to publish_post (which requires the token), so the agent knows exactly when this tool applies versus the sibling that performs the send.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

publish_buildPublish a build to the live siteA
Destructive
Inspect

Deploy a micropage build to the project's public URL. This changes what visitors see, so only call it when the user explicitly asks to publish, and pass confirm: true.

Defaults to the active build (the draft save_page just wrote); pass build with the id save_page returned to be exact, or an older build number to roll back to it (that build becomes active). Refused while another build of the project is still publishing.

It returns at once with status publishing, after_event_id and an ETA (builds wait about 3 minutes in the queue unless the account is Pro+). Then call get_deploy_status with that build and after_event_id to follow it to the end. It does not save source; call save_page first.

NameRequiredDescriptionDefault
buildNoWhich build to publish: the id save_page returned ("id:4567") or a build number ("v12" or 12). Defaults to the project's active build. Naming an older build republishes that snapshot and makes it the active build.
confirmNoMust be true. Publishing changes the public site; ask the user before setting it.
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.

Output Schema

NameRequiredDescription
etaYes
nextYes
buildYes
statusYes
live_urlYes
plan_tierYes
project_idYes
eta_secondsYesRough time until the site is live.
after_event_idYesPass to get_deploy_status so it only reports events from this publish.
active_build_changedYesTrue when the named build was not the active build and was made active.
previous_active_build_idYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (destructive, non-idempotent, open-world), and the description adds substantial behavioral context beyond them: the operation is refused while another build is publishing, it returns immediately with status/after_event_id/ETA, queue time is about 3 minutes unless Pro+, and naming an older build makes it the active build. This is exactly the kind of beyond-schema disclosure that helps an agent sequence calls correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The most consequential fact, that this changes what visitors see, is front-loaded in the first sentence. Subsequent sentences are dense with operational facts (confirmation, build targeting, refusal condition, async return, next call, save_page dependency) and none are filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even though an output schema exists, the description pre-announces the async contract (status publishing, after_event_id, ETA) and the follow-up tool, which is essential for correct orchestration. Prerequisites, authorization/confirmation, and failure mode are all covered, leaving nothing an agent needs missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 description adds real semantics: build defaults to the active build (the one save_page just wrote), accepts an id or older build number to roll back and re-activate, and confirm must be true. It complements rather than merely repeats the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Deploy a micropage build to the project's public URL') plus the consequence ('changes what visitors see'), which immediately distinguishes it from siblings like save_page or preview_post_send. The rollback capability is also named, so an agent knows the full scope of the operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly gates invocation ('only call it when the user explicitly asks to publish, and pass confirm: true') and names prerequisites and follow-ups: call save_page first because it does not save source, then call get_deploy_status with the returned build and after_event_id. The refusal condition (another build still publishing) is also spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

publish_postPublish a micropage post (may send email)A
Destructive
Inspect

Publish a post: put it live on the site under /content and, if it has email enabled with a list, email it to every active subscriber on that list. Publishing a post that is already published, or that was emailed before and has since been unpublished, re-sends the email to the whole list. Same as micropage posts publish <slug>.

Needs the confirmation_token from preview_post_send, taken after the post's last change; show the user that preview and get their go-ahead first. A stale or missing token is refused with nothing changed.

Posts that would send email are refused unless the user has set MICROPAGE_MCP_ALLOW_SEND=1 in this server's config; there is no web-only override, so to publish such a post on the web only, save it with email: false first. When the client supports it the user is also asked to confirm the send directly. The site rebuild redeploys the live build, so an unpublished page draft left by save_page or the editor stays a draft. It returns build_id and after_event_id to follow the rebuild with get_deploy_status. Use unpublish_post to take a post down.

NameRequiredDescriptionDefault
slugYesThe post's slug, as list_posts shows it (e.g. "launching-new-dashboard"). Normalised like the CLI does.
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.
confirmation_tokenYesThe confirmation_token from preview_post_send for this post, taken after its last change and shown to the user.

Output Schema

NameRequiredDescription
noteYes
slugYes
emailedYes
post_idYes
projectYes
build_idYesThe build the site rebuild redeploys: the live one, not an unpublished page draft. Pass to get_deploy_status; null when nothing was rebuilt.
published_atYes
after_event_idYesPass to get_deploy_status with build_id to see only events from this rebuild.
rebuild_queuedYesTrue when a site rebuild was queued so the post appears under /content.
recipient_countYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=true and idempotentHint=false, and the description substantiates why: re-publishing or re-publishing an unpublished post re-blasts email to the entire list. It also discloses the env-var gate with no web-only override, that stale tokens are refused with nothing changed, and the returned build_id/after_event_id handles. This is well beyond what annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action and its email blast are front-loaded, then preconditions, gates, and return values follow. It is long (~200 words) but nearly every sentence carries a distinct constraint; only mild redundancy in restating the token requirement from the schema keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers preconditions, the non-idempotent re-send behavior, the environment gate with its override workaround, draft-handling during the rebuild, and follow-up via get_deploy_status. With an output schema present and detailed param descriptions, nothing material is missing for a destructive, email-sending action.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters are already documented, including the confirmation_token provenance. The description reinforces the token's freshness requirement but adds little syntax or format detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Publish a post: put it live on the site under /content') plus the consequential side effect (email to every active subscriber). It distinguishes itself from unpublish_post and maps to the CLI equivalent, so an agent can place it immediately among its siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states the precondition chain: get confirmation_token from preview_post_send after the last change, show the preview, get user go-ahead. It also names the refusal conditions (stale/missing token, MICROPAGE_MCP_ALLOW_SEND unset), the workaround to publish web-only (save with email: false), and the inverse tool unpublish_post.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_pageSave .page source as a draftA
Destructive
Inspect

Compile .page markup and save it as the project's draft build. It never goes live until publish_build deploys it: call publish_build only when the user asks. Post changes rebuild the live site, not this draft.

Pass the whole site source each time (pages: [{ name: "landing.page", content }], extra .page files are merged after it by name). If the project's active build is a draft or a failed build it is overwritten; otherwise a new draft is created and made active. Returns the build id and number, compiler issues (such as a missing image file) and the editor URL where the user can preview the draft; drafts have no public URL.

Images are not uploaded here: call upload_asset first, then reference the file with img: <- filename. Call get_markup_reference before writing markup you are unsure of. Saving also registers the source's forms on the project.

NameRequiredDescriptionDefault
pagesYesThe whole site source as one or more .page files, merged like the CLI does (landing.page first, then the others by name, a blank line between). Pass every file each time: this replaces the source, it does not patch it.
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.
llms_txtNoThe site's /llms.txt, stored verbatim. Omit to keep the current build's llms.txt; pass an empty string to remove it.

Output Schema

NameRequiredDescription
liveYesAlways false: save_page never changes the live site; the draft goes live only with publish_build.
nextYes
buildYes
actionYesupdated_draft: the active draft (or failed build) was overwritten. created_draft: a new draft was made active.
issuesYesProblems the compiler flagged, e.g. a referenced file that does not exist. Fix them before publishing.
projectYes
live_urlYesThe public URL; it still shows the last published build.
llms_txtYes
page_countYes
preview_urlYesWhere the user can preview this draft: the project in the micropage editor.
previous_active_build_idYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, but the description goes further by specifying what is destroyed (an active draft or failed build is overwritten, otherwise a new draft is created and made active), that drafts have no public URL, that the source is replaced not patched, and that saving registers forms. This is concrete mutation semantics beyond the annotation flags, with no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and the publish boundary, then prerequisites, then return/merge details. It is longer than most definitions but nearly every sentence carries a distinct fact; minor redundancy exists because the landing.page-first merge rule appears in both the description and the pages schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even though an output schema exists, the description summarizes the return (build id and number, compiler issues, editor URL) to support the downstream publish workflow, and it covers prerequisites, overwrite behavior, and side effects. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 and the schema already carries merge order and replacement semantics. The description adds usable guidance the schema does not: the inline `img: <- filename` asset reference pattern, the requirement to pass every file each time, and that forms are registered as a side effect of the pages payload.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Compile .page markup and save it as the project's draft build') and immediately draws the boundary against the sibling that publishes it (publish_build). An agent can distinguish save_page from publish_build, upsert_post, and upload_asset without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing: call publish_build only when the user asks, call upload_asset first for images, call get_markup_reference when unsure of markup. It also states when NOT to expect a live result ('Post changes rebuild the live site, not this draft'), which is exactly the discrimination an agent needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unpublish_postUnpublish a micropage postA
Destructive
Inspect

Take a published post off the site: its page 404s and it goes back to draft. The post itself is kept and can be published again later; emails already sent are not recalled. Same as micropage posts unpublish <slug>.

Needs confirm: true, which you should only pass after the user has agreed. Queues a site rebuild when the project has been published. The site rebuild redeploys the live build, so an unpublished page draft left by save_page or the editor stays a draft. It returns build_id and after_event_id to follow the rebuild with get_deploy_status. To remove a post for good use delete_post instead.

NameRequiredDescriptionDefault
slugYesThe post's slug, as list_posts shows it (e.g. "launching-new-dashboard"). Normalised like the CLI does.
confirmNoMust be true. Ask the user first: this changes the live site.
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.

Output Schema

NameRequiredDescription
slugYes
post_idYes
projectYes
build_idYesThe build the site rebuild redeploys: the live one, not an unpublished page draft. Pass to get_deploy_status; null when nothing was rebuilt.
unpublishedYes
after_event_idYesPass to get_deploy_status with build_id to see only events from this rebuild.
rebuild_queuedYesTrue when a site rebuild of the live build was queued to take the post down.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, but the description goes further and discloses what is and isn't destroyed (post kept, republishable), that sent emails are not recalled, that a site rebuild is queued when the project is published, and that drafts from save_page stay drafts. That is meaningful side-effect disclosure beyond the annotation flags.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the effect and the permanence distinction, and every sentence carries information. It is somewhat dense and the CLI equivalence line is marginal, but nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation with a rebuild side effect, it covers reversibility, retained data, the confirm gate, and names build_id/after_event_id plus get_deploy_status for follow-up. With an output schema present, no return-value explanation is owed, so nothing an agent needs is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 still adds value by clarifying that confirm=true must only be passed after user agreement, which is a behavioral constraint the schema states only tersely.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource plus the observable effect: the page 404s and the post returns to draft. It also distinguishes itself from delete_post by noting the post is kept and can be republished, so an agent can separate it from siblings without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit routing: use this to unpublish, use delete_post to remove for good, and publish_post is the inverse. It also states the confirm precondition and when it can be passed, which is exactly the when/when-not guidance an agent needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

upload_assetUpload an image assetA
DestructiveIdempotent
Inspect

Upload one image (.png, .jpg, .jpeg, .gif, .webp, .ico, .svg; max 10 MB) to a micropage project's file storage, from a local file path, a public https URL, or base64 bytes. Returns the stored filename, the markup to reference it (img: <- hero.webp) and its URL.

Use it BEFORE save_page or upsert_post reference the image: page markup like img: <- hero.webp and a post's hero: hero.webp only resolve to files already stored in the project, and a missing name renders no image. Upload each asset once; calling again with identical content is a no-op (deduped: true, same SHA-256 as the CLI uses).

Uploading different content under an existing name deletes the old file and stores the new one. A page that is already live keeps pointing at the old file until it is saved and published again, so re-run save_page and publish_build after replacing an image on a live site. Prefer a new filename to avoid that.

Do not use it for non-image files (unsupported), for images already hosted elsewhere that markup can reference by full https URL, or to look up existing files (use list_files). Fails with the plan's storage limit when the project is full.

NameRequiredDescriptionDefault
sourceYesWhere the bytes come from: exactly one of {path}, {url} or {base64}. Max 10 MB. The content must really be the image type the filename's extension says.
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.
filenameYesName to store the asset under, e.g. "hero.webp". A bare name (no folders) with one of: .png, .jpg, .jpeg, .gif, .webp, .ico, .svg. This is the name .page markup references, as in `img: <- hero.webp`.

Output Schema

NameRequiredDescription
urlYesWhere the stored file is served from.
markupYesReady-to-use markup line, e.g. `img: <- hero.webp`.
dedupedYesTrue when an identical file was already stored under this name; nothing was uploaded.
file_idYes
filenameYesStored name. Reference it in .page markup as `img: <- <filename>`.
replacedYesTrue when a different file with this name was deleted and replaced. A live page keeps the old reference until republished.
mime_typeYes
size_bytesYes
content_hashYesSHA-256 of the bytes, used for dedupe.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare destructiveHint/idempotentHint/openWorldHint, yet the description adds substantial non-annotation context: dedup/no-op on identical content, that overwriting a name deletes the old file, that already-live pages keep pointing at the old file until save_page + publish_build re-run, and that it fails against the plan's storage limit. This exceeds the annotation bar.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with what it does and formats/sources, then ordered constraints (use-before-save, dedup, overwrite semantics, exclusions, failure mode). The four paragraphs are dense but every sentence carries an actionable fact.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, yet the description still orients the agent with the ordering constraint, overwrite consequence, dedup semantics, and failure mode. For a 3-param mutation with rich annotations, nothing necessary for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the source union variants, the 20 s URL timeout, and the path being local-stdio-only, so the schema already carries parameter meaning. The description largely restates the source options and the filename/markup relationship that the schema also documents, adding little new per-parameter detail. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Upload one image ... to a micropage project's file storage') and enumerates accepted formats, size cap, and the three accepted sources. An agent can distinguish it from list_files, get_file_url, and save_page without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use ('Use it BEFORE save_page or upsert_post reference the image') plus explicit when-not-to ('Do not use it for non-image files, ... images already hosted elsewhere that markup can reference by full https URL, or to look up existing files (use list_files)'). It names the alternative sibling for the lookup case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

upsert_postCreate or update a micropage postA
Destructive
Inspect

Create or update one post (a blog post under /content and/or a newsletter email), keyed by slug: an existing slug is updated, a new one is created as a draft. Same as micropage posts push for one file; the arguments are the post front-matter fields plus body_markdown (see the micropage://posts/format resource).

Every call replaces the whole post: an omitted optional field (description, hero, subject, preview, email/list) is cleared. The exception is date (the post's public date, past or today): omitted, the post keeps its current date. To edit, read the post with list_posts(slug) first and pass everything back, with its revision: if the post changed since that read (in the editor, the CLI or another session), the save is refused with REVISION_CONFLICT and nothing is written; re-read it, merge, and save again.

Saving never sends email and never publishes a draft. But if the post is already published, the save changes the live page at once and rebuilds the site, so it needs confirm_live_update: true after the user agrees. The site rebuild redeploys the live build, so an unpublished page draft left by save_page or the editor stays a draft. It returns build_id and after_event_id to follow the rebuild with get_deploy_status. When every field already matches the saved post (a date that keeps the current one counts as matching), nothing is written, no rebuild is queued, no confirmation is needed, and action is "unchanged".

Images are not uploaded here. For the hero pass an https URL or the filename of an asset uploaded with upload_asset; inside body_markdown use hosted URLs only (upload_asset, then get_file_url). To publish afterwards use preview_post_send, then publish_post.

NameRequiredDescriptionDefault
dateNoPublic date of the post, YYYY-MM-DD (midnight UTC) or ISO 8601 (2026-10-01T09:30:00Z; no offset means UTC). Sets the published date; past or today only (scheduling is not supported). On a draft it is held until the first publish. Unlike the other optional fields, omitting it leaves the post's date unchanged.
heroNoHero image: an https URL, or the filename of an asset already uploaded to this project (call upload_asset first for a new image). Omitted clears it.
listNoNewsletter form name to send to (case-insensitive exact match). Required with email: true; only allowed with it.
slugNoURL slug, unique per project; the post lives at /content/<slug>. Defaults to the slugified title. The slug picks which post is updated: an existing slug updates that post, a new one creates a post.
emailNotrue makes the post an email to `list` when it is published (saving never sends). Default false: web only.
titleYesPost title. Required.
previewNoEmail preheader / inbox preview text.
projectYesWhich project: its uuid, its numeric id, its micropage hostname ("acme" or "acme.micropage.sh") or its custom domain ("www.acme.com"). A full URL also works. Get valid values from list_projects.
subjectNoEmail subject. Defaults to the title.
revisionNoThe revision from list_posts; pass it when editing an existing post so a change made since your read is not overwritten. 0 means the post must not exist yet. Omitted, the post's revision at save time is used.
visibilityNolisted (default): shown in the site's /content index. unlisted: has a page but is not listed.
descriptionNoWeb summary for the /content archive, meta description and og tags. Omitted clears it.
body_markdownYesPost body in Markdown. Images must already be hosted URLs: upload each image with upload_asset, get its URL with get_file_url, and write ![alt](https://...). Local paths are not uploaded here and would 404.
confirm_live_updateNoRequired (true) when the post is already published: saving then changes the live page at once and rebuilds the site. Ask the user before setting it.

Output Schema

NameRequiredDescription
heroYes
listYes
slugYes
emailYes
actionYesunchanged: every field already matched the saved post, so nothing was written and no rebuild was queued.
post_idYes
projectYes
build_idYesThe build the site rebuild redeploys: the live one, not an unpublished page draft. Pass to get_deploy_status; null when nothing was rebuilt.
revisionYesThe post's revision after this call; pass it as `revision` on the next edit.
warningsYes
publishedYesTrue when the post is live, so a save (other than an unchanged one) changed the live page.
after_event_idYesPass to get_deploy_status with build_id to see only events from this rebuild.
rebuild_queuedYesTrue when the save queued a site rebuild (only for published posts).

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only flag destructive/idempotent/openWorld; the description adds far more: full-replace semantics (omitted optional fields are cleared), the date exception, REVISION_CONFLICT behavior with nothing written, that live published posts change immediately and rebuild the site, that email is never sent on save, and the 'unchanged' no-op path.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Long, but the length is earned by genuinely complex behavior (replace semantics, revisions, live rebuilds, no-op detection) and the purpose is front-loaded. A few clauses (site rebuild redeploy details) could be tightened, but nothing is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers prerequisites, conflict handling, confirmation gating, image handling, and follow-up tools (get_deploy_status), and the output schema carries the return shape. For a 14-parameter mutation tool this is essentially complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 description adds cross-field meaning beyond the schema: slug determines which post, revision enforces optimistic concurrency, confirm_live_update is gated on already-published state, and the date-omitted exception is called out. It doesn't restate every field, which is fine given the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create or update one post'), names the two artifact types (blog post under /content and/or newsletter email), and explains the slug keying that determines create-vs-update. This clearly distinguishes it from siblings like save_page, publish_post, and delete_post.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: read with list_posts(slug) first and pass back the revision; upload images with upload_asset then get_file_url; publish afterwards via preview_post_send then publish_post. It also states when confirm_live_update is required and when nothing is written.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

whoamiShow the micropage account in useA
Read-onlyIdempotent
Inspect

Report which micropage account this server acts as: email, plan tier, subscription, and whether it runs on the user's micropage login session or on a project deploy token (and if so, which project it is pinned to).

Call it first when a micropage tool fails with a login, session or plan error, or when the user asks which account is connected. It never fails for a missing login: it returns logged_in false and a note saying what the user must do (usually run micropage login in a terminal). It does not log in, log out, or change anything.

Do not call it before every task; the other tools report login and plan problems themselves.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
nameYes
noteYesWhat to tell the user, when something needs their action.
emailYes
user_idYes
auth_modeYes
logged_inYes
paid_planYesEvery tool except whoami and get_markup_reference needs a paid plan.
plan_tierYesNull when it could not be read.
config_pathYesThe CLI session file in use (session mode).
subscriptionYes
pinned_project_uuidYesDeploy-token mode only: the one project this server may touch.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, and the description goes further by disclosing failure semantics ('never fails for a missing login: it returns logged_in false and a note saying what the user must do'), plus an explicit non-effect statement ('does not log in, log out, or change anything'). That is behavioral context beyond what the annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded: what it reports, then when to call it, then when not to. Three short paragraphs with no wasted filler, though enumerating the returned fields is mildly redundant against the existing output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only diagnostic tool with an output schema already documenting return values, the description supplies the missing pieces: trigger conditions, failure behavior, and explicit non-mutation. Nothing an agent needs to call it correctly is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4 and there is nothing schema-side to compensate for. The description accurately implies a no-argument call and instead frames the returned identity fields, which is the relevant semantic content for a parameterless tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Report') and resource ('which micropage account this server acts as') and enumerates exactly what is reported: email, plan tier, subscription, and session vs. deploy-token identity. An agent can distinguish this from any sibling project/page/post tool without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit trigger conditions ('first when a micropage tool fails with a login, session or plan error, or when the user asks which account is connected') and an explicit negative case ('Do not call it before every task; the other tools report login and plan problems themselves'). This is textbook when-to-use / 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.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.12
    • Changedget_deploy_status3 fields changed
      • changedOutput schema / properties / events / items / properties / type / description
        Previous value: -"e.g. build.enqueued, deployment.started, deployment.domain_wiring, deployment.completed, build.failed."New value: +"e.g. build.enqueued, deployment.started, deployment.domain_wiring, deployment.completed, build.failed, or build.superseded (a newer build took this deploy over, or nothing further will deploy)."
      • addedOutput schema / properties / superseded
        Added value: +{
        +  "description": "Builds whose deploy was taken over by a newer build during this call, in order. When a newer build of the project took over, this call followed it, so `build` is the last one followed; empty when nothing was superseded.",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "build_id": {
        +        "type": "number"
        +      },
        +      "reason": {
        +        "description": "publish or live_build_changed.",
        +        "type": [
        +          "string",
        +          "null"
        +        ]
        +      },
        +      "superseded_by_build_id": {
        +        "type": [
        +          "number",
        +          "null"
        +        ]
        +      }
        +    },
        +    "required": [
        +      "build_id",
        +      "superseded_by_build_id",
        +      "reason"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "project_id",
        -  "build",
        -  "events",
        -  "events_truncated",
        -  "after_event_id",
        -  "done",
        -  "succeeded",
        -  "waiting_for_start",
        -  "possibly_stuck",
        -  "live_url",
        -  "next"
        -]New value: +[
        +  "project_id",
        +  "build",
        +  "events",
        +  "events_truncated",
        +  "after_event_id",
        +  "done",
        +  "succeeded",
        +  "waiting_for_start",
        +  "possibly_stuck",
        +  "superseded",
        +  "live_url",
        +  "next"
        +]
    • Changedlist_posts2 fields changed
      • addedOutput schema / properties / post / properties / revision
        Added value: +{
        +  "description": "Changes whenever the post's content is saved. Pass it to upsert_post as `revision` when editing this post.",
        +  "type": [
        +    "number",
        +    "null"
        +  ]
        +}
      • changedOutput schema / properties / post / required
        Previous value: -[
        -  "id",
        -  "slug",
        -  "title",
        -  "visibility",
        -  "published",
        -  "published_at",
        -  "email",
        -  "list",
        -  "send_status",
        -  "recipient_count",
        -  "created_at",
        -  "description",
        -  "body_markdown",
        -  "hero",
        -  "subject",
        -  "preview",
        -  "sent_count"
        -]New value: +[
        +  "id",
        +  "slug",
        +  "title",
        +  "visibility",
        +  "published",
        +  "published_at",
        +  "email",
        +  "list",
        +  "send_status",
        +  "recipient_count",
        +  "created_at",
        +  "description",
        +  "body_markdown",
        +  "hero",
        +  "subject",
        +  "preview",
        +  "sent_count",
        +  "revision"
        +]
    • Changedpreview_post_send3 fields changed
      • addedOutput schema / properties / already_emailed
        Added value: +{
        +  "description": "True when the post has been emailed before, even if it was unpublished since. Unpublishing does not recall or reset a send.",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / resend_warning / description
        Added value: +"Set when publishing would email a post that is already published or was emailed before: a RE-SEND to the whole list."
      • changedOutput schema / required
        Previous value: -[
        -  "project",
        -  "post",
        -  "will_email",
        -  "list",
        -  "recipient_count",
        -  "already_published",
        -  "resend_warning",
        -  "send_allowed",
        -  "publish_allowed",
        -  "blocked_reason",
        -  "confirmation_token",
        -  "expires_in_seconds"
        -]New value: +[
        +  "project",
        +  "post",
        +  "will_email",
        +  "list",
        +  "recipient_count",
        +  "already_published",
        +  "already_emailed",
        +  "resend_warning",
        +  "send_allowed",
        +  "publish_allowed",
        +  "blocked_reason",
        +  "confirmation_token",
        +  "expires_in_seconds"
        +]
    • Changedupsert_post7 fields changed
      • addedInput schema / properties / date
        Added value: +{
        +  "description": "Public date of the post, YYYY-MM-DD (midnight UTC) or ISO 8601 (2026-10-01T09:30:00Z; no offset means UTC). Sets the published date; past or today only (scheduling is not supported). On a draft it is held until the first publish. Unlike the other optional fields, omitting it leaves the post's date unchanged.",
        +  "pattern": "^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{1,9})?)?(Z|[+-]\\d{2}:?\\d{2})?)?$",
        +  "type": "string"
        +}
      • addedInput schema / properties / revision
        Added value: +{
        +  "description": "The revision from list_posts; pass it when editing an existing post so a change made since your read is not overwritten. 0 means the post must not exist yet. Omitted, the post's revision at save time is used.",
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / action / description
        Added value: +"unchanged: every field already matched the saved post, so nothing was written and no rebuild was queued."
      • changedOutput schema / properties / action / enum
        Previous value: -[
        -  "created",
        -  "updated"
        -]New value: +[
        +  "created",
        +  "updated",
        +  "unchanged"
        +]
      • changedOutput schema / properties / published / description
        Previous value: -"True when the post was already live, so this save changed the live page."New value: +"True when the post is live, so a save (other than an unchanged one) changed the live page."
      • addedOutput schema / properties / revision
        Added value: +{
        +  "description": "The post's revision after this call; pass it as `revision` on the next edit.",
        +  "type": [
        +    "number",
        +    "null"
        +  ]
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "project",
        -  "post_id",
        -  "slug",
        -  "action",
        -  "published",
        -  "rebuild_queued",
        -  "build_id",
        -  "after_event_id",
        -  "email",
        -  "list",
        -  "hero",
        -  "warnings"
        -]New value: +[
        +  "project",
        +  "post_id",
        +  "slug",
        +  "action",
        +  "published",
        +  "rebuild_queued",
        +  "build_id",
        +  "after_event_id",
        +  "email",
        +  "list",
        +  "hero",
        +  "revision",
        +  "warnings"
        +]
  2. 1 tool updatev0.1.3
    • Changedwhoami1 field changed
      • changedOutput schema / properties / auth_mode / enum
        Previous value: -[
        -  "session",
        -  "deploy_token",
        -  "none"
        -]New value: +[
        +  "session",
        +  "deploy_token",
        +  "oauth",
        +  "none"
        +]
  3. 20 tool updatesv0.1.0
    • First observedcreate_project
    • First observeddelete_post
    • First observedget_deploy_status
    • First observedget_file_url
    • First observedget_markup_reference
    • First observedget_page_source
    • First observedget_project
    • First observedlist_builds
    • First observedlist_files
    • First observedlist_forms
    • First observedlist_posts
    • First observedlist_projects
    • First observedpreview_post_send
    • First observedpublish_build
    • First observedpublish_post
    • First observedsave_page
    • First observedunpublish_post
    • First observedupload_asset
    • First observedupsert_post
    • First observedwhoami

TDQS

A4.4/5.0

Scored across 20 tools

Disambiguation5/5

Each tool targets a distinct resource-and-action pair (projects, pages/builds, posts, files, forms, reference), and the descriptions actively disambiguate near-neighbors: publish_build vs publish_post, unpublish_post vs delete_post, upload_asset vs list_files vs get_file_url, and get_project vs get_page_source vs list_builds vs get_deploy_status. The explicit 'do not use it for X, use Y' notes leave essentially no room for misselection.

Naming Consistency4/5

Nearly every tool follows a clean snake_case verb_noun pattern (list_projects, get_project, create_project, save_page, publish_post, upsert_post, upload_asset, list_files). Minor deviations are preview_post_send (extra noun) and whoami (no verb), but the convention remains predictable and readable throughout.

Tool Count4/5

At 20 tools the set sits at the upper end of the comfortable range, but the domain is genuinely broad (projects, builds, posts/newsletters, assets, forms, reference), so most tools earn their place. It is slightly heavy but not inflated with redundant variants.

Completeness4/5

Core lifecycles are well covered: posts have full create/read/update/publish/unpublish/delete, pages have save/read/publish/list-builds, and assets have upload/list/url. Notable gaps remain — no tool to read form submissions (list_submissions is referenced but absent), no project delete/rename, and no file delete — though agents can work around these.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers