Skill api-platform-mcp
Expose les ressources API Platform en tant qu'outils et ressources Model Context Protocol pour les agents IA via des attributs PHP.
- Étoiles GitHub
- 29
- Fichiers
- 1
- Dernier commit
- 22 oct. 2026
- Licence
- —
- Outils autorisés
- —
Que fait la skill api-platform-mcp ?
api-platform-mcp est une agent skill. Expose les ressources API Platform en tant qu'outils et ressources Model Context Protocol pour les agents IA via des attributs PHP.
Résumé généré à partir du SKILL.md de la skill.
À propos du skill api-platform-mcp
Cette compétence permet aux développeurs utilisant API Platform d'exposer des ressources API basées sur PHP en tant qu'outils et ressources Model Context Protocol. Elle permet aux agents IA de découvrir et d'interagir avec votre logique backend existante en transformant des classes PHP en outils appelables ou en ressources en lecture seule. Cela est réalisé grâce à des attributs spécialisés tels que #[McpTool] pour l'exécution de commandes et #[McpResource] pour la récupération de contenu comme la documentation ou la configuration.
Les développeurs peuvent intégrer cela dans des applications Symfony ou Laravel pour fournir des données structurées ou des réponses personnalisées. Le système réutilise votre pile de métadonnées existante, y compris les state processors, les providers et la validation. Vous pouvez définir des schémas d'entrée spécifiques à l'aide de DTO, gérer des collections avec McpToolCollection, ou contourner la sérialisation JSON standard en renvoyant un CallToolResult. Cela garantit qu'un LLM peut interagir avec votre API via des opérations standard de type tools/call et resources/read sans avoir besoin de routes HTTP traditionnelles.
Ce qu'un agent peut faire avec
- 1Exposer la logique backend sous forme d'outilsTransformez une classe PHP spécifique en un outil appelable qu'un agent IA peut utiliser pour traiter des données.
- 2Appliquer des règles métier sur les entrées de l'agentGarantissez que les données envoyées par un agent IA respectent des contraintes de validation spécifiques, comme les formats d'e-mail ou la longueur des chaînes de caractères.
Rédigé à partir du SKILL.md du skill. Chaque cas d'utilisation est vérifié par rapport à une citation de celui-ci.
Comment installer la skill api-platform-mcp
Chaque commande copie le dossier de la skill dans le répertoire des skills du client. Redémarrez le client ou démarrez une nouvelle session pour la charger.Installer la skill api-platform-mcp dans Plugin
/plugin marketplace add api-platform/skillset /plugin install api-platform@api-platform-skillset
Installer la skill api-platform-mcp dans Claude Code
~/.claude/skills/api-platform-mcp/SKILL.md
$ npx degit api-platform/skillset/skills/api-platform-mcp ~/.claude/skills/api-platform-mcpInstaller la skill api-platform-mcp dans Claude Code (project)
.claude/skills/api-platform-mcp/SKILL.md
$ npx degit api-platform/skillset/skills/api-platform-mcp .claude/skills/api-platform-mcpInstaller la skill api-platform-mcp dans Codex
~/.agents/skills/api-platform-mcp/SKILL.md
$ npx degit api-platform/skillset/skills/api-platform-mcp ~/.agents/skills/api-platform-mcpInstaller la skill api-platform-mcp dans Gemini CLI
~/.gemini/skills/api-platform-mcp/SKILL.md
$ npx degit api-platform/skillset/skills/api-platform-mcp ~/.gemini/skills/api-platform-mcpInstaller la skill api-platform-mcp dans Claude.ai
npx degit api-platform/skillset/skills/api-platform-mcp api-platform-mcp && zip -r api-platform-mcp.zip api-platform-mcp # claude.ai → Customize → Skills → + → Create skill → Upload a skill → api-platform-mcp.zip
SKILL.md
Voir sur GitHubMCP: Exposing Your API to AI Agents
API Platform turns PHP classes into Model Context Protocol tools and resources. It reuses the existing metadata stack — state processors/providers, validation, serialization, JSON Schema — so an MCP tool is just an operation with no HTTP route.
@experimental. API may change between minor releases.
Install & enable
Symfony — composer require api-platform/mcp symfony/mcp-bundle (bundle namespace is
Symfony\AI\McpBundle, composer name symfony/mcp-bundle):
# config/packages/mcp.yaml
mcp:
client_transports:
http: true
stdio: false
http:
path: "/mcp"
session: { store: "file", directory: "%kernel.cache_dir%/mcp", ttl: 3600 }
# config/packages/api_platform.yaml
api_platform:
mcp:
enabled: true # default: true
format: jsonld # default; must be a registered api_platform.format (json, jsonapi, …)
format sets the serialization format for structured content. jsonld emits @context,
@id, @type. Laravel — enabled by default, endpoint auto-registered at /mcp:
// config/api-platform.php
return [ /* … */ 'mcp' => ['enabled' => true] ];
API Platform registers its own SDK Handler; supports() returns true only for tools/resources
in its registry, otherwise the SDK's own handler chain runs. API Platform tools and native
mcp/sdk tools coexist on the same server.
Two ways to declare a tool
Standalone #[McpTool] class attribute — convenient for a one-off tool. Class properties
become the inputSchema; a state processor handles the command
(CQRS-style — the agent's input is processed through your logic):
use ApiPlatform\Metadata\McpTool;
#[McpTool(
name: 'process_message',
description: 'Process a message with priority',
processor: [self::class, 'process'],
)]
class ProcessMessage
{
public function __construct(
private string $message,
private int $priority = 1,
) {}
// getters + setters drive (de)serialization
public static function process($data): mixed
{
$data->setMessage('Processed: '.$data->getMessage());
return $data;
}
}
The agent's arguments are deserialized into a ProcessMessage, passed to the processor; the
returned object is serialized back as structured content. processor is any callable or a
ProcessorInterface service.
mcp: array on #[ApiResource] — use when the class exposes no HTTP endpoints
(operations: []), combines several MCP operations, or needs resource-level control. Keys are
the tool names, so omit name: inside each new McpTool(...):
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\McpTool;
use App\State\ReadHydraResourceProcessor;
#[ApiResource(
operations: [],
mcp: [
'read_hydra_resource' => new McpTool(
description: 'Navigate to a Hydra API resource by URI.',
processor: ReadHydraResourceProcessor::class,
structuredContent: false,
),
],
)]
class ReadHydraResource
{
public string $uri;
}
Separate input DTO
When the input schema must differ from the result class, point input: at a DTO. That DTO drives
inputSchema; the host class describes the output:
#[McpTool(
name: 'search_books',
description: 'Search books by keyword',
input: SearchQuery::class, // what the agent sends
processor: SearchBooksProcessor::class,
)]
class BookSearchResult
{
public int $id;
public string $title;
public string $isbn;
}
The processor receives a SearchQuery instance and returns the result(s).
Collections — McpToolCollection
Use McpToolCollection (extends McpTool, implements CollectionOperationInterface) when a tool
returns a list — the serializer and schema factory emit collection-shaped output:
use ApiPlatform\Metadata\McpToolCollection;
#[ApiResource(operations: [], mcp: [
'list_books' => new McpToolCollection(
description: 'List Books',
input: SearchQuery::class,
processor: SearchBooksProcessor::class,
structuredContent: true,
),
])]
class Book { public ?int $id = null; public ?string $title = null; public ?string $isbn = null; }
With structuredContent: true and the default jsonld format, the response carries @context,
hydra:totalItems, and a hydra:member array of serialized items; the published outputSchema
reflects that shape. Output schemas are flattened for MCP compliance — no $ref, allOf,
$schema, or definitions.
Custom responses — CallToolResult
Default: results serialize through API Platform's serialization
as structured JSON. For full control, set structuredContent: false and return a CallToolResult:
use Mcp\Schema\Content\TextContent;
use Mcp\Schema\Result\CallToolResult;
#[McpTool(name: 'generate_report', description: 'Generate a markdown report',
processor: [self::class, 'process'], structuredContent: false)]
class Report
{
public function __construct(private string $title, private string $content) {}
// getters/setters …
public static function process($data): CallToolResult
{
return new CallToolResult(
[new TextContent("# {$data->getTitle()}\n\n{$data->getContent()}")],
false, // isError
// 3rd arg: optional _meta array
);
}
}
structuredContent: false disables automatic JSON serialization; the CallToolResult is sent
as-is, with no structuredContent / _meta key in the response.
Schema overrides — the nullable-union gotcha
PHP nullable types generate union schemas like {"type": ["array", "null"]}. Some LLM providers
reject these. Override per property with #[ApiProperty(schema: [...])]:
use ApiPlatform\Metadata\ApiProperty;
class InvokeHydraOperation
{
public string $uri;
public string $method;
#[ApiProperty(schema: ['type' => 'object', 'description' => 'JSON payload for the request'])]
public ?array $payload = null; // without override: {"type": ["array","null"]}
}
Validation — off by default
The MCP SDK validates inputs against the JSON Schema at transport level (types, required fields).
API Platform's own validation pipeline is disabled for MCP tools. Set validate: true to
run business constraints (email format, length, custom rules):
use Symfony\Component\Validator\Constraints as Assert;
#[McpTool(name: 'submit_contact', description: 'Submit a contact form',
processor: [self::class, 'process'], validate: true)]
class ContactForm
{
#[Assert\NotBlank] #[Assert\Length(min: 3, max: 50)]
private ?string $name = null;
#[Assert\NotNull] #[Assert\Email]
private ?string $email = null;
}
Laravel — same validate: true, plus rules: instead of constraints:
#[McpTool(name: 'submit_contact', description: '…', processor: [self::class, 'process'],
validate: true, rules: ['name' => 'required|min:3|max:50', 'email' => 'required|email'])]
Read-only resources — #[McpResource]
Expose retrievable content (docs, config, reference data) backed by a
state provider. uri must be unique and use the resource:// scheme:
use ApiPlatform\Metadata\McpResource;
#[ApiResource(operations: [], mcp: [
'api_docs' => new McpResource(
uri: 'resource://my-app/documentation',
name: 'App-Documentation',
description: 'Application API documentation',
mimeType: 'text/markdown',
provider: [self::class, 'provide'],
),
])]
class Documentation
{
public function __construct(private string $content, private string $uri) {}
public static function provide(): self
{
return new self('# My API Documentation\n\nWelcome.', 'resource://my-app/documentation');
}
}
Options
McpTool and McpResource extend HttpOperation, so they accept all standard
operation options. MCP-specific / notable ones:
| Option | Tool | Res | Notes |
|---|---|---|---|
name |
✓ | ✓ | exposed to agents; defaults to class short name. Omit in mcp: array (key wins) |
description |
✓ | ✓ | defaults to class DocBlock |
structuredContent |
✓ | ✓ | include JSON structured content (default true) |
input / output |
✓ | separate DTO for input schema / output representation | |
inputFormats / outputFormats |
✓ | (de)serialization formats, e.g. ['json'], ['jsonld'] |
|
contentNegotiation |
✓ | ✓ | default false for MCP |
validate |
✓ | run validation pipeline (default false for MCP) |
|
rules |
✓ | Laravel validation rules (Laravel only) | |
annotations/icons/meta |
✓ | ✓ | behavior hints / icon URLs / arbitrary metadata |
uri |
✓ | required, resource:// scheme, unique across server |
|
mimeType / size |
✓ | content MIME type / byte size if known |
Wire protocol (for testing)
Everything is JSON-RPC 2.0 POSTed to /mcp with
Accept: application/json, text/event-stream. initialize returns an mcp-session-id header;
send it back on every subsequent call. tools/list / resources/list enumerate; tools/call
(params: {name, arguments}) and resources/read (params: {uri}) invoke. The handler overrides
Accept to the operation's output format, so a jsonld tool always responds JSON-LD regardless
of use_symfony_listeners.
Laravel
- Config under
mcpinconfig/api-platform.php; endpoint auto-registered at/mcp. - Validation uses
rules:(string/array/closure/FormRequest), not Symfony constraints. - MongoDB is not supported for MCP.
Checklist
-
api-platform/mcp+symfony/mcp-bundleinstalled,/mcptransport configured (Symfony) - Tool class has a
processor(write) orMcpResourcehas aprovider(read) -
operations: []when the class is MCP-only (no HTTP routes) -
name:omitted insidemcp:array entries (the array key is the name) -
McpToolCollection(notMcpTool) for list-returning tools -
structuredContent: false+CallToolResultwhen bypassing JSON serialization - Nullable/union properties overridden with
#[ApiProperty(schema: …)]if the LLM rejects them -
validate: trueset explicitly where business constraints must run -
McpResourceuriis unique and usesresource://
Fichiers de cette skill
1Questions sur la skill api-platform-mcp
Comment installer la skill api-platform-mcp dans Claude Code ?
Exécutez npx degit api-platform/skillset/skills/api-platform-mcp ~/.claude/skills/api-platform-mcp. Claude Code charge les skills depuis ~/.claude/skills (tous les projets) ou .claude/skills (un seul projet) et utilise une skill lorsque sa description correspond à la tâche.
Quels clients peuvent utiliser la skill api-platform-mcp ?
Tout client qui lit le format Agent Skills : Claude Code, Codex, Gemini CLI et claude.ai (envoi sous forme de ZIP). Les scripts de la skill ne s'exécutent que si le client autorise l'exécution de code.
Comment puis-je renvoyer une liste d'éléments à un agent IA ?
Utilisez la classe McpToolCollection au lieu de McpTool lorsqu'un outil doit renvoyer une collection d'éléments.
API Platform exécute-t-il sa validation standard pour les outils MCP ?
Non, le pipeline de validation d'API Platform est désactivé par défaut pour les outils MCP ; vous devez explicitement définir validate: true pour exécuter les contraintes métier.
Comment gérer les propriétés nullables que les LLM pourraient rejeter ?
Vous pouvez surcharger le JSON-Schema pour des propriétés spécifiques en utilisant l'attribut #[ApiProperty(schema: [...])].