Gravi MCP
Build your page from your AI tool
The Gravi MCP server lets an AI assistant read and edit your page: add links, write text, change the theme, reorder blocks and check results. It uses the same API keys as the REST API.
- Server URL
- https://api.gravi.page/mcp
- Transport
- Streamable HTTP, stateless
Before you start
You need a Pro project. Scripts and coding tools use an API key (Settings → API); connectors like Claude.ai or ChatGPT sign in with OAuth instead. Give a key only the scopes the assistant needs: with content:read and content:write it can build pages; response and analytics tools appear only if the key or connection has those scopes.
Set up
Replace gravi_… with your API key. Never commit it to a repository.
Claude Code
claude mcp add --transport http gravi https://api.gravi.page/mcp \
--header "Authorization: Bearer gravi_…"Cursor
Add to ~/.cursor/mcp.json (or .cursor/mcp.json in a project):
{
"mcpServers": {
"gravi": {
"url": "https://api.gravi.page/mcp",
"headers": {
"Authorization": "Bearer gravi_…"
}
}
}
}VS Code
Add to .vscode/mcp.json. VS Code asks for the key once and stores it:
{
"inputs": [
{
"type": "promptString",
"id": "gravi-key",
"description": "Gravi API key",
"password": true
}
],
"servers": {
"gravi": {
"type": "http",
"url": "https://api.gravi.page/mcp",
"headers": {
"Authorization": "Bearer ${input:gravi-key}"
}
}
}
}Claude.ai, ChatGPT and other connectors
In the app's connector settings add a custom connector with the server URL above and leave the credential fields empty. Gravi opens a sign-in and consent screen where you choose the project and what the app may do (form responses are off by default). No API key is needed. Disconnect any time in Settings → API → Connected apps.
Tools
The assistant only sees the tools your key's scopes allow. Every change returns the public page URL so you can look at the result. Tool descriptions are in English.
get_projectThe project behind this key: plan, limits and usage, the key's scopes, pages with their public URLs and the block types with their sizes. Call first to learn what is allowed.Needs: any keylist_pagesPages of the project with id, slug, public URL, status and block count.Needs: content:readget_pageOne page: settings, header (name, bio as Markdown), theme and its blocks in reading order with type, size and a short summary (text blocks as Markdown).Needs: content:readcreate_pageCreate and publish a page at gravi.page/{slug}, optionally from a template.Needs: content:writeupdate_pageChange a page's address, status (published / unpublished), SEO fields or language.Needs: content:writedelete_pageDelete a page (restorable for 30 days from the dashboard). Requires confirm_slug equal to the page's slug.Needs: content:read, content:writeupdate_headerSet the page's name, bio (Markdown) and avatar (imported from an image URL; null removes it).Needs: content:writelist_themesTheme presets (Pro presets are marked), fonts and the override options of set_theme.Needs: any keyset_themeSet a page's theme: a preset plus optional overrides (replaces the previous overrides).Needs: content:writeadd_blocksAdd up to 20 blocks to a page, in order: link {url, title?}, text {markdown}, heading {text}, image {image_url, alt?}, video {url}, article {markdown}, spacer. Optional size and position per block. Stops at the first error and reports what was added.Needs: content:writeupdate_blockChange a block: markdown (text / article), params (partial; top-level keys replace, null removes one) or size.Needs: content:writeremove_blocksDelete blocks from a page by id (cannot be undone through the API).Needs: content:writereorder_blocksSet the block order for the desktop and/or mobile view. Each list must contain every block id of the page exactly once; blocks keep their sizes and are re-flowed in that order.Needs: content:writelock_blocksProtect blocks with one shared password (Pro). Visitors see a placeholder until they unlock. The password is write-only and never returned.Needs: content:writeunlock_blocksRemove the password protection from blocks.Needs: content:writelist_formsForm blocks with response counts per status and their columns.Needs: responses:readlist_responsesResponses of a form, newest first. Filter by status, date range (ISO) or search text; paginate with cursor.Needs: responses:readupdate_responsesChange the status, read state or note of responses (up to 100 by id), or delete them.Needs: responses:writeget_analyticsViews, clicks, top blocks, referrers, countries and devices of a page for a period (UTC days, default the last 30; limited by the plan's history).Needs: analytics:read
Errors and limits
Failures come back as tool errors with the API's code and message, for example LIMIT_REACHED: Free plan allows 60 blocks per page. Requests count against the key's rate limits (see the API docs). Without a key the server answers 401, and a project without API access answers 403.