blackcube / mcp
MCP server for the Blackcube admin data layer
Requires
- php: ^8.4
- blackcube/active-record: ^1.0
- blackcube/dboard: ^1.0
- blackcube/dcore: ^1.0
- blackcube/injector: ^1.0
- blackcube/yii-bridge-model: ^1.0
- guzzlehttp/guzzle: ^8.1
- mcp/sdk: ^0.8
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- symfony/console: ^8.1
- yiisoft/active-record: ^1.1
- yiisoft/aliases: ^3.1
- yiisoft/cache: ^3.2
- yiisoft/cache-file: ^3.2
- yiisoft/db: ^2.0
- yiisoft/db-migration: ^2.1
- yiisoft/form-model: ^1.1
- yiisoft/hydrator: ^1.6
- yiisoft/injector: ^1.2
- yiisoft/log: ^2.2
Requires (Dev)
- codeception/codeception: ^5.3
- codeception/module-asserts: ^3.3
- codeception/module-db: ^3.2
- httpsoft/http-message: ^1.1
- vlucas/phpdotenv: ^5.7
- yiisoft/db-mysql: ^2.0
- yiisoft/di: ^1.4
- yiisoft/event-dispatcher: ^1.1
- yiisoft/factory: ^1.3
- yiisoft/test-support: ^3.2
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-09-25 14:44:28 UTC
README
MCP server exposing the content administration operations of the Blackcube ecosystem, on top of blackcube/dcore. Opaque MCP keys or OAuth2 access tokens issued by the dboard authorization server, tools gated on dboard permissions, Streamable HTTP transport mounted as a PSR-15 middleware.
You generate an MCP key, or let an LLM client register itself and ask an administrator for consent; then the agent drives the content tree, blocs, taxonomy and discoverability through dcore — no parallel data path, no business logic duplicated.
Authentication
Two credentials open the server, both carrying dboard permissions:
- an opaque MCP key, generated in the dboard "MCP keys" screen or in the console, for the agents you run yourself;
- an OAuth2 access token issued by the dboard authorization server, for LLM clients: the client registers itself (RFC 7591), sends the administrator to the consent screen (authorization code + PKCE), and receives a token bounded by the permissions that administrator holds. The bound is checked again on every request: a right lost in dboard is lost on the server at once.
The server publishes its protected resource metadata (RFC 9728) under /.well-known/oauth-protected-resource followed by the endpoint path, and points at /dboard/oauth/mcp, its population on the dboard side. Each tool declares the dboard permissions it gates on (PERMISSIONS), and MCP:CONNECT is required for any credential.
Quickstart
composer require blackcube/mcp
The package is a dboard addon. Its DI, routes and parameters are merged by yiisoft/config; the host application declares the addon and its migrations in its parameters:
use Blackcube\Mcp\Dboard\McpAddon; return [ 'yiisoft/db-migration' => [ 'sourceNamespaces' => [ 'Blackcube\\Dboard\\Migrations', 'Blackcube\\Dcore\\Migrations', 'Blackcube\\Mcp\\Migrations', ], ], 'blackcube/dboard' => [ 'addons' => [ 'mcp' => [ 'rbac' => [McpAddon::class, 'getRbac'], 'sidebar' => [McpAddon::class, 'getSidebar'], 'routes' => [McpAddon::class, 'getRoutesGroup'], 'population' => [McpAddon::class, 'getPopulation'], 'scopes' => [McpAddon::class, 'getScopes'], ], ], ], 'blackcube/mcp' => [ 'endpoint' => '/mcp', 'maxTtlDays' => 180, 'defaultTtlDays' => 90, 'allowedHosts' => ['cms.example.com'], ], ];
Psr\Clock\ClockInterface is expected from the host application (blackcube/oauth2 provides one); the package does not bind it.
Run the migrations, then create a key. Scopes are dboard permissions: MCP:CONNECT is mandatory, the others are the permissions the tools gate on (McpAddon::getScopes() lists them all). The token is printed once.
php yii.php migrate:up
php yii.php mcp:keyCreate --name="content agent" --scopes=MCP:CONNECT,CONTENT:VIEW
mcp:keyList, mcp:keyRevoke and mcp:keyGc complete the console side; the dboard "MCP keys" screen does the same, rotation included.
Point the MCP client at the endpoint (Streamable HTTP) with the token as a bearer:
{
"mcpServers": {
"blackcube": {
"type": "http",
"url": "https://cms.example.com/mcp",
"headers": {
"Authorization": "Bearer <token>"
}
}
}
}
An OAuth2-capable client needs no key: it discovers the authorization server from /.well-known/oauth-protected-resource/mcp, registers itself and asks an administrator for consent.
Tests
vendor/bin/codecept run
License
BSD-3-Clause. See LICENSE.md.
Author
Philippe Gaultier philippe@blackcube.io