kinetis / mcp
The Model Context Protocol server for Kinetis — tools and resources declared with attributes and validated like HTTP routes, served over stdio and as an ordinary /mcp route.
Requires
- php: ^8.4
- kinetis/framework: ^1.8.1
- nyholm/psr7: ^1.8.2
- psr/container: ^2.0.2
- psr/http-message: ^2.0
- psr/http-server-middleware: ^1.0.2
- psr/log: ^3.0.2
Requires (Dev)
- infection/infection: ^0.35.0
- kinetis/auth: ^1.2.2
- kinetis/persistence: ^1.2.2
- phpstan/phpstan: ^2.2.8
- phpunit/phpunit: ^13.3.3
- vimeo/psalm: ^6.17
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
kinetis/mcp
The native Model Context Protocol server for Kinetis
Part of Kinetis, a non-blocking PHP framework for API-first applications, developed in the kinetis-dev/kinetis monorepo.
The Model Context Protocol server for Kinetis — tools and resources an AI agent can discover and call, declared with attributes and validated exactly like HTTP routes.
use Kinetis\Mcp\Attributes\McpTool; final readonly class AccountController { #[McpTool(name: 'get_user_status', description: 'Retrieve user status by ID')] public function getUserStatus(int $userId): array { return ['userId' => $userId, 'status' => 'active']; } }
Two transports: stdio (kinetis mcp:serve — how Claude Desktop, Cursor,
and most local clients launch a server) and Streamable HTTP (/mcp, an
ordinary route), both implementing the 2026-07-28 revision's
stateless, per-request model. Every message is its own unit of work: a
fresh request scope,
transaction rollback for anything a tool leaves open, disposal once the
response is written. The mcp middleware group authenticates the HTTP
endpoint with the same middleware the auth packages ship for routes, and
the identity they resolve reaches the tool; without one, /mcp answers
401 and dispatches nothing, unless MCP_HTTP_PUBLIC=true opens it. A
deployment that pre-warms .kinetis-cache/ runs bin/kinetis build in
the deploy that upgrades this package, so its compiled mcp group
carries the guard. An unexpected exception — a tool, a resource, or the
logger reporting either one — never crashes the server or reaches the
client as anything more than a fixed, generic message; see the "Error
handling" section at
kinetis.dev/docs/mcp.html.
Provides
Installing this package is what opts it in — it registers the following
automatically, through the extra.kinetis declaration in its
composer.json (see
kinetis.dev/docs/cli.html):
- A command on
vendor/bin/kinetis:mcp:serve, the stdio transport. - A route:
POST /mcp, the Streamable HTTP transport, wrapped by two permanent members of themcpmiddleware group: the spec-requiredOriginvalidation, and the identity guard that keeps the endpoint closed to unauthenticated callers. - A service binding:
McpServer, built lazily on first use from your application's own discovered tools and resources.
Nothing else — no global middleware, event listeners, or other routes.
Configuration
Read from the environment (or .env) via Kinetis\Config:
| Key | Default | Purpose |
|---|---|---|
MCP_ALLOWED_ORIGINS |
(empty) | Comma-separated exact Origin values allowed on /mcp. Empty rejects any request that sends an Origin header at all; requests without one (CLI clients, server-to-server) always pass. |
MCP_HTTP_PUBLIC |
false |
Serves /mcp to unauthenticated callers. Left at false, a request no mcp-group middleware registered a CurrentUserInterface for is answered 401 before anything is dispatched — see the "Securing the HTTP transport" section at kinetis.dev/docs/mcp.html. |
MCP_DISCOVERY_PATHS |
(unset) | Comma-separated sub-paths (relative to each PSR-4 base directory) restricting tool/resource discovery, for a large application that wants a bounded scan. |
Installation
composer require kinetis/mcp
Requires PHP 8.4 or later and kinetis/framework.
Documentation:
kinetis.dev/docs/mcp.html
License
MIT