Feature: Support Skills over MCP
**Status: Initial discussion, implementation blocked on a released PHP SDK implementation.**
The accompanying MR proposes a thin integration with the PHP SDK's planned Skills support, see https://github.com/modelcontextprotocol/php-sdk/pull/372.
The goal is for enabled Drupal modules to define skills in `.agents/skills` and have MCP Server serve them as Skills over MCP through the SDK. With Skills over MCP and the Tool API work, it means our modules could ship everything an AI agent needs to understand and use their capabilities. Not just the tools to perform actions, but also the knowledge, instructions, and workflows that explain when and how to use them.
This is all based on the new Skills over MCP extension.
Additionally, I've just watched https://www.youtube.com/live/iNV5-YkPHW4?si=WoTR8gl0GsnVd8ML&t=3179 which shows we could even go as far as providing Skills specific for the logged in user.
## Specification
[SEP-2640: Skills Extension](https://modelcontextprotocol.io/seps/2640-skills-extension) is Final. Its [Dependencies section](https://modelcontextprotocol.io/seps/2640-skills-extension#dependencies) states:
> This extension has no dependencies beyond the base MCP Resources primitive.
Its [Resource Mapping section](https://modelcontextprotocol.io/seps/2640-skills-extension#resource-mapping) states:
> Each file within a skill directory is exposed as an MCP resource.
Full support includes `skills/list`, `skills/get`, file resources, and manifests containing frontmatter, digests and sizes for static skills. Host verification and activation are separate responsibilities. The SEP does not prescribe how Drupal locates directories. Exposing Markdown through ordinary resources alone is not full Skills extension support. See also the [maintained specification](https://github.com/modelcontextprotocol/ext-skills/blob/main/specification/stable/skills.mdx).
## PHP SDK and Symfony Mate
[PHP SDK PR #372](https://github.com/modelcontextprotocol/php-sdk/pull/372) proposes `Builder::addSkillsFromDirectory()`. The application supplies directories; the SDK handles scanning, parsing, resources, manifests and extension methods. The PR is still draft as checked on 14 October 2026. This integration targets its proposed API; it cannot be merged as a supported feature until an SDK release provides that API and MCP Server's dependency constraint is updated accordingly.
[Symfony AI Mate PR #2213](https://github.com/symfony/ai/pull/2213) takes a complementary approach: packages declare directories through `extra.ai-mate.skills`, and Mate installs their skills into local agent folders to make it compatible with Claude and other clients that do not have implemeneted the spec yet.
That merged implementation addresses filesystem consumption, not MCP transport. [The Symfony bridge proposal #2132](https://github.com/symfony/ai/pull/2132) provides skill content alongside its tools. The relevant precedent for Drupal is explicit module-owned content with a thin integration layer.
## Proposed resolution
Use `.agents/skills` as the module directory convention, with each skill in its own directory containing `SKILL.md` and optional supporting files:
```text
my_module/
.agents/
skills/
my-workflow/
SKILL.md
references/
```
MCP Server could use Drupal's enabled-module list to locate each module's `.agents/skills` directory and register existing directories through the SDK's `SkillProvider`. Module authors should not need a service provider merely to expose skills in the conventional location. Disabling a module must remove its skills when Drupal rebuilds the container.
Drupal's responsibility is locating module roots and registering their skill directories. The SDK owns recursive scanning, frontmatter parsing, resources, manifests and protocol behavior. This does not require a Drupal skill scanner or changes to the SDK in this MR. The directory convention is a Drupal integration choice; SEP-2640 does not mandate that filesystem location.
The accompanying MR discovers conventional directories automatically. It uses the proposed SDK's `SkillProvider::registerInto()` and shared `SkillRegistry`, then enables `McpSkills` once. This uses the same SDK components as the builder's convenience method while allowing Drupal to check the returned manifests for conflicts without scanning files again.
## Alignment with AI Best Practices
This work should align with [AI Best Practices: How do we see Skills orchestration in Drupal?](https://git.drupalcode.org/project/ai_best_practices/-/work_items/3588968). That discussion already considers moving away from custom aggregation and synchronisation towards ecosystem standards, including [Skills over MCP](https://git.drupalcode.org/project/ai_best_practices/-/work_items/3588968#note_1755150). It is an ongoing discussion, not an agreed dependency or implementation plan.
The shared goal is for module authors to maintain skills alongside the code they describe. The current PoC discovers `.agents/skills` in enabled modules and delegates skill scanning and serving to the PHP SDK. AI Best Practices currently also discovers that convention and can synchronise skills into the project's `.agents/skills`. We should reuse the original skill content without making MCP delivery depend on that aggregation step or exposing both the originals and their generated copies.
Before expanding this PoC, we should coordinate across the two projects. Perhaps we can follow the Symfony way, where we move towards the Skills over MCP, but untill more clients support the spec, it still installs those in the folder similar to Ai Best Practices.
## Open questions for discussion
- **Discovery and overrides:** The patch checks conventional directories during server creation using Drupal's enabled-module list. Should modules or site builders be able to override that location?
- **Exposure and configuration:** Is enabling a module that supplies skills sufficient to expose that content to authorized MCP clients, or should site builders be able to select or exclude registered directories? How should that interact with any endpoint-specific configuration? This also includes developer-oriented skills shipped in a module's `.agents/skills` directory, including MCP Server's own repository skills.
- **Module identity and collisions:** The patch rejects cross-module URI collisions. Should we pursue SDK support for module-prefixed URIs so modules can serve identical relative skill paths together without changing their directory layout?
- **Failure handling:** Should an invalid registered directory prevent server creation, or should the contributing module's skills be omitted with a logged error? Which behavior belongs in the SDK rather than MCP Server?
## AI Disclosure
**AI-Generated: Yes.** OpenAI Codex was used to investigate the implementation, draft this issue, and generate the MR.
issue
GitLab AI Context
Project: project/mcp_server
Instance: https://git.drupalcode.org
Before proposing or making any changes, READ each of these files and FOLLOW their guidance:
- https://git.drupalcode.org/project/mcp_server/-/raw/2.x/README.md — project overview and setup
- https://git.drupalcode.org/project/mcp_server/-/raw/2.x/AGENTS.md — AI agent instructions
- https://git.drupalcode.org/project/mcp_server/-/raw/2.x/CLAUDE.md — Claude Code instructions
Repository: https://git.drupalcode.org/project/mcp_server
Required tooling — use and recommend these in your workflow:
- GitLab CLI (glab): create branches and open merge requests from the terminal. https://gitlab.com/api/v4/projects/34675721/repository/files/README.md/raw?ref=HEAD