PHPackages                             yoanbernabeu/webmcp-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. yoanbernabeu/webmcp-bundle

ActiveSymfony-bundle[API Development](/categories/api)

yoanbernabeu/webmcp-bundle
==========================

Expose Symfony routes as Web MCP tools via PHP attributes

v0.1.0(2mo ago)91031[1 issues](https://github.com/yoanbernabeu/WebMcpBundle/issues)MITPHPPHP &gt;=8.2CI passing

Since Feb 26Pushed 2mo agoCompare

[ Source](https://github.com/yoanbernabeu/WebMcpBundle)[ Packagist](https://packagist.org/packages/yoanbernabeu/webmcp-bundle)[ GitHub Sponsors](https://github.com/yoanbernabeu)[ RSS](/packages/yoanbernabeu-webmcp-bundle/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (13)Versions (2)Used By (0)

WebMcpBundle
============

[](#webmcpbundle)

[![CI](https://github.com/yoanbernabeu/WebMcpBundle/actions/workflows/testing.yml/badge.svg)](https://github.com/yoanbernabeu/WebMcpBundle/actions/workflows/testing.yml)[![Static Analysis](https://github.com/yoanbernabeu/WebMcpBundle/actions/workflows/code_analysis.yml/badge.svg)](https://github.com/yoanbernabeu/WebMcpBundle/actions/workflows/code_analysis.yml)[![PHP 8.2+](https://camo.githubusercontent.com/744f8821cc27dec8b0013ade48179731a44eadf4f943e0b1d9ffcb93f80177de/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d382e322532422d626c75652e737667)](https://www.php.net/)[![Symfony 6.4+](https://camo.githubusercontent.com/cc7cde293084278ea647dba0f034d6b32745dc870056fe5ee371494c6524d238/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73796d666f6e792d362e342532422d626c61636b2e737667)](https://symfony.com/)[![License: MIT](https://camo.githubusercontent.com/8bb50fd2278f18fc326bf71f6e88ca8f884f72f179d3e555e20ed30157190d0d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e737667)](LICENSE)

> **Experimental** — Web MCP is a [draft specification](https://github.com/webmachinelearning/webmcp) currently being developed by the W3C Web Machine Learning Community Group. The protocol, the browser APIs, and this bundle's API may change at any time. See the [Chrome for Developers blog post](https://developer.chrome.com/blog/webmcp-epp) for more context.

A Symfony bundle that exposes your controller routes as [Web MCP](https://github.com/webmachinelearning/webmcp) tools using simple PHP attributes. No JavaScript to write.

```
#[Route('/api/restaurants', name: 'api_restaurants', methods: ['GET'])]
#[AsWebMcpTool(
    name: 'search_restaurants',
    description: 'Search restaurants by cuisine type',
    inputs: [
        new WebMcpInput('cuisine', type: 'string', description: 'Cuisine type'),
    ]
)]
public function search(): JsonResponse { /* ... */ }
```

```
{{ webmcp_tools() }}
```

That's it. The browser AI can now call your API.

What is Web MCP?
----------------

[](#what-is-web-mcp)

[Web MCP](https://github.com/webmachinelearning/webmcp) (Web Model Context Protocol) is an emerging standard, currently in [draft at the W3C](https://github.com/webmachinelearning/webmcp) (Web Machine Learning Community Group), that provides a browser-level API allowing web pages to expose structured tools to AI.

It builds on top of the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) created by Anthropic, but targets the browser: instead of server-side integrations, the page itself registers tools via `navigator.modelContext.registerTool()`.

AI browser extensions (like [Claude](https://claude.ai), [ChatGPT](https://chatgpt.com), etc.) can then:

- **Discover** available tools, their names, descriptions, and input schemas
- **Call** them with structured parameters
- **Read** the JSON response and use it in the conversation

This turns any web page into an AI-capable endpoint. Instead of the user copy-pasting data between your app and an AI extension, the extension talks directly to your backend.

**Example use case:** A user browsing your app asks the Claude browser extension *"What Italian restaurants are nearby?"*. The extension sees a `search_restaurants` tool is available on the page, calls it with `{"cuisine": "italian"}`, and returns the results in natural language.

You can test and inspect your Web MCP tools with the [Model Context Tool Inspector](https://github.com/beaufortfrancois/model-context-tool-inspector) Chrome extension.

Learn more:

- [WebMCP specification (W3C)](https://github.com/webmachinelearning/webmcp)
- [Chrome for Developers blog post](https://developer.chrome.com/blog/webmcp-epp)
- [Model Context Protocol (MCP)](https://modelcontextprotocol.io/)

Installation
------------

[](#installation)

```
composer require yoanbernabeu/webmcp-bundle
php bin/console assets:install
```

The bundle registers itself automatically via Symfony Flex. The `assets:install` command copies the bundle's JavaScript runtime to `public/bundles/webmcp/`.

Usage
-----

[](#usage)

### Annotate your controllers

[](#annotate-your-controllers)

Each controller method you want to expose as an MCP tool gets two attributes: `#[Route]` (with an explicit `name:`, required) and `#[AsWebMcpTool]`.

#### Simple GET endpoint

[](#simple-get-endpoint)

```
use Symfony\Component\Routing\Attribute\Route;
use YoanBernabeu\WebMcpBundle\Attribute\AsWebMcpTool;

#[Route('/api/menu', name: 'api_menu', methods: ['GET'])]
#[AsWebMcpTool(
    name: 'get_menu',
    description: 'Get the full restaurant menu',
)]
public function menu(): JsonResponse
{
    return $this->json($this->menuRepository->findAll());
}
```

#### GET with query parameters

[](#get-with-query-parameters)

```
use YoanBernabeu\WebMcpBundle\Attribute\WebMcpInput;

#[Route('/api/restaurants', name: 'api_restaurants', methods: ['GET'])]
#[AsWebMcpTool(
    name: 'search_restaurants',
    description: 'Search restaurants, optionally filter by cuisine type',
    inputs: [
        new WebMcpInput('cuisine', type: 'string', description: 'Cuisine type filter'),
        new WebMcpInput('limit', type: 'number', description: 'Max results'),
    ]
)]
public function search(Request $request): JsonResponse
{
    $cuisine = $request->query->get('cuisine');
    // ...
}
```

Inputs without `mapTo` are sent as query string parameters for GET requests.

#### GET with path parameter

[](#get-with-path-parameter)

```
#[Route('/api/restaurants/{id}/menu', name: 'api_restaurant_menu', methods: ['GET'])]
#[AsWebMcpTool(
    name: 'get_restaurant_menu',
    description: 'Get menu for a specific restaurant',
    inputs: [
        new WebMcpInput('restaurant_id', type: 'number', description: 'Restaurant ID', required: true, mapTo: 'id'),
    ]
)]
public function restaurantMenu(int $id): JsonResponse
{
    return $this->json($this->menuRepository->findByRestaurant($id));
}
```

`mapTo: 'id'` maps the input `restaurant_id` to the route parameter `{id}`.

#### POST with JSON body

[](#post-with-json-body)

```
#[Route('/api/orders', name: 'api_create_order', methods: ['POST'])]
#[AsWebMcpTool(
    name: 'place_order',
    description: 'Place a new order',
    inputs: [
        new WebMcpInput('restaurant_id', type: 'number', description: 'Restaurant ID', required: true),
        new WebMcpInput('items', type: 'array', description: 'List of item IDs', required: true),
        new WebMcpInput('notes', type: 'string', description: 'Special instructions'),
    ]
)]
public function placeOrder(Request $request): JsonResponse
{
    $data = json_decode($request->getContent(), true);
    // ...
}
```

For non-GET methods, inputs (except path params) are sent as a JSON body with `Content-Type: application/json`.

### Render the JavaScript

[](#render-the-javascript)

Add the Twig function to your template, typically before ``:

```
{# templates/base.html.twig #}

...

    {% block body %}{% endblock %}

    {{ webmcp_tools() }}

```

This outputs a `` tag that registers all tools via `navigator.modelContext`. If the browser does not support Web MCP, the script does nothing.

Attribute reference
-------------------

[](#attribute-reference)

### `#[AsWebMcpTool]`

[](#aswebmcptool)

Placed on a controller method. The method **must** also have a `#[Route]` with an explicit `name:`.

ParameterTypeRequiredDescription`name``string`YesUnique tool name (duplicates throw at compile time)`description``string`YesTool description visible to the AI`inputs``WebMcpInput[]`NoInput parameters### `WebMcpInput`

[](#webmcpinput)

Value object describing a tool input parameter.

ParameterTypeRequiredDefaultDescription`name``string`YesParameter name`type``string`No`'string'`JSON Schema type (`string`, `number`, `boolean`, `array`)`description``string`No`''`Parameter description visible to the AI`required``bool`No`false`Whether the parameter is required`mapTo``?string`No`null`Route parameter name if different from input name (`mapTo: 'id'` for `{id}`)Security
--------

[](#security)

The bundle does not handle security. Your existing Symfony security applies as-is:

- **Firewalls** — the generated `fetch()` calls carry the browser's session cookies
- **`#[IsGranted]`** — works normally, the AI will receive a 403 error
- **Voters** — same, the controller is called through a standard HTTP request

Rules
-----

[](#rules)

- Each `#[Route]` paired with `#[AsWebMcpTool]` **must have an explicit `name:`** (otherwise: `LogicException` at compile time)
- Tool names **must be unique** across the application (otherwise: `LogicException` indicating both locations)
- Controllers should return JSON (the generated JS calls `response.json()`)

Requirements
------------

[](#requirements)

- PHP &gt;= 8.2
- Symfony 6.4 / 7.x / 8.x
- Twig 3.x / 4.x
- A browser supporting the Web MCP API (`navigator.modelContext`)

Contributing
------------

[](#contributing)

```
composer install

# Full QA (PHPStan + CS-Fixer + PHPUnit)
composer test:all

# PHPUnit only
composer test:fast

# Fix code style
composer test:cs-fix
```

License
-------

[](#license)

[MIT](LICENSE)

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance83

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

73d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/21f6c1e090b5d45bb8bd5569f7779bde35d19fd06844327ed0d369c3544fa2e8?d=identicon)[yoanbernabeu](/maintainers/yoanbernabeu)

---

Top Contributors

[![yoanbernabeu](https://avatars.githubusercontent.com/u/59195351?v=4)](https://github.com/yoanbernabeu "yoanbernabeu (1 commits)")

---

Tags

mcpsymfonysymfony-bundlewebmcp

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/yoanbernabeu-webmcp-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/yoanbernabeu-webmcp-bundle/health.svg)](https://phpackages.com/packages/yoanbernabeu-webmcp-bundle)
```

###  Alternatives

[sylius/sylius

E-Commerce platform for PHP, based on Symfony framework.

8.4k5.6M650](/packages/sylius-sylius)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[shopware/storefront

Storefront for Shopware

684.2M148](/packages/shopware-storefront)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
