MCP Server for Client Content and Site Updates
Need this adapted for your organization? Work with AstroWeb.dev — Astro services by NViewsWEB.
Documentation

MCP Server for Client Content and Site Updates

How clients connect Claude or Codex to their AstroWEBTheme site to draft and update text and images safely, how the endpoint is secured, and what is planned for developer-side theme updates.

AstroWEBTheme MCP server workflow for client content updates

AstroWEBTheme includes an optional client content MCP: a secured endpoint on the site itself that lets a client’s AI assistant draft and update the site’s text and images. Nothing a client’s assistant writes goes live on its own. A person reviews and publishes it.

A second, developer-side MCP for planning theme-core updates is still planned.

What clients can do

A connected assistant can:

  • list and read entries in the collections you allow
  • create or update a draft from plain Markdown
  • upload images with alt text
  • ask for a review with request_publish

It cannot publish, delete, change settings, read users, or touch anything outside the allowed collections. It has no access to the dashboard.

Where changes are stored

The endpoint picks the storage automatically.

Situation Where drafts go How they go live
A D1 database is bound (preferred) content_entries as draft; images go to R2 and the media library An admin publishes from the dashboard. Edits to an entry that is already live are staged as a pending revision and applied by an admin with Restore
No database A content/<token>-<date> git branch, using the GitHub API request_publish opens a pull request; merging it publishes

In git mode the MCP never writes to the base branch and never merges.

Turn it on

  1. Edit src/site/config/mcp.mjs: set enabled: true, list the editable collections, and set defaultAuthor. In git mode also fill in git.owner and git.repo.
  2. Apply migrations/014_mcp_tokens.sql if you use D1.
  3. Create a token for each client (see below).
  4. Deploy.

The endpoint is https://your-site/mcp/. The trailing slash matters because the site uses trailingSlash: "always".

Create a client token

node devtools/mcp-token.mjs --label "Acme editor" --role editor --days 90 --collections blog

The script prints the token once, plus either the SQL to store its hash in D1 or a JSON entry for the MCP_TOKENS secret when there is no database. Only the SHA-256 of the secret is ever stored. Tokens must expire (1 to 365 days), can be limited to some collections, and are revoked by removing the entry or setting revoked_at.

Role Can
viewer read content
editor read, save drafts, upload images, request review

In git mode, also set a GITHUB_TOKEN secret. Use a fine-grained token restricted to this one repository with only Contents (write) and Pull requests (write).

Connect a client

Claude (custom connector). Add a custom connector with the URL https://your-site/mcp/ and send the token as a bearer token in the Authorization header, if your Claude plan lets you set one for a connector.

Claude Code.

claude mcp add --transport http astroweb-content https://your-site/mcp/ --header "Authorization: Bearer awm_YOUR_TOKEN"

Codex. Add the server to config.toml with the URL and a bearer token environment variable, as described in the Codex MCP documentation for your version.

Client options change between versions. Check the current documentation for your client, and never paste the token into a chat or a shared file.

Tools

Tool Needs What it does
list_content viewer Lists entries in a collection
get_content viewer Returns one entry as Markdown
save_draft editor Creates or updates a draft from Markdown
upload_media editor Uploads a PNG, JPEG, WebP, GIF or AVIF image with alt text
request_publish editor Marks a draft for review, or opens a pull request in git mode

Security model

The endpoint is built on the assumption that both the client’s assistant and the content it reads can be manipulated.

  • Off by default. Disabled until enabled: true; a disabled endpoint returns 404.
  • Scoped tokens. Random 256-bit secrets, stored only as hashes, always expiring, revocable, limited by role and collection. Comparison is constant-time and failures return one generic 401.
  • Separate from the dashboard. The endpoint does not use dashboard sessions, so a token cannot reach any admin page or API.
  • Nothing publishes itself. There is no publish tool. Live entries are never edited in place, and a git pull request is never merged by the MCP.
  • Plain Markdown only. MDX can run code at build time, so input containing imports, exports, {expressions}, raw HTML, components or javascript:/data: links is rejected. Frontmatter is generated from validated fields, never accepted from the client.
  • Images checked by content. The file type is read from its first bytes. SVG and anything unrecognised is refused, size is capped, and file names are rewritten.
  • Prompt-injection aware. Content returned to the assistant is labelled as data, and a read can never trigger a write.
  • Locked-down paths. In git mode, writes are limited to the allowed collection folders and the media folder, on a content/ branch.
  • Browser and network protections. Requests with a browser Origin header are refused unless listed, only POST with JSON is accepted, responses are no-store, and bodies are size-limited.
  • Rate limits and audit. Per-IP and per-token request limits, a separate hourly write limit, and every call is recorded in audit_log (or the worker log when there is no database) without content.
  • Errors reveal nothing. Unexpected failures return a generic message.

Admin API hardening

Adding client tokens made it important that the existing dashboard APIs only accept admins. Every /api/admin/content and /api/admin/media handler now requires the admin role; before this change several accepted any signed-in user, and six media handlers checked nothing beyond the middleware.

Limits to know about

  • Without KV, rate limits are per worker instance and therefore weaker.
  • Applying a staged edit to a live D1 entry (Restore) replaces the body only; title and description changes are recorded on the revision but not applied automatically.
  • A stolen token can draft content until it expires or is revoked, so keep lifetimes short and revoke promptly.
  1. The client asks their assistant to read the page and propose changes.
  2. The assistant saves a draft and uploads images with alt text.
  3. The assistant calls request_publish.
  4. You review the draft or pull request and publish or merge it.

Planned developer update server

A separate, local, read-only MCP server for developers is still planned in devtools/mcp/. It would expose theme_info, update_plan, check, doctor and drift_report by wrapping the existing astroweb dry-run commands, and would never write outside core/ or touch secrets. It is not shipped yet. See Theme Update and Core Boundaries for what theme updates preserve.