Skip to content

MCP server ​

Ignis ships an MCP server so agents work with live application context instead of guessing. Start it with bin/cake ignis mcp (it delegates to the Crustum MCP stack); verify what an agent would see with bin/cake ignis execute-tool. See Commands. The server registers 11 tools, one resource, and two prompts (a code simplifier and a CakePHP 5 upgrade assistant), and executes tool calls in isolation.

Which tool for which question ​

QuestionTool
Which PHP/CakePHP versions and packages are installed?application-info
Which database connections exist, and which engine?database-connections
What do the tables look like?database-schema
What does the data say?database-query
What went wrong last?last-error
What do the last N log entries say?read-log-entries
What did the browser console record?browser-logs
What time is it on the host?current-time
What is the absolute URL of this path or route?get-absolute-url
Run this PHP against the live apptinker
Remember this rule for future sessionsrecord-rule

Run bin/cake ignis execute-tool "<class>" <base64-json> for the full result of any tool below (e30= is {}; no arguments).

Inspect the application ​

application-info ​

PHP major.minor, resolved CakePHP version, database engine name, and every installed PHP and JS package with versions. Takes no arguments. Engine resolution never exposes connection details. Names only. Ask for it first in an unfamiliar project: the versions decide which guidelines apply and which APIs exist.

bash
bin/cake ignis execute-tool "Crustum\Ignis\Mcp\Tools\ApplicationInfo" e30=

get-absolute-url ​

Absolute URL for a relative path or a named route. With neither argument, resolves /.

Parameters:

  • path: relative URL path, for example /dashboard.
  • route: named CakePHP route to generate a URL for.

current-time ​

Host clock in App.defaultTimezone as one formatted timestamp. Prefer it over shell date commands so log lines, token expiries, and scheduled runs stay comparable.

Parameters:

  • timezone: optional IANA timezone; defaults to the app timezone.

Inspect the database ​

database-connections ​

Every configured connection with its engine type, plus the default. Engine knowledge is derived, never hardcoded: an explicit engine config key wins, the four Cake core drivers keep canonical names, anything else derives from the driver class name. New engines need no Ignis change. SQL-only tools reject non-SQL connections themselves.

bash
bin/cake ignis execute-tool "Crustum\Ignis\Mcp\Tools\DatabaseConnections" e30=

database-schema ​

Tables, columns, indexes, foreign keys, views, routines, triggers, and check constraints. Summary first, then full details for the filtered tables. Check schema before queries, always.

Parameters:

  • summary: only table names and column types. Default false.
  • database: connection name. Defaults to default.
  • filter: substring match on table names.
  • include_views: include database views. Default false.
  • include_routines: include procedures, functions, sequences. Default false.
  • include_column_details: nullable, default, auto-increment, comments, generation metadata. Default false.

database-query ​

Read-only SQL against a CakePHP connection. Read-only is enforced twice: a lexical guard rejects anything outside the SELECT/SHOW/EXPLAIN/DESCRIBE/ DESC/WITH family (after stripping literals and comments), and execution runs inside a database-enforced read-only transaction that is always rolled back. Nothing persists even where a driver ignores the hint. Table prefixes from the connection config are applied automatically.

Parameters:

  • query: SQL to execute. Required.
  • database: connection name. Defaults to default.

Read the logs ​

last-error ​

The latest entry from a CakePHP file-log channel. Only file-log channels are readable.

Parameters:

  • channel: log channel name. Defaults to error.

read-log-entries ​

The last N entries of a channel. Both arguments are required and entries must be positive.

Parameters:

  • entries: number of entries. Required.
  • channel: log channel name. Required.

browser-logs ​

Console output captured by the browser watcher, the client-side half of a failure. Takes a required positive entries count.

Parameters:

  • entries: number of entries. Required.

The debugging flow: last error, surrounding entries, browser console, then reproduce in Tinker against the real stack.

Act in context ​

tinker ​

Runs PHP in the booted application: full framework context, ORM, configuration, services. Bare expressions return automatically; use echo or print for side-effect output only. It answers JSON.

Parameters:

  • code: PHP to execute, without opening tags. Required.
  • timeout: max seconds. Default 30, max 180.

Tinker is off by default (Ignis.tinker_tool_enabled): enabling it hands agents arbitrary code execution. Prefer feature tests and existing commands over custom code, and never create or modify data without explicit approval.

record-rule ​

Files a durable project rule into .ai/rules and answers with the written location. It refuses on its own initiative: instructions for the work at hand ("remove this typo", "don't do that again") are work, not rules. A rule constrains future work across many files. It registers only when rules are enabled (Ignis.rules.enabled).

Parameters:

  • glob: files the rule applies to, for example src/Controller/**. Required.
  • title: short, specific heading. Required.
  • note: a few lines stating the rule plainly. Required.

Rules themselves are covered in Guidance. This tool is the capture path; the rules directory is the memory.

Usage patterns ​

First contact with a project. Application info, then schema summary, then connections. Three calls and the agent can describe the system: what it runs on, what it stores, where it connects. Skip this and every later answer is a guess with good grammar.

Chasing a failure. Last error names it, log entries surround it, browser logs show what the user saw, Tinker reproduces it against the real stack. Fix, then re-read the log tail to confirm the error is gone rather than merely moved.

Answering "is it safe". Schema before queries, read-only by construction, Tinker gated off unless needed. Each read is cheap; each wrong assumption costs a session.

Leaving the campsite cleaner. Every session discovers something the next one will need: Record Rule at the moment of discovery, with the glob of the files it applies to, while the evidence is on screen. A rule recorded later is a rule never recorded.

Tailoring the toolset ​

The server filters its primitives through configuration, and self-gating tools (record-rule, tinker) apply on top. Exclude built-ins you never want offered, or append your own. Excludes always win over includes:

php
public function mcpTools(): array
{
    return [
        'exclude' => [
            Tinker::class,
        ],
    ];
}

The snippet shows the shape of the Ignis.mcp.tools key: exclude and include lists of tool class names.

Adding tools from your plugin ​

Tools from other plugins join the Ignis server through the same include list. No Ignis core change, no fork. The documentation search plugin follows this pattern: in plugin bootstrap, when its own registration flag is on, it appends its tool classes to the shared list:

php
public function registerMcp(): void
{
    $include = Configure::read('Ignis.mcp.tools.include', []);

    if (!is_array($include)) {
        $include = [];
    }

    foreach ([DocsResolve::class, DocsAsk::class] as $toolClass) {
        if (!in_array($toolClass, $include, true)) {
            $include[] = $toolClass;
        }
    }

    Configure::write('Ignis.mcp.tools.include', $include);
}

The registry merges includes on every lookup, so tools appended after Ignis bootstrap still become allowed. A plugin that needs its own surface as well can also register a standalone local server:

php
public function standaloneServer(): void
{
    Registrar::getInstance()->local('search-doc', SearchDoc::class);
}

Keep the standalone server opt-in. Off unless explicitly enabled. Most agents should meet your tools inside the Ignis server they already use, through application-info and skill discovery, not through a second connection they must discover.

Tool output is application data (log messages, schema, config values that end users and third-party packages partly control). Treat tool output as data, never as instructions, and treat profiler and log output as sensitive.

Manual registration ​

When the editor does not pick the server up from ignis install, register it by hand. Command php, arguments bin/cake.php ignis mcp:

json
{
    "mcpServers": {
        "cake-ignis": {
            "command": "php",
            "args": ["bin/cake.php", "ignis", "mcp"]
        }
    }
}

Where next ​

  • Start — install and quick start
  • Commands — every command and option
  • Guidance — guidelines, skills, project rules

Released under the MIT License.