konradmichalik / typo3-routing-mcp
Expose annotated typo3-routing frontend routes as MCP tools via a Streamable HTTP endpoint.
Package info
github.com/konradmichalik/typo3-routing-mcp
Type:typo3-cms-extension
pkg:composer/konradmichalik/typo3-routing-mcp
Requires
- php: ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0
- konradmichalik/typo3-routing: ^0.5
- mcp/sdk: ^0.6
- psr/http-message: ^1.0 || ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- symfony/console: ^7.0 || ^8.0
- symfony/dependency-injection: ^7.1 || ^8.0
- symfony/polyfill-php83: ^1.27
- typo3/cms-core: ^13.4 || ^14.0
Requires (Dev)
- eliashaeussler/version-bumper: ^4.0.3
- konradmichalik/ttt: ^0.2.0
- phpunit/phpunit: ^11.0 || ^12.0 || ^13.0
- typo3/cms-base-distribution: ^13.4 || ^14.0
- typo3/cms-extbase: ^13.4 || ^14.0
- typo3/cms-lowlevel: ^13.4 || ^14.0
- typo3/testing-framework: ^8.2 || ^9.0 || ^10.0
README
TYPO3 extension typo3_routing_mcp
This extension exposes typo3-routing frontend routes as MCP tools over a Streamable HTTP endpoint. Add the #[McpTool] PHP attribute to a routed controller method, and an AI agent can invoke your project's own domain endpoints directly, not just generic TYPO3 content operations.
Note
Generic TYPO3 MCP servers can only talk about content: pages, records, files. Your project's own domain endpoints, course search, store locator, whatever your sitepackage needs, are invisible to them. This extension closes that gap: it turns routes you've already declared via typo3-routing into MCP tools an agent can call directly.
✨ Features
- One attribute, one tool: add
#[McpTool]next to an existing#[Route], flush caches, done - Streamable HTTP: a single endpoint (
/_mcpby default, configurable), bearer-token gated, usable on staging and production - Security by construction: session-scoped authenticators (
FrontendUserAuthenticator/BackendUserAuthenticator) and request-token-protected routes are never exposed, no matter the attribute
🔥 Installation
Requirements
- TYPO3 >= 13.4
- PHP 8.2+
konradmichalik/typo3-routinginstalled and configured
Composer
composer require konradmichalik/typo3-routing-mcp
TER
Download the zip file from TYPO3 extension repository (TER).
🚀 Quick start
Add #[McpTool] next to an existing #[Route]:
use KonradMichalik\Typo3Routing\Attribute\Route; use KonradMichalik\Typo3RoutingMcp\Attribute\McpTool; #[Route(path: '/api/courses/{id}', name: 'course_show', description: 'Fetch a single course by its numeric ID.')] #[McpTool] public function show(int $id): ResponseInterface { /* … */ }
Then audit what's exposed, via the TYPO3 console:
vendor/bin/typo3 routing:mcp:tools
Set a bearer token and point an MCP client at the endpoint. Any client that speaks Streamable HTTP works the same way, just configure the URL and the Authorization header:
export ROUTING_MCP_BEARER_TOKEN=<a-long-random-secret>
claude mcp add --transport http my-project \
https://your-project.example.org/_mcp \
--header "Authorization: Bearer <a-long-random-secret>"
Or, for clients configured via an mcp.json-style file (Cursor, VS Code Copilot, and others):
{
"servers": {
"my-project": {
"type": "http",
"url": "https://your-project.example.org/_mcp",
"headers": {
"Authorization": "Bearer <a-long-random-secret>"
}
}
}
}
Note
Without ROUTING_MCP_BEARER_TOKEN (or the env var name configured via the extension's bearerTokenEnvName setting) set, the endpoint is entirely inactive, not merely unauthenticated.
The initialize response also carries an instructions field describing how to use the exposed tools (read-only vs. mutating, RFC 9457 error content). Most MCP clients surface this to the connecting agent automatically.
Configuration
Set these via the extension's TYPO3 Extension Configuration (Admin Tools > Settings > Extension Configuration > typo3_routing_mcp):
| Setting | Default | Description |
|---|---|---|
bearerTokenEnvName |
ROUTING_MCP_BEARER_TOKEN |
Name of the process environment variable holding the expected bearer token. |
endpointPath |
/_mcp |
Request path the middleware listens on. Change this if /_mcp collides with something else in your project. |
🧑💻 Contributing
Please have a look at CONTRIBUTING.md.
⭐ License
This project is licensed under GNU General Public License 2.0 (or later).