Kirby MCP

by bnomei

Not rated
GitHub

About

CLI-first MCP server for composer-based Kirby CMS projects—inspect blueprints/templates/plugins, interact with a real Kirby runtime, and use a bundled Kirby knowledge base.

Details

Author
bnomei
Categories
Developer Tools, Other

Setup

Install Kirby MCP in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/bnomei/kirby-mcp

Follow the installation instructions in the repository README, then restart your MCP client.

CLI-first MCP server for Composer-based Kirby CMS projects. It lets an IDE or agent inspect your Kirby project (blueprints, templates, plugins, docs) and interact with a real Kirby runtime. It ships with a local knowledge base of Kirby concepts and tasks. For agent-specific install steps (Claude Code, Codex CLI) and Skill sync, seeClient setup.

It can also run as a projectless global reference MCP (kirby-mcp --global) for always-on Kirby docs/KB research. Global reference mode is intentionally separate from project-local MCP servers and cannot inspect, render, update, or run commands in a Kirby project.

[!WARNING] Prompt injection is a serious security threat, especially when used with documents retrieved from the internet. You might not see it happen when observing the conversation with the agent!

composer require bnomei/kirby-mcp --dev vendor/bin/kirby-mcp install vendor/bin/kirby-mcp

This quickstart is for a local stdio MCP server. If you want Kirby to serve a production HTTP/mcproute, installbnomei/kirby-mcpas a normal Composer dependency instead of--dev; seeHTTP transportbelow.

Then configure your MCP client (Cursor/Claude Code/Codex CLI) using the examples inClient setupand copy the bundled Skills as described below.

SeeClient setup → Claude CodeandClient setup → Codex CLIfor per-agent install and Skill sync steps.

Install once with Composer and run the global reference MCP anywhere:

composer global require bnomei/kirby-mcp kirby-mcp --global

Use this mode for always-available Kirby research: bundled KB search, glossary, Panel field/section reference, hooks, extensions, update-schema guides, official docs search, and plugin directory search.

Global reference mode is projectless by design:

- It does not auto-detect or accept--project.
- It does not expose project/runtime tools such askirby_roots,kirby_info,kirby_render_page, content updates, eval/query, runtime install, or IDE helper generation.
- If you need project context or mutations, add a separate project-local MCP server withvendor/bin/kirby-mcp.

Use these once your MCP client is connected to the server.

[!TIP] "Use the Kirby MCP to make a plan to..." is a reliable way to get your agent to use the tools and resources this MCP server provides. If you ask it to take action, it tends to edit files directly based on its training and skills.

Use the Kirby MCP to make a plan to... build a contact form page.

kirby_roots,kirby_blueprint_read,kirby_templates_index,kirby_snippets_index,kirby_controllers_index,kirby_render_page,kirby_dump_log_tail,kirby://config/{option}

Here’s a Kirby MCP–driven plan for a new contact form page in this project: - Confirm requirements: fields (name/email/message), spam protection (honeypot + csrf()), success UX (inline vs redirect), and whether to store submissions. - Panel setup: reuse existing blueprint site/blueprints/pages/contact.yml; update site/blueprints/site.yml so the site “pages” section allows creating template contact. - Create the page: add content/4_contact/contact.txt (or create via Panel once allowed) and fill recipient, subject, success, text. - Frontend: add site/templates/contact.php + a snippet like site/snippets/contact-form.php (escape all echoed user input; include hidden CSRF field + honeypot). - Controller: add site/controllers/contact.php to handle POST: check csrf(get('csrf')), validate with invalid(), then send mail via $kirby->email() using replyTo (never use user input as from) and an email template like site/templates/emails/contact.text.php (optional contact.html.php). - Email config: add site/config/config.php email.transport/email.presets (current kirby://config/email is null). - Verify with MCP: render the page via kirby_render_page(id='contact', noCache=true); debug with mcp_dump() + kirby_dump_log_tail(traceId=...); inspect blueprint/roots via kirby_blueprint_read(id='pages/contact') and kirby://roots.
Show me the fields available on the home page blueprint and what they do using the MCP.

kirby_blueprint_read,kirby_blueprints_index

Show me the current content of the about page.
Append " with AI" to the title of the home page with Kirby MCP.

kirby_read_page_content,kirby_update_page_content,kirby://field/text/update-schema

[!TIP] Either on its own or with a request, the resources can be used to quickly bring knowledge and runtime information into the current context of your agent.

What is the kirby://config/debug for production?

[!TIP] The MCP server ships with a local knowledge base about Kirby. It consists of a glossary, common tasks, and update guides for content fields. This reduces the need to rely on external resources and is very fast.

[!TIP] But sometimes you or your agent needs to dig deeper. That is why the MCP server also provides a fallback to the official Kirby search and docs (not including the forum). You can trigger it by mentioningsearch onlinein your request.

kirby search online for panel permissions

[!TIP] When you need to discover third-party plugins, you can also search the official Kirby plugin directory and fetch details from each plugin page.

kirby search plugins online for e-commerce cart

[!TIP] Your agent will use the next tool under the hood itself, but you can use it as well to quickly check what the MCP server knows about a given topic.

What mcp tool should I use to... list plugins?
list blueprints, templates, snippets, collections, controllers, models, plugins, routes, roots

kirby_blueprints_loaded,kirby_blueprints_index,kirby_templates_index,kirby_snippets_index,kirby_collections_index,kirby_controllers_index,kirby_models_index,kirby_plugins_index,kirby_routes_index,kirby_roots

[!IMPORTANT] Thekirby_evaltool is disabled by default and CLI commands are protected by an allowlist/denylist, see config and security below.

kirby MCP tinker $site->index()->count()
kirby MCP check query site.find('notes').unlisted.count kirby MCP check query page.siblings.count (model: notes)
My home page renders incorrectly. Help me debug it with mcp_dump() to return the current $page object.

kirby_render_page,kirby_dump_log_tail,kirby_templates_index,kirby_snippets_index,kirby_controllers_index,kirby_models_index

[!INFO]kirby_initis required once per session before calling any other tool or resource but the agent should figure this out automatically. Some capabilities require the runtime wrappers because they query Kirby at runtime. Installing/updating them should happen automatically as well.

At initialization, the server tells the agent which tools/resources to use. The knowledge base cross-references them so the agent can find the next step.

Current inventory: 37 tools, 15 resources, 15 resource templates, 216 KB articles.

In global reference mode (kirby-mcp --global), the exposed surface is intentionally smaller:kirby_init,kirby_search,kirby_online,kirby_online_plugins,kirby_tool_suggest, and static reference resources/templates (kirby://kb, glossary, fields/sections, hooks, extensions, and update schemas).

- kirby_blueprint_read— read a single blueprint by id
- kirby_blueprints_index— index blueprints, includes plugin-registered ones when runtime is installed
- kirby_blueprints_loaded— list blueprint ids loaded at runtime
- kirby_cache_clear— clear in-memory caches for this MCP session (StaticCache, config, composer, roots, tool index)
- kirby_cli_version— runkirby versionand return stdout, stderr and exit code
- kirby_composer_audit— parse composer.json for scripts and quality tools
- kirby_collections_index— index named collections, includes plugin-registered ones when runtime is installed
- kirby_controllers_index— index controllers, includes plugin-registered ones when runtime is installed
- kirby_online— search official Kirby docs (online fallback) and optionally fetch markdown pages
- kirby_online_plugins— search the official Kirby plugins directory (online fallback) and optionally fetch plugin details
- kirby_dump_log_tail— tail.kirby-mcp/dumps.jsonlwritten bymcp_dump()
- kirby_eval— execute PHP in Kirby runtime for quick inspection, requires enable plus confirm
- kirby_query_dot— evaluate Kirby query language (dot-notation) strings, requires confirm and can be disabled via config
- kirby_generate_ide_helpers— generate regeneratable IDE helper files into.kirby-mcp/
- kirby_ide_helpers_status— report missing template/snippet PHPDoc@varhints for used Kirby globals + helper file freshness (mtime-based)
- kirby_info— project runtime info, composer audit and local environment detection
- kirby_init— session guidance plus project-specific audit, call once per session
- kirby_search— search the bundled local Kirby knowledge base markdown files (preferred)
- kirby_models_index— index registered page models with class and file path info
- kirby_plugins_index— index loaded plugins, prefers runtime truth when installed
- kirby_read_file_content— read file content/metadata by id or uuid
- kirby_read_page_content— read page content by id or uuid
- kirby_read_site_content— read site content
- kirby_read_user_content— read user content by id or email
- kirby_render_page— render a page by id or uuid and return HTML plus errors
- kirby_roots— resolved Kirby roots viakirby roots
- kirby_routes_index— list registered routes with best-effort source location (config/plugin)
- kirby_run_cli_command— run a Kirby CLI command, guarded by an allowlist
- kirby_runtime_install— install project-local Kirby MCP runtime CLI commands into the project
- kirby_runtime_status— check whether runtime command wrappers are installed
- kirby_snippets_index— index snippets, includes plugin-registered ones when runtime is installed
- kirby_templates_index— index templates, includes plugin-registered ones when runtime is installed
- kirby_tool_suggest— suggest the best next Kirby MCP tool/resource for a task
- kirby_update_file_content— update file metadata/content, plus confirm (seekirby://blueprint/file/update-schema+kirby://field/{type}/update-schemafor payload shapes)
- kirby_update_page_content— update page content, plus confirm (seekirby://blueprint/page/update-schema+kirby://field/{type}/update-schemafor payload shapes)
- kirby_update_site_content— update site content, plus confirm (seekirby://blueprint/site/update-schema+kirby://field/{type}/update-schemafor payload shapes)
- kirby_update_user_content— update user content, plus confirm (seekirby://blueprint/user/update-schema+kirby://field/{type}/update-schemafor payload shapes)

[!TIP] Call a resource to bring condensed knowledge into the current context of your agent.

- kirby://commands— Kirby CLI command list, parsed fromkirby help
- kirby://composer— composer audit, scripts and quality tooling
- kirby://extensions— Kirby plugin extensions list (links tokirby://extension/{name})
- kirby://fields— Kirby Panel field types list (links tokirby://field/{type})
- kirby://fields/update-schema— Kirby content field guides list (links tokirby://field/{type}/update-schema)
- kirby://blueprints/update-schema— Kirby blueprint update guides list (links tokirby://blueprint/{type}/update-schema)
- kirby://glossary— Kirby glossary terms list (links tokirby://glossary/{term})
- kirby://kb— bundled KB index (links tokirby://kb/{path})
- kirby://hooks— Kirby hook names list (links tokirby://hook/{name})
- kirby://info— project runtime info, composer audit and local environment detection
- kirby://roots— Kirby roots discovered via CLI, respects configured host
- kirby://sections— Kirby Panel section types list (links tokirby://section/{type})
- kirby://tools— weighted keyword index for Kirby MCP tools/resources/templates
- kirby://uuid/new— generate a new Kirby UUID string (respectscontent.uuidformat)

- kirby://blueprint/{encodedId}— read a blueprint by URL-encoded id, e.g.pages%2Fhome
- kirby://cli/command/{command}— parsedkirby <command> --helpoutput, e.g.backuporuuid:generate
- kirby://config/{option}— read a Kirby config option by dot path
- kirby://extension/{name}— Kirby extension reference markdown from getkirby.com, e.g.commandsordarkroom-drivers
- kirby://field/{type}— Kirby Panel field reference markdown from getkirby.com, e.g.blocksoremail
- kirby://field/{type}/update-schema— bundled content field guide fromkb/update-schema/{type}.md
- kirby://blueprint/{type}/update-schema— bundled blueprint update guide fromkb/update-schema/blueprint-{type}.md
- kirby://glossary/{term}— read a bundled Kirby glossary entry by term, e.g.apiorkql
- kirby://kb/{path}— read a bundled KB document by path (relative tokb/, no.md)
- kirby://hook/{name}— Kirby hook reference markdown from getkirby.com, e.g.file.changeName:afterorfile-changename-after
- kirby://file/content/{encodedIdOrUuid}— read file content/metadata by URL-encoded id or uuid
- kirby://page/content/{encodedIdOrUuid}— read page content by URL-encoded id or uuid
- kirby://section/{type}— Kirby Panel section reference markdown from getkirby.com, e.g.fieldsorfiles
- kirby://site/content— read site content
- kirby://susie/{phase}/{step}— easter egg resource template
- kirby://user/content/{encodedIdOrEmail}— read user content by URL-encoded id or email

Bundled Skills live invendor/bnomei/kirby-mcp/skillsafter installation. Copy them into your agent’s local skills folder using theClient setupinstructions below.

- kirby-project-tour— Project inventory and orientation (roots, blueprints, plugins) with next-step recommendations.
- kirby-content-migration— Safe content migrations with runtime read/update tools and update schemas.
- kirby-scaffold-page-type— Scaffold a page type (blueprint + template + optional controller/model) using project conventions.
- kirby-routing-and-representations— Custom routes, redirects, and content representations (.json/.xml/.rss).
- kirby-collections-and-navigation— Listings, pagination, search, filtering/sorting/grouping, and navigation menus.
- kirby-panel-and-blueprints— Blueprint design, Panel UX,extends, and custom areas/fields/sections.
- kirby-plugin-development— Reusable plugins with hooks/extensions, KirbyTags, blocks, and shared controllers/templates.
- kirby-headless-api— Headless API setup with Kirby API, KQL, and JSON representations.
- kirby-i18n-workflows— Language config, translation keys, localized labels, and import/export workflows.
- kirby-security-and-auth— Login/roles/permissions, access restriction, and protected downloads.
- kirby-performance-and-media— Cache tuning, CDN/media routing, responsive images, and lazy loading.
- kirby-debugging-and-tracing— Render reproduction, runtime tracing withmcp_dump, and code-path discovery.
- kirby-ide-support— IDE helper status plus minimal PHPDoc/type-hint improvements.
- kirby-upgrade-and-maintenance— Safe Kirby upgrades with composer audit, plugin checks, and verification.
- kirby-forms-and-frontend-actions— Contact forms, uploads, emails, and frontend page creation with validation/CSRF.

[!NOTE] The--projectflag is optional when you run the server from the Kirby project root. Use it (orKIRBY_MCP_PROJECT_ROOT) only for project-local MCP servers that should inspect a specific Kirby project. Command-based stdio is the default and recommended setup for local IDE/agent use.kirby-mcp --globalis a separate projectless reference server and must not be combined with--project.

Add to.cursor/mcp.json(project) or~/.cursor/mcp.json(global):

{ "mcpServers": { "kirby-reference": { "command": "kirby-mcp", "args": ["--global"] }, "kirby-project": { "command": "/absolute/path/to/kirby-project/vendor/bin/kirby-mcp" } } }

Usekirby-referencefor docs/KB research that is always available. Usekirby-projectonly when that specific Kirby project should be inspectable or mutable.

claude mcp add kirby -- vendor/bin/kirby-mcp
claude mcp add kirby-reference -- kirby-mcp --global
claude mcp add kirby -- vendor/bin/kirby-mcp --project=/absolute/path/to/kirby-project
mkdir -p ~/.claude/skills rsync -a vendor/bnomei/kirby-mcp/skills/ ~/.claude/skills/

Restart Claude Code after copying (use.claude/skills/instead for repo-scoped skills).

codex mcp add kirby -- vendor/bin/kirby-mcp
codex mcp add kirby-reference -- kirby-mcp --global
codex mcp add kirby -- vendor/bin/kirby-mcp --project=/absolute/path/to/kirby-project
mkdir -p ~/.codex/skills rsync -a vendor/bnomei/kirby-mcp/skills/ ~/.codex/skills/

Start the server (point it at a composer-based Kirby project):

- From the Kirby project root:vendor/bin/kirby-mcp
- Or explicitly:vendor/bin/kirby-mcp --project=/absolute/path/to/kirby-project
- Or as the projectless global reference server:kirby-mcp --global

HTTP is disabled by default.vendor/bin/kirby-mcpcontinues to run stdio unless you add the Kirby route and set"http.enabled": truein.kirby-mcp/mcp.jsonor environment variables.

[!NOTE] Remote HTTP follows the standard MCP pattern: HTTPS/mcp, Bearer/OAuth auth, and MCP metadata discovery. Claude Code and Claude Desktop/Claude.ai custom connectors are the primary tested targets. Other MCP-compatible clients may work if they support remote HTTP MCP and the configured auth mode. OpenAI/ChatGPT uses MCP through Responses API tools and ChatGPT Apps/MCP Apps, not the Claude custom-connector URL flow documented here.

For a Kirby route, install this package as a production dependency:

Do not install it withcomposer require --devif your/mcproute should work in production; the production PHP runtime must be able to autoloadBnomei\KirbyMcp\Mcp\KirbyMcpRoutes.

Add these routes to your Kirby config, usuallysite/config/config.php:

<?php use Bnomei\KirbyMcp\Mcp\KirbyMcpRoutes; return [ 'routes' => [ ...KirbyMcpRoutes::routes(), ], ];

If your config already definesroutes, spread these entries into the existing routes array instead of replacing it. No special Nginx location orvendor/bin/kirby-mcpproxy is required.

The route helper adds/mcpplus the optional OAuth metadata, registration, authorize/token, JWKS, and login routes. If you changehttp.path, pass the same path to the route helper:

'routes' => [ ...KirbyMcpRoutes::routes('/custom-mcp'), ],

If you also change the built-in OAuth provider path, pass it as a named argument:

'routes' => [ ...KirbyMcpRoutes::routes('/custom-mcp', oauthPath: '/custom-mcp/oauth'), ],

Put the JSON examples below in your Kirby project’s MCP config file:.kirby-mcp/mcp.json.

[!WARNING] All/mcprequests requireAuthorization: Bearer ...; query-string credentials are rejected. Public route requests require HTTPS, requests with anOriginheader must matchhttp.allowedOrigins, and every operation is scope-checked. If the route is registered buthttp.enabledis false, it returns 404.

Useshared-tokenonly for local development from the same machine:

{ "http": { "enabled": true, "path": "/mcp", "allowedOrigins": ["http://127.0.0.1:3000"], "auth": { "mode": "shared-token", "token": "replace-with-a-long-random-secret", "scopes": ["kirby-mcp:read", "kirby-mcp:runtime", "kirby-mcp:write", "kirby-mcp:execute", "kirby-mcp:admin"] } } }

The Kirby route rejects shared-token requests unless PHP reportsREMOTE_ADDRas loopback and the request host is a real loopback host (localhost,::1, or a valid IPv4 literal in127.0.0.0/8).

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.