Getting started
Requirements
| Requirement | Version |
|---|---|
| PHP | 8.3 – 8.5 |
mcp/sdk | ~0.7.0 (experimental until 1.0 — hence the tilde pin) |
| MCP protocol | 2025-11-25 (the SDK's default; it advertises this in initialize regardless of what the client asks for) |
ext-fileinfo | required by the SDK |
Install
composer require rasuvaeff/yii3-mcp1. Declare a tool
Tools are ordinary Yii3 services. Capability methods are annotated with the SDK's own attributes — this package invents no protocol structures:
use Mcp\Capability\Attribute\McpTool;
final readonly class OrderTools
{
public function __construct(private OrderRepository $orders) {}
/**
* Returns the current status of an order.
*/
#[McpTool(name: 'order.status')]
public function status(string $orderId): string
{
return $this->orders->get($orderId)->status->value;
}
}Input schemas are generated by the SDK from the method signature and DocBlock. #[McpResource], #[McpResourceTemplate] and #[McpPrompt] methods work the same way — see Capabilities for all four.
2. Register it
// config/params.php
return [
'rasuvaeff/yii3-mcp' => [
'server_name' => 'my-app',
'server_version' => '1.0.0',
'tools' => [OrderTools::class],
'endpoint_secret' => getenv('MCP_SECRET'),
],
];Handlers are registered as [class, method] references — the SDK resolves the instance through the Yii3 container on call, so constructor dependencies are injected the normal way. endpoint_secret is mandatory before the endpoint answers anything: an empty secret makes SharedSecretMiddleware reject every request with an explanatory 503 rather than serve unprotected — see Security.
3. Route the endpoint
// config/routes.php
Route::methods(['POST', 'GET', 'DELETE', 'OPTIONS'], '/mcp')
->middleware(SharedSecretMiddleware::class)
->action(McpAction::class),An MCP client connects with the secret header:
{
"mcpServers": {
"my-app": {
"type": "http",
"url": "https://example.com/mcp",
"headers": { "X-Mcp-Secret": "..." }
}
}
}stdio for local development
// add McpServeCommand to your console commands
./yii mcp:serveClaude Code config: claude mcp add my-app -- ./yii mcp:serve.
Check what's actually served
Before pointing a real client at the endpoint, mcp:list prints every registered tool, resource, template and prompt without one — see Operations for the full introspection and diagnostics workflow:
./yii mcp:list
./yii mcp:doctorNext steps
- Architecture — how
McpServerFactoryassembles the SDKServerfrom DI config. - Security — the shared-secret guard, client identity, session ownership.
- Capabilities — tools, resources, prompts, completions in full.
- Cookbook: your first MCP server — a worked walkthrough with
mcp:doctoralong the way.