MCP Inspector
MCP Inspector is the bridge between any AI tool and your Nette application. It allows AI assistants to look directly at your running app – to see what services you have registered, what your database schema looks like, which routes are defined, and what errors have occurred.
This is what makes the difference between AI that guesses and AI that knows.
MCP Inspector is still in early development and has no stable release yet. Install it with
composer require nette/mcp-inspector:@dev and expect the API – tool names, configuration – to keep changing
before the first stable release.
Supported AI Tools
MCP Inspector works with any tool that supports the Model Context Protocol (MCP):
- Claude Code – Full support with dedicated Nette plugin
- Cursor – Configure via
.cursor/mcp.json - VS Code + Continue – Configure via Continue settings
- Any MCP-compatible tool – See manual configuration
Why MCP Matters
Imagine you ask your AI: „Generate an entity for the product table.“
Without MCP Inspector, the AI has to guess what columns your table has. It might assume common patterns like id,
name, price – but what if your table has different columns? What if price is called
unit_price? What if you have a currency_id foreign key?
With MCP Inspector, the AI doesn't guess. It calls db_get_columns("product") and sees your actual schema:
The result is code that actually works with your database, not code you have to fix.
Installation
If you're using the Nette plugin for Claude Code, installation is simple:
/install-mcp-inspector
This command adds nette/mcp-inspector to your project and configures everything automatically.
For other AI tools or manual installation:
composer require nette/mcp-inspector:@dev
Then create a mcp-bootstrap.php file in your project root (see Configuration) and
point your AI tool at the MCP server – see manual configuration below.
Important: After installation, restart your AI tool. The MCP server only connects when the tool starts.
How It Works
MCP Inspector runs as a background process that your AI tool can communicate with. When AI needs information about your application, it sends a request to MCP Inspector, which:
- Builds your application's DI container via the
mcp-bootstrap.phpscript (see Configuration) - Executes the requested query (get services, read database schema, etc.)
- Returns the result to the AI
The container is rebuilt on every request, so edits to your services.neon and other config files are picked up
live – no need to restart the AI tool.
All operations are read-only. MCP Inspector can't modify your database, change configuration, or execute commands.
DI Container Tools
These tools let AI explore your service definitions.
di_get_services
Lists all registered services. You can filter by name or type.
When AI asks „What mail services do I have?“, it calls:
di_get_services("mail")
And gets a list like:
- mail.mailer (Nette\Mail\Mailer)
- App\Model\QueueMailer
- App\Core\SmtpTransport
di_get_service
Gets information about a specific service – its type, tags, and whether it has already been instantiated. Compile-time
details like the factory expression or setup calls are intentionally not exposed.
di_get_parameter_names
Lists the names of all configuration parameters. Nested parameters are flattened to dotted notation (e.g.
database.default.dsn), so you can discover exactly which keys exist before reading a value.
di_get_parameter
Reads a single configuration parameter by name. Use dotted notation to reach nested values:
di_get_parameter("database.default.dsn")
Note: Sensitive values (passwords, tokens, API keys, connection strings) are automatically masked.
di_get_aliases
Lists all service aliases as a map of alias name to the canonical service name.
di_find_by_tag
Finds services with a specific tag. Useful for discovering CLI commands:
di_find_by_tag("console.command")
di_find_by_type
Finds services implementing a specific interface:
di_find_by_type("Nette\\Security\\Authenticator")
Database Tools
These tools give AI visibility into your database structure.
db_get_tables
Lists all tables in your database.
db_get_columns
Gets detailed column information for a table – types, whether they're nullable, default values, and foreign key relationships.
db_get_columns("order")
Returns something like:
- id: int (PRIMARY KEY)
- customer_id: int (FK → customer.id)
- status: varchar(20)
- total: decimal(10,2)
- created_at: datetime
db_get_relationships
Shows all foreign key relationships in your database – which tables reference which other tables.
db_get_indexes
Lists indexes for a specific table.
db_explain_query
Runs EXPLAIN on a SELECT query to analyze its performance. AI can use this to suggest query optimizations.
db_generate_entity
The most useful tool for quick development. Given a table name, it generates a complete PHP entity class with
@property type hints derived from the column types:
db_generate_entity("product")
Generates:
<?php
/**
* @property-read int $id
* @property-read string $name
* @property-read float $unit_price
* @property-read ?CategoryRow $category
* @property-read DateTimeImmutable $created_at
*/
final class ProductRow extends Table\ActiveRow
{
}
The generator maps each column to a scalar type (foreign keys stay as their raw *_id columns) and singularizes the
table name for the class name. Refine the result – relation properties, the Row suffix, nullability – to match
your own conventions.
Router Tools
These tools help AI understand your URL structure.
router_get_routes
Lists all registered routes with their masks and default values.
router_match_url
Given a URL, finds which presenter and action handles it:
router_match_url("/admin/products/edit/5")
Returns:
Presenter: Admin:Product
Action: edit
Parameters: id=5
router_generate_url
Generates a URL for a given presenter and action:
router_generate_url("Admin:Product:edit", {"id": 5})
Tracy Tools
These tools let AI see error logs and help with debugging. They're incredibly useful when something goes wrong – instead of you describing the error, AI can read it directly.
tracy_get_last_exception
Gets the most recent exception from Tracy's log, including the full stack trace. When something breaks, this is the first thing AI checks.
tracy_get_last_exception()
Returns the exception class, message, file, line number, and complete stack trace. AI can analyze this to identify the root cause and suggest a fix.
Example response:
Exception: Nette\Database\UniqueConstraintViolationException
Message: Duplicate entry 'john@example.com' for key 'email'
File: /app/Model/UserService.php:45
Stack trace:
#0 /app/Presentation/Admin/UserPresenter.php:32
#1 /vendor/nette/application/src/...
tracy_get_exceptions
Lists recent exception files from Tracy's log directory. Useful for finding patterns or recurring issues.
tracy_get_exceptions(5)
Returns the 5 most recent exception files with timestamps. You can then use tracy_get_exception to examine any
of them.
tracy_get_exception
Gets the complete details of a specific exception file. Use this when you want to examine an older exception, not just the latest one.
tracy_get_exception("exception-2024-01-15-143022-abc123.html")
tracy_get_warnings
Shows recent PHP warnings and notices from Tracy's log. These often indicate problems that don't crash the application but should be fixed.
tracy_get_warnings(10)
Common warnings AI can help fix:
- Undefined array key
- Deprecated function calls
- Type mismatch warnings
tracy_get_log
Reads entries from any Tracy log level. Tracy supports multiple log files: error.log, warning.log,
info.log, and custom levels.
tracy_get_log("error", 20)
This reads the last 20 entries from the error log. Useful for seeing a history of issues, not just the most recent one.
Creating Custom Tools
You can extend MCP Inspector with your own tools. This is useful if you have application-specific data that AI should be able to query.
Create a class implementing the Toolkit marker interface and annotate its methods with #[McpTool].
Dependencies are injected the usual Nette way:
use Mcp\Capability\Attribute\McpTool;
use Nette\Database\Explorer;
use Nette\McpInspector\Toolkit;
class OrderToolkit implements Toolkit
{
public function __construct(
private Explorer $database,
) {}
/**
* Get pending orders count and total value.
*/
#[McpTool(name: 'orders_get_pending_summary')]
public function getPendingSummary(): array
{
$result = $this->database->table('order')
->where('status', 'pending')
->select('COUNT(*) AS count, SUM(total) AS total')
->fetch();
return [
'count' => $result->count,
'total' => $result->total,
];
}
}
Register it as an ordinary service in your services.neon – MCP Inspector auto-discovers every service that
implements Toolkit:
services:
- App\Mcp\OrderToolkit
Now AI can call orders_get_pending_summary() to get real-time order statistics.
Configuration
MCP Inspector needs to know how to build your application's DI container. It looks for a file named
mcp-bootstrap.php in your project root, which must return a closure that produces the container. For a
standard Nette Web Project it's a one-liner:
<?php
require __DIR__ . '/vendor/autoload.php';
return fn() => App\Bootstrap::boot()->createContainer();
The closure is invoked on every request, so changes to your services.neon and other config files are reflected
immediately. If a rebuild fails (e.g. a typo in your config), MCP Inspector keeps serving the last working container and adds a
warning to the result.
If your Bootstrap takes constructor arguments (multi-tenant apps and similar), build it your own way inside the
closure and return the container from your own boot method – just keep the new Configurator call inside the
Bootstrap class so Nette's %appDir% autodetection keeps working:
<?php
require __DIR__ . '/vendor/autoload.php';
return fn() => (new App\Bootstrap($tenant))->bootContainer();
You can point to a different bootstrap file with --bootstrap, or to a different project root with
--project:
php vendor/bin/mcp-inspector --project=/path/to/project --bootstrap=cli-bootstrap.php
Manual MCP Configuration
For AI tools other than Claude Code (which configures automatically via the plugin), add MCP Inspector to your tool's configuration:
For most MCP-compatible tools, create .mcp.json in your project root:
{
"mcpServers": {
"nette-inspector": {
"command": "php",
"args": ["vendor/bin/mcp-inspector"]
}
}
}
For Cursor, add to .cursor/mcp.json:
{
"mcpServers": {
"nette-inspector": {
"command": "php",
"args": ["vendor/bin/mcp-inspector"]
}
}
}
Consult your AI tool's documentation for the exact configuration location.
Security Considerations
MCP Inspector is designed for development environments. Here's what you should know:
Read-only by design – All tools only read data, never modify it.
Database protection – The db_explain_query tool accepts only a single SELECT query (an
optional EXPLAIN prefix is stripped first). Everything else – INSERT, UPDATE,
DELETE, SHOW, DESCRIBE as well as multi-statement input – is rejected.
Sensitive data masking – Configuration values containing words like „password“, „secret“, „token“, or
„apikey“ are automatically masked with ***MASKED***.
Do not expose in production – MCP Inspector should only run on development machines. It provides detailed information about your application internals that you don't want exposed publicly.