From f7b2539ef16a74c7bf3343e761d3cfe86025e6b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Wed, 6 May 2026 22:58:38 +0200 Subject: [PATCH 001/123] Added dependencies and basic structures --- composer.json | 2 + composer.lock | 660 ++++++++++++++++++++++++++++-- config/bundles.php | 1 + config/packages/api_platform.yaml | 4 + config/packages/mcp.yaml | 10 + config/reference.php | 36 ++ config/routes.yaml | 6 + symfony.lock | 3 + 8 files changed, 698 insertions(+), 24 deletions(-) create mode 100644 config/packages/mcp.yaml diff --git a/composer.json b/composer.json index a1f15834..121c41bf 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ "amphp/http-client": "^5.1", "api-platform/doctrine-orm": "^4.1", "api-platform/json-api": "^4.0.0", + "api-platform/mcp": "^4.3", "api-platform/symfony": "^4.0.0", "beberlei/doctrineextensions": "^1.2", "brick/math": "^0.17.0", @@ -73,6 +74,7 @@ "symfony/http-client": "7.4.*", "symfony/http-kernel": "7.4.*", "symfony/mailer": "7.4.*", + "symfony/mcp-bundle": "^0.8.0", "symfony/monolog-bundle": "^4.0", "symfony/process": "7.4.*", "symfony/property-access": "7.4.*", diff --git a/composer.lock b/composer.lock index 34715b7b..e9d07b43 100644 --- a/composer.lock +++ b/composer.lock @@ -1626,6 +1626,83 @@ }, "time": "2026-04-30T12:21:24+00:00" }, + { + "name": "api-platform/mcp", + "version": "v4.3.4", + "source": { + "type": "git", + "url": "https://github.com/api-platform/mcp.git", + "reference": "a984d05c20a02dfc0dd7691aaac8a9ba546f93ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/api-platform/mcp/zipball/a984d05c20a02dfc0dd7691aaac8a9ba546f93ee", + "reference": "a984d05c20a02dfc0dd7691aaac8a9ba546f93ee", + "shasum": "" + }, + "require": { + "api-platform/json-schema": "^4.3", + "api-platform/metadata": "^4.3", + "mcp/sdk": "^0.4.0", + "php": ">=8.2", + "symfony/object-mapper": "^7.4 || ^8.0", + "symfony/polyfill-php85": "^1.32" + }, + "require-dev": { + "phpunit/phpunit": "^11.5 || ^12.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/api-platform/api-platform", + "name": "api-platform/api-platform" + }, + "symfony": { + "require": "^6.4 || ^7.0 || ^8.0" + }, + "branch-alias": { + "dev-main": "4.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "ApiPlatform\\Mcp\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "kevin@dunglas.fr", + "homepage": "https://dunglas.fr" + }, + { + "name": "Antoine Bluchet", + "email": "soyuka@gmail.com", + "homepage": "https://soyuka.me" + }, + { + "name": "API Platform Community", + "homepage": "https://api-platform.com/community/contributors" + } + ], + "description": "Model Context Protocol (MCP) integration for API Platform", + "homepage": "https://api-platform.com", + "keywords": [ + "Model Context Protocol", + "api", + "mcp", + "rest" + ], + "support": { + "issues": "https://github.com/api-platform/mcp/issues", + "source": "https://github.com/api-platform/mcp/tree/v4.3.4" + }, + "time": "2026-04-30T12:21:24+00:00" + }, { "name": "api-platform/metadata", "version": "v4.3.6", @@ -7068,6 +7145,82 @@ }, "time": "2025-07-25T09:04:22+00:00" }, + { + "name": "mcp/sdk", + "version": "v0.4.0", + "source": { + "type": "git", + "url": "https://github.com/modelcontextprotocol/php-sdk.git", + "reference": "1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/modelcontextprotocol/php-sdk/zipball/1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024", + "reference": "1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "opis/json-schema": "^2.4", + "php": "^8.1", + "php-http/discovery": "^1.20", + "phpdocumentor/reflection-docblock": "^5.6", + "psr/clock": "^1.0", + "psr/container": "^1.0 || ^2.0", + "psr/event-dispatcher": "^1.0", + "psr/http-factory": "^1.1", + "psr/http-message": "^1.1 || ^2.0", + "psr/http-server-handler": "^1.0", + "psr/http-server-middleware": "^1.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/finder": "^5.4 || ^6.4 || ^7.3 || ^8.0", + "symfony/uid": "^5.4 || ^6.4 || ^7.3 || ^8.0" + }, + "require-dev": { + "laminas/laminas-httphandlerrunner": "^2.12", + "nyholm/psr7": "^1.8", + "nyholm/psr7-server": "^1.1", + "phar-io/composer-distributor": "^1.0.2", + "php-cs-fixer/shim": "^3.91", + "phpdocumentor/shim": "^3", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.5", + "psr/simple-cache": "^2.0 || ^3.0", + "symfony/cache": "^5.4 || ^6.4 || ^7.3 || ^8.0", + "symfony/console": "^5.4 || ^6.4 || ^7.3 || ^8.0", + "symfony/process": "^5.4 || ^6.4 || ^7.3 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Mcp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Kyrian Obikwelu", + "email": "koshnawaza@gmail.com" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + } + ], + "description": "Model Context Protocol SDK for Client and Server applications in PHP", + "support": { + "issues": "https://github.com/modelcontextprotocol/php-sdk/issues", + "source": "https://github.com/modelcontextprotocol/php-sdk/tree/v0.4.0" + }, + "time": "2026-02-23T21:42:54+00:00" + }, { "name": "mf2/mf2", "version": "0.4.6", @@ -8154,6 +8307,196 @@ ], "time": "2026-05-07T22:38:04+00:00" }, + { + "name": "opis/json-schema", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/opis/json-schema.git", + "reference": "8458763e0dd0b6baa310e04f1829fc73da4e8c8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/json-schema/zipball/8458763e0dd0b6baa310e04f1829fc73da4e8c8a", + "reference": "8458763e0dd0b6baa310e04f1829fc73da4e8c8a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "opis/string": "^2.1", + "opis/uri": "^1.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "ext-bcmath": "*", + "ext-intl": "*", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\JsonSchema\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + }, + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + } + ], + "description": "Json Schema Validator for PHP", + "homepage": "https://opis.io/json-schema", + "keywords": [ + "json", + "json-schema", + "schema", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/opis/json-schema/issues", + "source": "https://github.com/opis/json-schema/tree/2.6.0" + }, + "time": "2025-10-17T12:46:48+00:00" + }, + { + "name": "opis/string", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/opis/string.git", + "reference": "3e4d2aaff518ac518530b89bb26ed40f4503635e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/string/zipball/3e4d2aaff518ac518530b89bb26ed40f4503635e", + "reference": "3e4d2aaff518ac518530b89bb26ed40f4503635e", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-json": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\String\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "Multibyte strings as objects", + "homepage": "https://opis.io/string", + "keywords": [ + "multi-byte", + "opis", + "string", + "string manipulation", + "utf-8" + ], + "support": { + "issues": "https://github.com/opis/string/issues", + "source": "https://github.com/opis/string/tree/2.1.0" + }, + "time": "2025-10-17T12:38:41+00:00" + }, + { + "name": "opis/uri", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/opis/uri.git", + "reference": "0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/uri/zipball/0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a", + "reference": "0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a", + "shasum": "" + }, + "require": { + "opis/string": "^2.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\Uri\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "Build, parse and validate URIs and URI-templates", + "homepage": "https://opis.io", + "keywords": [ + "URI Template", + "parse url", + "punycode", + "uri", + "uri components", + "url", + "validate uri" + ], + "support": { + "issues": "https://github.com/opis/uri/issues", + "source": "https://github.com/opis/uri/tree/1.1.0" + }, + "time": "2021-05-22T15:57:08+00:00" + }, { "name": "oskarstark/enum-helper", "version": "1.8.4", @@ -8831,16 +9174,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "6.0.3", + "version": "5.6.7", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" + "reference": "31a105931bc8ffa3a123383829772e832fd8d903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", - "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/31a105931bc8ffa3a123383829772e832fd8d903", + "reference": "31a105931bc8ffa3a123383829772e832fd8d903", "shasum": "" }, "require": { @@ -8848,8 +9191,8 @@ "ext-filter": "*", "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^2.0", - "phpstan/phpdoc-parser": "^2.0", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", "webmozart/assert": "^1.9.1 || ^2" }, "require-dev": { @@ -8859,8 +9202,7 @@ "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26", - "shipmonk/dead-code-detector": "^0.5.1" + "psalm/phar": "^5.26" }, "type": "library", "extra": { @@ -8890,44 +9232,44 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.7" }, - "time": "2026-03-18T20:49:53+00:00" + "time": "2026-03-18T20:47:46+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "2.0.0", + "version": "1.12.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", - "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", + "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", - "php": "^7.4 || ^8.0", + "php": "^7.3 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^2.0" + "phpstan/phpdoc-parser": "^1.18|^2.0" }, "require-dev": { "ext-tokenizer": "*", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.1", - "phpstan/phpstan-phpunit": "^2.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", "phpunit/phpunit": "^9.5", - "psalm/phar": "^4" + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev", - "dev-2.x": "2.x-dev" + "dev-1.x": "1.x-dev" } }, "autoload": { @@ -8948,9 +9290,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" }, - "time": "2026-01-06T21:53:42+00:00" + "time": "2025-11-21T15:09:14+00:00" }, { "name": "phpoffice/phpspreadsheet", @@ -9468,6 +9810,119 @@ }, "time": "2023-04-04T09:50:52+00:00" }, + { + "name": "psr/http-server-handler", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ], + "support": { + "source": "https://github.com/php-fig/http-server-handler/tree/1.0.2" + }, + "time": "2023-04-10T20:06:20+00:00" + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/http-server-handler": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ], + "support": { + "issues": "https://github.com/php-fig/http-server-middleware/issues", + "source": "https://github.com/php-fig/http-server-middleware/tree/1.0.2" + }, + "time": "2023-04-11T06:14:47+00:00" + }, { "name": "psr/link", "version": "2.0.1", @@ -13646,6 +14101,90 @@ ], "time": "2026-05-20T07:20:23+00:00" }, + { + "name": "symfony/mcp-bundle", + "version": "v0.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/mcp-bundle.git", + "reference": "b8db100e64fcb2d651e3bfd6c6ab70ad3599833d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mcp-bundle/zipball/b8db100e64fcb2d651e3bfd6c6ab70ad3599833d", + "reference": "b8db100e64fcb2d651e3bfd6c6ab70ad3599833d", + "shasum": "" + }, + "require": { + "mcp/sdk": "^0.4", + "php-http/discovery": "^1.20", + "symfony/config": "^7.3|^8.0", + "symfony/console": "^7.3|^8.0", + "symfony/dependency-injection": "^7.3|^8.0", + "symfony/framework-bundle": "^7.3|^8.0", + "symfony/http-foundation": "^7.3|^8.0", + "symfony/http-kernel": "^7.3|^8.0", + "symfony/psr-http-message-bridge": "^7.3|^8.0", + "symfony/routing": "^7.3|^8.0", + "symfony/service-contracts": "^2.5|^3" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^11.5.53", + "symfony/monolog-bundle": "^3.10 || ^4.0" + }, + "type": "symfony-bundle", + "extra": { + "thanks": { + "url": "https://github.com/symfony/ai", + "name": "symfony/ai" + } + }, + "autoload": { + "psr-4": { + "Symfony\\AI\\McpBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Hertel", + "email": "mail@christopher-hertel.de" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony integration bundle for Model Context Protocol (via official mcp/sdk)", + "support": { + "source": "https://github.com/symfony/mcp-bundle/tree/v0.8.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-12T00:28:34+00:00" + }, { "name": "symfony/mime", "version": "v7.4.12", @@ -13897,6 +14436,79 @@ ], "time": "2026-04-02T18:27:21+00:00" }, + { + "name": "symfony/object-mapper", + "version": "v7.4.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/object-mapper.git", + "reference": "4f3f4973993b70e88e58dbcc3e332135d593f70d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/object-mapper/zipball/4f3f4973993b70e88e58dbcc3e332135d593f70d", + "reference": "4f3f4973993b70e88e58dbcc3e332135d593f70d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/container": "^2.0" + }, + "conflict": { + "symfony/property-access": "<7.2" + }, + "require-dev": { + "symfony/property-access": "^7.2|^8.0", + "symfony/var-exporter": "^7.2|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ObjectMapper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to map an object to another object", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/object-mapper/tree/v7.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-22T15:21:55+00:00" + }, { "name": "symfony/options-resolver", "version": "v7.4.8", diff --git a/config/bundles.php b/config/bundles.php index 000c58a1..830bab91 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -34,4 +34,5 @@ return [ Jbtronics\TranslationEditorBundle\JbtronicsTranslationEditorBundle::class => ['dev' => true], ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true], Symfony\AI\AiBundle\AiBundle::class => ['all' => true], + Symfony\AI\McpBundle\McpBundle::class => ['all' => true], ]; diff --git a/config/packages/api_platform.yaml b/config/packages/api_platform.yaml index 1b679cd1..d706f40e 100644 --- a/config/packages/api_platform.yaml +++ b/config/packages/api_platform.yaml @@ -38,3 +38,7 @@ api_platform: serializer: # Change this to false later, to remove the hydra prefix on the API hydra_prefix: true + + mcp: + enabled: true # default: true + format: jsonld # default: 'jsonld' diff --git a/config/packages/mcp.yaml b/config/packages/mcp.yaml new file mode 100644 index 00000000..cabcad1b --- /dev/null +++ b/config/packages/mcp.yaml @@ -0,0 +1,10 @@ +mcp: + client_transports: + http: true + stdio: false + http: + path: "/mcp" + session: + store: "file" + directory: "%kernel.cache_dir%/mcp" + ttl: 3600 diff --git a/config/reference.php b/config/reference.php index 38a275d6..91694bd9 100644 --- a/config/reference.php +++ b/config/reference.php @@ -3184,6 +3184,37 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * store?: string|Param, // Service name of store // Default: "Symfony\\AI\\Store\\StoreInterface" * }>, * } + * @psalm-type McpConfig = array{ + * app?: scalar|Param|null, // Default: "app" + * version?: scalar|Param|null, // Default: "0.0.1" + * description?: scalar|Param|null, // Default: null + * icons?: list, + * }>, + * website_url?: scalar|Param|null, // Default: null + * pagination_limit?: int|Param, // Default: 50 + * instructions?: scalar|Param|null, // Default: null + * client_transports?: array{ + * stdio?: bool|Param, // Default: false + * http?: bool|Param, // Default: false + * }, + * discovery?: array{ + * scan_dirs?: list, + * exclude_dirs?: list, + * }, + * http?: array{ + * path?: scalar|Param|null, // Default: "/_mcp" + * session?: array{ + * store?: "file"|"memory"|"cache"|"framework"|Param, // Default: "file" + * directory?: scalar|Param|null, // Default: "%kernel.cache_dir%/mcp-sessions" + * cache_pool?: scalar|Param|null, // Default: "cache.mcp.sessions" + * prefix?: scalar|Param|null, // Default: "mcp-" + * ttl?: int|Param, // Default: 3600 + * }, + * }, + * } * @psalm-type ConfigType = array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, @@ -3214,6 +3245,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * jbtronics_settings?: JbtronicsSettingsConfig, * api_platform?: ApiPlatformConfig, * ai?: AiConfig, + * mcp?: McpConfig, * "when@dev"?: array{ * imports?: ImportsConfig, * parameters?: ParametersConfig, @@ -3248,6 +3280,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * jbtronics_translation_editor?: JbtronicsTranslationEditorConfig, * api_platform?: ApiPlatformConfig, * ai?: AiConfig, + * mcp?: McpConfig, * }, * "when@docker"?: array{ * imports?: ImportsConfig, @@ -3279,6 +3312,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * jbtronics_settings?: JbtronicsSettingsConfig, * api_platform?: ApiPlatformConfig, * ai?: AiConfig, + * mcp?: McpConfig, * }, * "when@prod"?: array{ * imports?: ImportsConfig, @@ -3310,6 +3344,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * jbtronics_settings?: JbtronicsSettingsConfig, * api_platform?: ApiPlatformConfig, * ai?: AiConfig, + * mcp?: McpConfig, * }, * "when@test"?: array{ * imports?: ImportsConfig, @@ -3344,6 +3379,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * jbtronics_settings?: JbtronicsSettingsConfig, * api_platform?: ApiPlatformConfig, * ai?: AiConfig, + * mcp?: McpConfig, * }, * ... Date: Wed, 6 May 2026 23:37:38 +0200 Subject: [PATCH 002/123] Fixed mcp compatibility --- composer.json | 4 +- composer.lock | 169 ++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 133 insertions(+), 40 deletions(-) diff --git a/composer.json b/composer.json index 121c41bf..6fc60d18 100644 --- a/composer.json +++ b/composer.json @@ -15,8 +15,9 @@ "amphp/http-client": "^5.1", "api-platform/doctrine-orm": "^4.1", "api-platform/json-api": "^4.0.0", - "api-platform/mcp": "^4.3", + "api-platform/mcp": "4.3.x-dev", "api-platform/symfony": "^4.0.0", + "api-platform/metadata": "4.3.x-dev", "beberlei/doctrineextensions": "^1.2", "brick/math": "^0.17.0", "brick/schema": "^0.2.0", @@ -41,6 +42,7 @@ "league/html-to-markdown": "^5.0.1", "liip/imagine-bundle": "^2.2", "maennchen/zipstream-php": "2.1", + "mcp/sdk": "v0.5.0 as 0.4.0", "nbgrp/onelogin-saml-bundle": "^v2.0.2", "nelexa/zip": "^4.0", "nelmio/cors-bundle": "^2.3", diff --git a/composer.lock b/composer.lock index e9d07b43..c950c757 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,11 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], +<<<<<<< HEAD "content-hash": "d6bda397c505e1e6d540c814a2368fbb", +======= + "content-hash": "79f9618efcdf9891b62843fb5c3fb8de", +>>>>>>> dc5b8184 (Fixed mcp compatibility) "packages": [ { "name": "amphp/amp", @@ -1628,22 +1632,22 @@ }, { "name": "api-platform/mcp", - "version": "v4.3.4", + "version": "4.3.x-dev", "source": { "type": "git", "url": "https://github.com/api-platform/mcp.git", - "reference": "a984d05c20a02dfc0dd7691aaac8a9ba546f93ee" + "reference": "407c1039e8e022f7baed7d2cfbf63f5f09957f6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/mcp/zipball/a984d05c20a02dfc0dd7691aaac8a9ba546f93ee", - "reference": "a984d05c20a02dfc0dd7691aaac8a9ba546f93ee", + "url": "https://api.github.com/repos/api-platform/mcp/zipball/407c1039e8e022f7baed7d2cfbf63f5f09957f6b", + "reference": "407c1039e8e022f7baed7d2cfbf63f5f09957f6b", "shasum": "" }, "require": { "api-platform/json-schema": "^4.3", "api-platform/metadata": "^4.3", - "mcp/sdk": "^0.4.0", + "mcp/sdk": ">=0.4 <1.0", "php": ">=8.2", "symfony/object-mapper": "^7.4 || ^8.0", "symfony/polyfill-php85": "^1.32" @@ -1699,12 +1703,13 @@ ], "support": { "issues": "https://github.com/api-platform/mcp/issues", - "source": "https://github.com/api-platform/mcp/tree/v4.3.4" + "source": "https://github.com/api-platform/mcp/tree/4.3" }, - "time": "2026-04-30T12:21:24+00:00" + "time": "2026-05-06T12:07:59+00:00" }, { "name": "api-platform/metadata", +<<<<<<< HEAD "version": "v4.3.6", "source": { "type": "git", @@ -1715,6 +1720,18 @@ "type": "zip", "url": "https://api.github.com/repos/api-platform/metadata/zipball/e9e8a7b85d2d513edff3b108072f8ab23a9d6344", "reference": "e9e8a7b85d2d513edff3b108072f8ab23a9d6344", +======= + "version": "4.3.x-dev", + "source": { + "type": "git", + "url": "https://github.com/api-platform/metadata.git", + "reference": "52b367f046c5d202629e9441aece39b0e6b37838" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/api-platform/metadata/zipball/52b367f046c5d202629e9441aece39b0e6b37838", + "reference": "52b367f046c5d202629e9441aece39b0e6b37838", +>>>>>>> dc5b8184 (Fixed mcp compatibility) "shasum": "" }, "require": { @@ -1797,9 +1814,15 @@ "swagger" ], "support": { +<<<<<<< HEAD "source": "https://github.com/api-platform/metadata/tree/v4.3.6" }, "time": "2026-05-22T12:00:17+00:00" +======= + "source": "https://github.com/api-platform/metadata/tree/4.3" + }, + "time": "2026-05-06T12:07:59+00:00" +>>>>>>> dc5b8184 (Fixed mcp compatibility) }, { "name": "api-platform/openapi", @@ -7147,16 +7170,16 @@ }, { "name": "mcp/sdk", - "version": "v0.4.0", + "version": "v0.5.0", "source": { "type": "git", "url": "https://github.com/modelcontextprotocol/php-sdk.git", - "reference": "1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024" + "reference": "fb2c8c2ee4ab2791239c5f534bb07bfb7589d4e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/modelcontextprotocol/php-sdk/zipball/1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024", - "reference": "1f5f7e16a3af23dd43ec0a5c972d7aa8e8429024", + "url": "https://api.github.com/repos/modelcontextprotocol/php-sdk/zipball/fb2c8c2ee4ab2791239c5f534bb07bfb7589d4e8", + "reference": "fb2c8c2ee4ab2791239c5f534bb07bfb7589d4e8", "shasum": "" }, "require": { @@ -7164,19 +7187,22 @@ "opis/json-schema": "^2.4", "php": "^8.1", "php-http/discovery": "^1.20", - "phpdocumentor/reflection-docblock": "^5.6", + "phpdocumentor/reflection-docblock": "^5.6 || ^6.0", "psr/clock": "^1.0", "psr/container": "^1.0 || ^2.0", "psr/event-dispatcher": "^1.0", + "psr/http-client": "^1.0", "psr/http-factory": "^1.1", "psr/http-message": "^1.1 || ^2.0", "psr/http-server-handler": "^1.0", "psr/http-server-middleware": "^1.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "symfony/finder": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony/uid": "^5.4 || ^6.4 || ^7.3 || ^8.0" }, "require-dev": { + "composer/semver": "^3.0", + "ext-openssl": "*", + "firebase/php-jwt": "^6.10 || ^7.0", "laminas/laminas-httphandlerrunner": "^2.12", "nyholm/psr7": "^1.8", "nyholm/psr7-server": "^1.1", @@ -7188,8 +7214,13 @@ "psr/simple-cache": "^2.0 || ^3.0", "symfony/cache": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony/console": "^5.4 || ^6.4 || ^7.3 || ^8.0", + "symfony/finder": "^5.4 || ^6.4 || ^7.3 || ^8.0", + "symfony/http-client": "^5.4 || ^6.4 || ^7.3 || ^8.0", "symfony/process": "^5.4 || ^6.4 || ^7.3 || ^8.0" }, + "suggest": { + "symfony/finder": "Required for file-based discovery." + }, "type": "library", "autoload": { "psr-4": { @@ -7217,9 +7248,9 @@ "description": "Model Context Protocol SDK for Client and Server applications in PHP", "support": { "issues": "https://github.com/modelcontextprotocol/php-sdk/issues", - "source": "https://github.com/modelcontextprotocol/php-sdk/tree/v0.4.0" + "source": "https://github.com/modelcontextprotocol/php-sdk/tree/v0.5.0" }, - "time": "2026-02-23T21:42:54+00:00" + "time": "2026-04-26T13:37:40+00:00" }, { "name": "mf2/mf2", @@ -9174,16 +9205,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.6.7", + "version": "6.0.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "31a105931bc8ffa3a123383829772e832fd8d903" + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/31a105931bc8ffa3a123383829772e832fd8d903", - "reference": "31a105931bc8ffa3a123383829772e832fd8d903", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", "shasum": "" }, "require": { @@ -9191,8 +9222,8 @@ "ext-filter": "*", "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7|^2.0", + "phpdocumentor/type-resolver": "^2.0", + "phpstan/phpdoc-parser": "^2.0", "webmozart/assert": "^1.9.1 || ^2" }, "require-dev": { @@ -9202,7 +9233,8 @@ "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26" + "psalm/phar": "^5.26", + "shipmonk/dead-code-detector": "^0.5.1" }, "type": "library", "extra": { @@ -9232,44 +9264,44 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.7" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" }, - "time": "2026-03-18T20:47:46+00:00" + "time": "2026-03-18T20:49:53+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.12.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.18|^2.0" + "phpstan/phpdoc-parser": "^2.0" }, "require-dev": { "ext-tokenizer": "*", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" + "psalm/phar": "^4" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev" } }, "autoload": { @@ -9290,9 +9322,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" }, - "time": "2025-11-21T15:09:14+00:00" + "time": "2026-01-06T21:53:42+00:00" }, { "name": "phpoffice/phpspreadsheet", @@ -17930,6 +17962,7 @@ }, { "name": "symfony/yaml", +<<<<<<< HEAD "version": "v7.4.12", "source": { "type": "git", @@ -17940,6 +17973,18 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/yaml/zipball/8b6952b56ca6417f25f7a65758cadd0ce02edc51", "reference": "8b6952b56ca6417f25f7a65758cadd0ce02edc51", +======= + "version": "v7.4.10", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "c660d6538545a3e8e65a5621ee3d7a6d352892c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/c660d6538545a3e8e65a5621ee3d7a6d352892c7", + "reference": "c660d6538545a3e8e65a5621ee3d7a6d352892c7", +>>>>>>> dc5b8184 (Fixed mcp compatibility) "shasum": "" }, "require": { @@ -17982,7 +18027,11 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { +<<<<<<< HEAD "source": "https://github.com/symfony/yaml/tree/v7.4.12" +======= + "source": "https://github.com/symfony/yaml/tree/v7.4.10" +>>>>>>> dc5b8184 (Fixed mcp compatibility) }, "funding": [ { @@ -18002,7 +18051,11 @@ "type": "tidelift" } ], +<<<<<<< HEAD "time": "2026-05-20T07:20:23+00:00" +======= + "time": "2026-05-05T08:01:55+00:00" +>>>>>>> dc5b8184 (Fixed mcp compatibility) }, { "name": "symplify/easy-coding-standard", @@ -20811,12 +20864,21 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", +<<<<<<< HEAD "reference": "f9f1a88a11437cacd4d26b4953416af5c5425389" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/f9f1a88a11437cacd4d26b4953416af5c5425389", "reference": "f9f1a88a11437cacd4d26b4953416af5c5425389", +======= + "reference": "de95f6d567110e037eddcefa3d0d8f22d75d4053" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/de95f6d567110e037eddcefa3d0d8f22d75d4053", + "reference": "de95f6d567110e037eddcefa3d0d8f22d75d4053", +>>>>>>> dc5b8184 (Fixed mcp compatibility) "shasum": "" }, "conflict": { @@ -21139,7 +21201,11 @@ "georgringer/news": "<11.4.4|>=12,<12.3.2|>=13,<13.0.2|>=14,<14.0.3", "geshi/geshi": "<=1.0.9.1", "getformwork/formwork": "<=2.3.3", +<<<<<<< HEAD "getgrav/grav": "<=2.0.0.0-RC1", +======= + "getgrav/grav": "<2.0.0.0-beta4", +>>>>>>> dc5b8184 (Fixed mcp compatibility) "getgrav/grav-plugin-api": "<1.0.0.0-beta15", "getgrav/grav-plugin-form": "<9.1", "getkirby/cms": "<4.9|>=5,<5.4", @@ -21440,7 +21506,11 @@ "phpmailer/phpmailer": "<6.5", "phpmussel/phpmussel": ">=1,<1.6", "phpmyadmin/phpmyadmin": "<5.2.2", +<<<<<<< HEAD "phpmyfaq/phpmyfaq": "<4.1.3", +======= + "phpmyfaq/phpmyfaq": "<=4.1.1", +>>>>>>> dc5b8184 (Fixed mcp compatibility) "phpoffice/common": "<0.2.9", "phpoffice/math": "<=0.2", "phpoffice/phpexcel": "<=1.8.2", @@ -21600,7 +21670,11 @@ "starcitizentools/short-description": ">=4,<4.0.1", "starcitizentools/tabber-neue": ">=1.9.1,<2.7.2|>=3,<3.1.1", "starcitizenwiki/embedvideo": "<=4", +<<<<<<< HEAD "statamic/cms": "<5.73.22|>=6,<6.18.1", +======= + "statamic/cms": "<5.73.21|>=6,<6.15", +>>>>>>> dc5b8184 (Fixed mcp compatibility) "stormpath/sdk": "<9.9.99", "studio-42/elfinder": "<=2.1.67", "studiomitte/friendlycaptcha": "<0.1.4", @@ -21683,7 +21757,11 @@ "thelia/thelia": ">=2.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", "thinkcmf/thinkcmf": "<6.0.8", +<<<<<<< HEAD "thorsten/phpmyfaq": "<4.1.3", +======= + "thorsten/phpmyfaq": "<=4.1.1", +>>>>>>> dc5b8184 (Fixed mcp compatibility) "tikiwiki/tiki-manager": "<=17.1", "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", "tinymce/tinymce": "<7.2", @@ -21889,7 +21967,11 @@ "type": "tidelift" } ], +<<<<<<< HEAD "time": "2026-05-24T20:23:40+00:00" +======= + "time": "2026-05-06T21:27:25+00:00" +>>>>>>> dc5b8184 (Fixed mcp compatibility) }, { "name": "sebastian/cli-parser", @@ -23404,9 +23486,18 @@ "time": "2025-11-17T20:03:58+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "mcp/sdk", + "version": "0.5.0.0", + "alias": "0.4.0", + "alias_normalized": "0.4.0.0" + } + ], "minimum-stability": "stable", "stability-flags": { + "api-platform/mcp": 20, + "api-platform/metadata": 20, "roave/security-advisories": 20 }, "prefer-stable": false, From 75ef304fdb9086560387faf3e611199e30d68ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 May 2026 12:28:25 +0200 Subject: [PATCH 003/123] Added basic MCP tools to search for parts and get part details --- src/Entity/Parts/Part.php | 23 ++++++++ src/Mcp/DTO/ElementByIdInput.php | 35 +++++++++++ src/State/Mcp/GetPartByIdProcessor.php | 60 +++++++++++++++++++ src/State/Mcp/SearchPartsProcessor.php | 80 ++++++++++++++++++++++++++ 4 files changed, 198 insertions(+) create mode 100644 src/Mcp/DTO/ElementByIdInput.php create mode 100644 src/State/Mcp/GetPartByIdProcessor.php create mode 100644 src/State/Mcp/SearchPartsProcessor.php diff --git a/src/Entity/Parts/Part.php b/src/Entity/Parts/Part.php index 5ac81b60..97c051fb 100644 --- a/src/Entity/Parts/Part.php +++ b/src/Entity/Parts/Part.php @@ -32,6 +32,8 @@ use ApiPlatform\Metadata\ApiResource; use ApiPlatform\Metadata\Delete; use ApiPlatform\Metadata\Get; use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\McpTool; +use ApiPlatform\Metadata\McpToolCollection; use ApiPlatform\Metadata\Patch; use ApiPlatform\Metadata\Post; use ApiPlatform\Serializer\Filter\PropertyFilter; @@ -39,6 +41,7 @@ use App\ApiPlatform\Filter\EntityFilter; use App\ApiPlatform\Filter\LikeFilter; use App\ApiPlatform\Filter\PartStoragelocationFilter; use App\ApiPlatform\Filter\TagFilter; +use App\DataTables\Filters\PartSearchFilter; use App\Entity\Attachments\Attachment; use App\Entity\Attachments\AttachmentContainingDBElement; use App\Entity\Attachments\PartAttachment; @@ -55,7 +58,10 @@ use App\Entity\Parts\PartTraits\ManufacturerTrait; use App\Entity\Parts\PartTraits\OrderTrait; use App\Entity\Parts\PartTraits\ProjectTrait; use App\EntityListeners\TreeCacheInvalidationListener; +use App\Mcp\DTO\ElementByIdInput; use App\Repository\PartRepository; +use App\State\Mcp\GetPartByIdProcessor; +use App\State\Mcp\SearchPartsProcessor; use App\Validator\Constraints\UniqueObjectCollection; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -104,6 +110,23 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; ], normalizationContext: ['groups' => ['part:read', 'provider_reference:read', 'api:basic:read', 'part_lot:read'], 'openapi_definition_name' => 'Read'], denormalizationContext: ['groups' => ['part:write', 'api:basic:write', 'eda_info:write', 'attachment:write', 'parameter:write'], 'openapi_definition_name' => 'Write'], + mcp: [ + 'search_parts' => new McpToolCollection( + title: "Search parts by keyword", + description: 'Search for parts', + annotations: ['readOnlyHint' => true, 'destructiveHint' => false, 'idempotentHint' => true, 'openWorldHint' => false], + input: PartSearchFilter::class, + processor: SearchPartsProcessor::class, + ), + 'get_part_details' => new McpTool( + title: 'Get part details by ID', + description: 'Get detailed information about a specific part by its database ID', + annotations: ['readOnlyHint' => true, 'destructiveHint' => false, 'idempotentHint' => true, 'openWorldHint' => false], + normalizationContext: ['groups' => ['part:read', 'provider_reference:read', 'api:basic:read', 'part_lot:read', 'orderdetail:read', 'pricedetail:read', 'parameter:read', 'attachment:read', 'eda_info:read']], + input: ElementByIdInput::class, + processor: GetPartByIdProcessor::class + ), + ], )] #[ApiFilter(PropertyFilter::class)] #[ApiFilter(EntityFilter::class, properties: ["category", "footprint", "manufacturer", "partUnit", "partCustomState"])] diff --git a/src/Mcp/DTO/ElementByIdInput.php b/src/Mcp/DTO/ElementByIdInput.php new file mode 100644 index 00000000..bade3af2 --- /dev/null +++ b/src/Mcp/DTO/ElementByIdInput.php @@ -0,0 +1,35 @@ +. + */ + +declare(strict_types=1); + +namespace App\Mcp\DTO; + +use Symfony\Component\Validator\Constraints as Assert; + +readonly class ElementByIdInput +{ + public function __construct( + #[Assert\NotNull] + #[Assert\Positive] + public int $id, + ) { + } +} diff --git a/src/State/Mcp/GetPartByIdProcessor.php b/src/State/Mcp/GetPartByIdProcessor.php new file mode 100644 index 00000000..b147ef68 --- /dev/null +++ b/src/State/Mcp/GetPartByIdProcessor.php @@ -0,0 +1,60 @@ +. + */ + +declare(strict_types=1); + +namespace App\State\Mcp; + +use ApiPlatform\Metadata\Operation; +use ApiPlatform\State\ProcessorInterface; +use App\Entity\Parts\Part; +use App\Mcp\DTO\ElementByIdInput; +use Doctrine\ORM\EntityManagerInterface; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Symfony\Component\Security\Core\Exception\AccessDeniedException; + +class GetPartByIdProcessor implements ProcessorInterface +{ + public function __construct( + private readonly EntityManagerInterface $entityManager, + private readonly AuthorizationCheckerInterface $authorizationChecker, + ) { + } + + public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []) + { + if (!$data instanceof ElementByIdInput) { + throw new \InvalidArgumentException('Expected PartByIdInput'); + } + + $part = $this->entityManager->find(Part::class, $data->id); + + if (!$part instanceof Part) { + throw new NotFoundHttpException(sprintf('Part with id %d not found', $data->id)); + } + + if (!$this->authorizationChecker->isGranted('read', $part)) { + throw new AccessDeniedException(sprintf('Access denied to part with id %d', $data->id)); + } + + return $part; + } +} diff --git a/src/State/Mcp/SearchPartsProcessor.php b/src/State/Mcp/SearchPartsProcessor.php new file mode 100644 index 00000000..8d922394 --- /dev/null +++ b/src/State/Mcp/SearchPartsProcessor.php @@ -0,0 +1,80 @@ +. + */ + +declare(strict_types=1); + + +namespace App\State\Mcp; + +use ApiPlatform\Metadata\Operation; +use ApiPlatform\State\ProcessorInterface; +use App\DataTables\Filters\PartSearchFilter; +use App\Entity\Parts\Part; +use Doctrine\ORM\EntityManagerInterface; +use Doctrine\ORM\QueryBuilder; + +class SearchPartsProcessor implements ProcessorInterface +{ + + public function __construct( + private readonly EntityManagerInterface $entityManager, + ) { + + } + + public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []) + { + if (!$data instanceof PartSearchFilter) { + return []; + } + + $qb = $this->entityManager->getRepository(Part::class)->createQueryBuilder('part'); + + $data->apply($qb); + $this->addJoins($qb); + + $qb->addGroupBy('part'); + + return $qb->getQuery()->getResult(); + } + + private function addJoins(QueryBuilder $qb): void + { + $dql = $qb->getDQL(); + + if (str_contains($dql, '_category')) { + $qb->leftJoin('part.category', '_category'); + } + if (str_contains($dql, '_storelocations')) { + $qb->leftJoin('part.partLots', '_partLots'); + $qb->leftJoin('_partLots.storage_location', '_storelocations'); + } + if (str_contains($dql, '_orderdetails') || str_contains($dql, '_suppliers')) { + $qb->leftJoin('part.orderdetails', '_orderdetails'); + $qb->leftJoin('_orderdetails.supplier', '_suppliers'); + } + if (str_contains($dql, '_manufacturer')) { + $qb->leftJoin('part.manufacturer', '_manufacturer'); + } + if (str_contains($dql, '_footprint')) { + $qb->leftJoin('part.footprint', '_footprint'); + } + } +} From fc8769e220e6d8a7a4ee9f4c78a4c896935615fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 May 2026 13:44:49 +0200 Subject: [PATCH 004/123] updated dependencies --- composer.lock | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/composer.lock b/composer.lock index c950c757..eff8a735 100644 --- a/composer.lock +++ b/composer.lock @@ -4085,6 +4085,7 @@ }, { "name": "doctrine/orm", +<<<<<<< HEAD "version": "3.6.7", "source": { "type": "git", @@ -4095,6 +4096,18 @@ "type": "zip", "url": "https://api.github.com/repos/doctrine/orm/zipball/bc217c0e19c3a9eadfa67697143b87c9ba01272c", "reference": "bc217c0e19c3a9eadfa67697143b87c9ba01272c", +======= + "version": "3.6.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/orm.git", + "reference": "156f3b5a984e7eaa72d440bb6de1d3b6f8d2d6fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/orm/zipball/156f3b5a984e7eaa72d440bb6de1d3b6f8d2d6fd", + "reference": "156f3b5a984e7eaa72d440bb6de1d3b6f8d2d6fd", +>>>>>>> 3f10a123 (updated dependencies) "shasum": "" }, "require": { @@ -4167,9 +4180,15 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", +<<<<<<< HEAD "source": "https://github.com/doctrine/orm/tree/3.6.7" }, "time": "2026-05-25T16:45:47+00:00" +======= + "source": "https://github.com/doctrine/orm/tree/3.6.4" + }, + "time": "2026-05-07T07:04:34+00:00" +>>>>>>> 3f10a123 (updated dependencies) }, { "name": "doctrine/persistence", @@ -20269,6 +20288,7 @@ }, { "name": "phpstan/phpstan-symfony", +<<<<<<< HEAD "version": "2.0.18", "source": { "type": "git", @@ -20279,6 +20299,18 @@ "type": "zip", "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/a12176b639dec54e8bfd0a5ebf5fc36ffe003b5d", "reference": "a12176b639dec54e8bfd0a5ebf5fc36ffe003b5d", +======= + "version": "2.0.17", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-symfony.git", + "reference": "fdd0cb5f08d1980c612d6f259d825ea644ed03f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/fdd0cb5f08d1980c612d6f259d825ea644ed03f4", + "reference": "fdd0cb5f08d1980c612d6f259d825ea644ed03f4", +>>>>>>> 3f10a123 (updated dependencies) "shasum": "" }, "require": { @@ -20337,9 +20369,15 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan-symfony/issues", +<<<<<<< HEAD "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.18" }, "time": "2026-05-18T14:51:49+00:00" +======= + "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.17" + }, + "time": "2026-05-10T08:14:07+00:00" +>>>>>>> 3f10a123 (updated dependencies) }, { "name": "phpunit/php-code-coverage", @@ -20864,6 +20902,7 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", +<<<<<<< HEAD <<<<<<< HEAD "reference": "f9f1a88a11437cacd4d26b4953416af5c5425389" }, @@ -20879,6 +20918,14 @@ "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/de95f6d567110e037eddcefa3d0d8f22d75d4053", "reference": "de95f6d567110e037eddcefa3d0d8f22d75d4053", >>>>>>> dc5b8184 (Fixed mcp compatibility) +======= + "reference": "5a7fa9fd3ce6eefbc9b982d6c78d0aa15d328d6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/5a7fa9fd3ce6eefbc9b982d6c78d0aa15d328d6c", + "reference": "5a7fa9fd3ce6eefbc9b982d6c78d0aa15d328d6c", +>>>>>>> 3f10a123 (updated dependencies) "shasum": "" }, "conflict": { @@ -21402,7 +21449,10 @@ "miraheze/ts-portal": "<=33", "mittwald/typo3_forum": "<1.2.1", "mix/mix": ">=2,<=2.2.17", +<<<<<<< HEAD "mmc/ceselector": "<3.0.3|>=4,<4.0.2|>=5,<5.0.1|>=6,<6.0.1", +======= +>>>>>>> 3f10a123 (updated dependencies) "mobiledetect/mobiledetectlib": "<2.8.32", "modx/revolution": "<=3.1", "mojo42/jirafeau": "<4.4", @@ -21967,11 +22017,15 @@ "type": "tidelift" } ], +<<<<<<< HEAD <<<<<<< HEAD "time": "2026-05-24T20:23:40+00:00" ======= "time": "2026-05-06T21:27:25+00:00" >>>>>>> dc5b8184 (Fixed mcp compatibility) +======= + "time": "2026-05-08T23:22:52+00:00" +>>>>>>> 3f10a123 (updated dependencies) }, { "name": "sebastian/cli-parser", From c4f0583e54f74e72408f5838c5b550cd5142fee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 10 May 2026 16:21:34 +0200 Subject: [PATCH 005/123] Fixed get part details tool --- src/Entity/Parts/Part.php | 8 +- src/Mcp/JsonSchema/FixedSchemaFactory.php | 162 ++++++++++++++++++++++ 2 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 src/Mcp/JsonSchema/FixedSchemaFactory.php diff --git a/src/Entity/Parts/Part.php b/src/Entity/Parts/Part.php index 97c051fb..bbc0f8d1 100644 --- a/src/Entity/Parts/Part.php +++ b/src/Entity/Parts/Part.php @@ -86,7 +86,7 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; #[ORM\Index(columns: ['datetime_added', 'name', 'last_modified', 'id', 'needs_review'], name: 'parts_idx_datet_name_last_id_needs')] #[ORM\Index(columns: ['name'], name: 'parts_idx_name')] #[ORM\Index(columns: ['ipn'], name: 'parts_idx_ipn')] -#[ORM\Index(columns: ['gtin'], name: 'parts_idx_gtin')] +#[ORM\Index(name: 'parts_idx_gtin', columns: ['gtin'])] #[ApiResource( operations: [ new Get(normalizationContext: [ @@ -122,8 +122,12 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; title: 'Get part details by ID', description: 'Get detailed information about a specific part by its database ID', annotations: ['readOnlyHint' => true, 'destructiveHint' => false, 'idempotentHint' => true, 'openWorldHint' => false], - normalizationContext: ['groups' => ['part:read', 'provider_reference:read', 'api:basic:read', 'part_lot:read', 'orderdetail:read', 'pricedetail:read', 'parameter:read', 'attachment:read', 'eda_info:read']], + normalizationContext: [ + 'groups' => ['part:read', 'provider_reference:read', 'api:basic:read', 'part_lot:read', 'orderdetail:read', 'pricedetail:read', 'parameter:read', 'attachment:read', 'eda_info:read'], + 'item_uri_template' => '/api/parts/{id}', + ], input: ElementByIdInput::class, + validate: true, processor: GetPartByIdProcessor::class ), ], diff --git a/src/Mcp/JsonSchema/FixedSchemaFactory.php b/src/Mcp/JsonSchema/FixedSchemaFactory.php new file mode 100644 index 00000000..c851c394 --- /dev/null +++ b/src/Mcp/JsonSchema/FixedSchemaFactory.php @@ -0,0 +1,162 @@ +. + */ + +declare(strict_types=1); + +namespace App\Mcp\JsonSchema; + +use ApiPlatform\JsonSchema\Schema; +use ApiPlatform\JsonSchema\SchemaFactoryInterface; +use ApiPlatform\Metadata\Operation; +use Symfony\Component\DependencyInjection\Attribute\AsAlias; +use Symfony\Component\DependencyInjection\Attribute\AsDecorator; +use Symfony\Component\DependencyInjection\Attribute\AutowireDecorated; + +/** + * Overwrite the default JSON Schema factory to resolve $ref and allOf into a flat schema. + * This is a workaround until https://github.com/api-platform/core/pull/7962 is merged + */ +#[AsAlias('api_platform.mcp.json_schema.schema_factory')] +readonly class FixedSchemaFactory implements SchemaFactoryInterface +{ + public function __construct( + private readonly SchemaFactoryInterface $decorated, + ) { + } + + public function buildSchema(string $className, string $format = 'json', string $type = Schema::TYPE_OUTPUT, ?Operation $operation = null, ?Schema $schema = null, ?array $serializerContext = null, bool $forceCollection = false): Schema + { + $schema = $this->decorated->buildSchema($className, $format, $type, $operation, $schema, $serializerContext, $forceCollection); + + $definitions = []; + foreach ($schema->getDefinitions() as $key => $definition) { + $definitions[$key] = $definition instanceof \ArrayObject ? $definition->getArrayCopy() : (array) $definition; + } + + $rootKey = $schema->getRootDefinitionKey(); + if (null !== $rootKey) { + $root = $definitions[$rootKey] ?? []; + } else { + // Collection schemas (and others) put allOf/type directly on the root + $root = $schema->getArrayCopy(false); + } + + $flat = self::resolveNode($root, $definitions); + + $flatSchema = new Schema(Schema::VERSION_JSON_SCHEMA); + unset($flatSchema['$schema']); + foreach ($flat as $key => $value) { + $flatSchema[$key] = $value; + } + + return $flatSchema; + } + + /** + * Recursively resolve $ref, allOf, and nested structures into a flat schema node. + * + * @param array $resolving Tracks the current $ref resolution chain to detect circular references + */ + public static function resolveNode(array|\ArrayObject $node, array $definitions, array &$resolving = []): array + { + if ($node instanceof \ArrayObject) { + $node = $node->getArrayCopy(); + } + + if (isset($node['$ref'])) { + $refKey = str_replace('#/definitions/', '', $node['$ref']); + if (!isset($definitions[$refKey]) || isset($resolving[$refKey])) { + return ['type' => 'object']; + } + $resolving[$refKey] = true; + $resolved = self::resolveNode($definitions[$refKey], $definitions, $resolving); + unset($resolving[$refKey]); + + return $resolved; + } + + if (isset($node['allOf'])) { + $merged = ['type' => 'object', 'properties' => []]; + $requiredSets = []; + foreach ($node['allOf'] as $entry) { + $resolved = self::resolveNode($entry, $definitions, $resolving); + if (isset($resolved['properties'])) { + foreach ($resolved['properties'] as $k => $v) { + $merged['properties'][$k] = $v; + } + } + if (isset($resolved['required'])) { + $requiredSets[] = $resolved['required']; + } + } + + if ($requiredSets) { + $merged['required'] = array_merge(...$requiredSets); + } + if ([] === $merged['properties']) { + unset($merged['properties']); + } + if (isset($node['description'])) { + $merged['description'] = $node['description']; + } + + return self::resolveDeep($merged, $definitions, $resolving); + } + + // oneOf/anyOf nodes must not receive a type fallback — their type is expressed + // through the sub-schemas. Adding 'type: object' here would break schemas like + // HydraItemBaseSchema's @context, which is oneOf: [string, object]. + if (isset($node['oneOf']) || isset($node['anyOf'])) { + return self::resolveDeep($node, $definitions, $resolving); + } + + if (!isset($node['type'])) { + $node['type'] = 'object'; + } + + return self::resolveDeep($node, $definitions, $resolving); + } + + /** + * Recursively resolve nested properties and array items. + */ + private static function resolveDeep(array $node, array $definitions, array &$resolving): array + { + if (isset($node['items'])) { + $node['items'] = self::resolveNode( + $node['items'] instanceof \ArrayObject ? $node['items']->getArrayCopy() : $node['items'], + $definitions, + $resolving, + ); + } + + if (isset($node['properties']) && \is_array($node['properties'])) { + foreach ($node['properties'] as $propName => $propSchema) { + $node['properties'][$propName] = self::resolveNode( + $propSchema instanceof \ArrayObject ? $propSchema->getArrayCopy() : $propSchema, + $definitions, + $resolving, + ); + } + } + + return $node; + } +} From a9d75554d7112291627f696926346e6e7ac7e543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Tue, 26 May 2026 22:00:26 +0200 Subject: [PATCH 006/123] Updated dependencies --- composer.json | 6 +- composer.lock | 275 +++++++++++++------------------------------------- 2 files changed, 74 insertions(+), 207 deletions(-) diff --git a/composer.json b/composer.json index 6fc60d18..3fcaa5e3 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "amphp/http-client": "^5.1", "api-platform/doctrine-orm": "^4.1", "api-platform/json-api": "^4.0.0", - "api-platform/mcp": "4.3.x-dev", + "api-platform/mcp": "^v4.3.6", "api-platform/symfony": "^4.0.0", "api-platform/metadata": "4.3.x-dev", "beberlei/doctrineextensions": "^1.2", @@ -42,7 +42,7 @@ "league/html-to-markdown": "^5.0.1", "liip/imagine-bundle": "^2.2", "maennchen/zipstream-php": "2.1", - "mcp/sdk": "v0.5.0 as 0.4.0", + "mcp/sdk": "v0.5.0", "nbgrp/onelogin-saml-bundle": "^v2.0.2", "nelexa/zip": "^4.0", "nelmio/cors-bundle": "^2.3", @@ -76,7 +76,7 @@ "symfony/http-client": "7.4.*", "symfony/http-kernel": "7.4.*", "symfony/mailer": "7.4.*", - "symfony/mcp-bundle": "^0.8.0", + "symfony/mcp-bundle": "^v0.9.0.0", "symfony/monolog-bundle": "^4.0", "symfony/process": "7.4.*", "symfony/property-access": "7.4.*", diff --git a/composer.lock b/composer.lock index eff8a735..c409386c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,11 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], -<<<<<<< HEAD - "content-hash": "d6bda397c505e1e6d540c814a2368fbb", -======= - "content-hash": "79f9618efcdf9891b62843fb5c3fb8de", ->>>>>>> dc5b8184 (Fixed mcp compatibility) + "content-hash": "9171608b0a2f6caa65f4eca3b66ae351", "packages": [ { "name": "amphp/amp", @@ -1632,16 +1628,16 @@ }, { "name": "api-platform/mcp", - "version": "4.3.x-dev", + "version": "v4.3.6", "source": { "type": "git", "url": "https://github.com/api-platform/mcp.git", - "reference": "407c1039e8e022f7baed7d2cfbf63f5f09957f6b" + "reference": "35177126b8beb69169e7a33a325e00dbbdbbd7bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/mcp/zipball/407c1039e8e022f7baed7d2cfbf63f5f09957f6b", - "reference": "407c1039e8e022f7baed7d2cfbf63f5f09957f6b", + "url": "https://api.github.com/repos/api-platform/mcp/zipball/35177126b8beb69169e7a33a325e00dbbdbbd7bf", + "reference": "35177126b8beb69169e7a33a325e00dbbdbbd7bf", "shasum": "" }, "require": { @@ -1703,14 +1699,13 @@ ], "support": { "issues": "https://github.com/api-platform/mcp/issues", - "source": "https://github.com/api-platform/mcp/tree/4.3" + "source": "https://github.com/api-platform/mcp/tree/v4.3.6" }, - "time": "2026-05-06T12:07:59+00:00" + "time": "2026-05-11T06:02:06+00:00" }, { "name": "api-platform/metadata", -<<<<<<< HEAD - "version": "v4.3.6", + "version": "4.3.x-dev", "source": { "type": "git", "url": "https://github.com/api-platform/metadata.git", @@ -1720,18 +1715,6 @@ "type": "zip", "url": "https://api.github.com/repos/api-platform/metadata/zipball/e9e8a7b85d2d513edff3b108072f8ab23a9d6344", "reference": "e9e8a7b85d2d513edff3b108072f8ab23a9d6344", -======= - "version": "4.3.x-dev", - "source": { - "type": "git", - "url": "https://github.com/api-platform/metadata.git", - "reference": "52b367f046c5d202629e9441aece39b0e6b37838" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/api-platform/metadata/zipball/52b367f046c5d202629e9441aece39b0e6b37838", - "reference": "52b367f046c5d202629e9441aece39b0e6b37838", ->>>>>>> dc5b8184 (Fixed mcp compatibility) "shasum": "" }, "require": { @@ -1814,15 +1797,9 @@ "swagger" ], "support": { -<<<<<<< HEAD - "source": "https://github.com/api-platform/metadata/tree/v4.3.6" - }, - "time": "2026-05-22T12:00:17+00:00" -======= "source": "https://github.com/api-platform/metadata/tree/4.3" }, - "time": "2026-05-06T12:07:59+00:00" ->>>>>>> dc5b8184 (Fixed mcp compatibility) + "time": "2026-05-22T12:00:17+00:00" }, { "name": "api-platform/openapi", @@ -2442,16 +2419,16 @@ }, { "name": "brick/math", - "version": "0.17.1", + "version": "0.17.2", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "6aef71a9fbbd1ee7be0e313cd627f8e6f7125a5b" + "reference": "8189e751995f9e15729c1aa2f89fa8f166ffe818" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/6aef71a9fbbd1ee7be0e313cd627f8e6f7125a5b", - "reference": "6aef71a9fbbd1ee7be0e313cd627f8e6f7125a5b", + "url": "https://api.github.com/repos/brick/math/zipball/8189e751995f9e15729c1aa2f89fa8f166ffe818", + "reference": "8189e751995f9e15729c1aa2f89fa8f166ffe818", "shasum": "" }, "require": { @@ -2489,7 +2466,7 @@ ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.17.1" + "source": "https://github.com/brick/math/tree/0.17.2" }, "funding": [ { @@ -2497,7 +2474,7 @@ "type": "github" } ], - "time": "2026-04-19T20:55:20+00:00" + "time": "2026-05-25T20:34:43+00:00" }, { "name": "brick/schema", @@ -4085,7 +4062,6 @@ }, { "name": "doctrine/orm", -<<<<<<< HEAD "version": "3.6.7", "source": { "type": "git", @@ -4096,18 +4072,6 @@ "type": "zip", "url": "https://api.github.com/repos/doctrine/orm/zipball/bc217c0e19c3a9eadfa67697143b87c9ba01272c", "reference": "bc217c0e19c3a9eadfa67697143b87c9ba01272c", -======= - "version": "3.6.4", - "source": { - "type": "git", - "url": "https://github.com/doctrine/orm.git", - "reference": "156f3b5a984e7eaa72d440bb6de1d3b6f8d2d6fd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/156f3b5a984e7eaa72d440bb6de1d3b6f8d2d6fd", - "reference": "156f3b5a984e7eaa72d440bb6de1d3b6f8d2d6fd", ->>>>>>> 3f10a123 (updated dependencies) "shasum": "" }, "require": { @@ -4180,15 +4144,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", -<<<<<<< HEAD "source": "https://github.com/doctrine/orm/tree/3.6.7" }, "time": "2026-05-25T16:45:47+00:00" -======= - "source": "https://github.com/doctrine/orm/tree/3.6.4" - }, - "time": "2026-05-07T07:04:34+00:00" ->>>>>>> 3f10a123 (updated dependencies) }, { "name": "doctrine/persistence", @@ -4965,16 +4923,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.10.1", + "version": "2.10.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "73ab136360b5dfd858006eae9795e8fe43c80361" + "reference": "a1bbdc172f32a25fe999965b65b6e71fd87da9ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/73ab136360b5dfd858006eae9795e8fe43c80361", - "reference": "73ab136360b5dfd858006eae9795e8fe43c80361", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/a1bbdc172f32a25fe999965b65b6e71fd87da9ed", + "reference": "a1bbdc172f32a25fe999965b65b6e71fd87da9ed", "shasum": "" }, "require": { @@ -5062,7 +5020,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.10.1" + "source": "https://github.com/guzzle/psr7/tree/2.10.2" }, "funding": [ { @@ -5078,7 +5036,7 @@ "type": "tidelift" } ], - "time": "2026-05-20T09:27:36+00:00" + "time": "2026-05-25T22:58:15+00:00" }, { "name": "hshn/base64-encoded-file", @@ -14154,24 +14112,25 @@ }, { "name": "symfony/mcp-bundle", - "version": "v0.8.0", + "version": "v0.9.0", "source": { "type": "git", "url": "https://github.com/symfony/mcp-bundle.git", - "reference": "b8db100e64fcb2d651e3bfd6c6ab70ad3599833d" + "reference": "654f639e94f4d7694771e6628380a9ff04c9d9c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mcp-bundle/zipball/b8db100e64fcb2d651e3bfd6c6ab70ad3599833d", - "reference": "b8db100e64fcb2d651e3bfd6c6ab70ad3599833d", + "url": "https://api.github.com/repos/symfony/mcp-bundle/zipball/654f639e94f4d7694771e6628380a9ff04c9d9c1", + "reference": "654f639e94f4d7694771e6628380a9ff04c9d9c1", "shasum": "" }, "require": { - "mcp/sdk": "^0.4", + "mcp/sdk": "^0.5", "php-http/discovery": "^1.20", "symfony/config": "^7.3|^8.0", "symfony/console": "^7.3|^8.0", "symfony/dependency-injection": "^7.3|^8.0", + "symfony/finder": "^7.3|^8.0", "symfony/framework-bundle": "^7.3|^8.0", "symfony/http-foundation": "^7.3|^8.0", "symfony/http-kernel": "^7.3|^8.0", @@ -14214,7 +14173,7 @@ ], "description": "Symfony integration bundle for Model Context Protocol (via official mcp/sdk)", "support": { - "source": "https://github.com/symfony/mcp-bundle/tree/v0.8.0" + "source": "https://github.com/symfony/mcp-bundle/tree/v0.9.0" }, "funding": [ { @@ -14234,7 +14193,7 @@ "type": "tidelift" } ], - "time": "2026-04-12T00:28:34+00:00" + "time": "2026-05-15T23:41:17+00:00" }, { "name": "symfony/mime", @@ -14792,16 +14751,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.38.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "9c862df890f7c833b1101ac5578ec4dcf199efb5" + "reference": "e9247d281d694a5120554d9afaf54e070e88a603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/9c862df890f7c833b1101ac5578ec4dcf199efb5", - "reference": "9c862df890f7c833b1101ac5578ec4dcf199efb5", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e9247d281d694a5120554d9afaf54e070e88a603", + "reference": "e9247d281d694a5120554d9afaf54e070e88a603", "shasum": "" }, "require": { @@ -14850,7 +14809,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.1" }, "funding": [ { @@ -14870,7 +14829,7 @@ "type": "tidelift" } ], - "time": "2026-05-25T12:39:52+00:00" + "time": "2026-05-26T05:58:03+00:00" }, { "name": "symfony/polyfill-intl-icu", @@ -14962,16 +14921,16 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.37.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + "reference": "dc21118016c039a66235cf93d96b435ffb282412" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", - "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/dc21118016c039a66235cf93d96b435ffb282412", + "reference": "dc21118016c039a66235cf93d96b435ffb282412", "shasum": "" }, "require": { @@ -15025,7 +14984,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.38.1" }, "funding": [ { @@ -15045,7 +15004,7 @@ "type": "tidelift" } ], - "time": "2024-09-10T14:38:51+00:00" + "time": "2026-05-25T15:22:23+00:00" }, { "name": "symfony/polyfill-intl-normalizer", @@ -15134,16 +15093,16 @@ }, { "name": "symfony/polyfill-php83", - "version": "v1.38.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "c4406e07046227db8844a25f89d111da078aaa9c" + "reference": "8339098cae28673c15cce00d80734af0453054e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/c4406e07046227db8844a25f89d111da078aaa9c", - "reference": "c4406e07046227db8844a25f89d111da078aaa9c", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/8339098cae28673c15cce00d80734af0453054e2", + "reference": "8339098cae28673c15cce00d80734af0453054e2", "shasum": "" }, "require": { @@ -15190,7 +15149,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.1" }, "funding": [ { @@ -15210,20 +15169,20 @@ "type": "tidelift" } ], - "time": "2026-05-25T12:39:52+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { "name": "symfony/polyfill-php84", - "version": "v1.38.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "a0e0aca0368801ec79f8791dea9a7c12af527c93" + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/a0e0aca0368801ec79f8791dea9a7c12af527c93", - "reference": "a0e0aca0368801ec79f8791dea9a7c12af527c93", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", "shasum": "" }, "require": { @@ -15270,7 +15229,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1" }, "funding": [ { @@ -15290,20 +15249,20 @@ "type": "tidelift" } ], - "time": "2026-05-25T12:12:52+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { "name": "symfony/polyfill-php85", - "version": "v1.38.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "3e851ffb42624b64b3b9ec234a0e2074b0f880e3" + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/3e851ffb42624b64b3b9ec234a0e2074b0f880e3", - "reference": "3e851ffb42624b64b3b9ec234a0e2074b0f880e3", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", "shasum": "" }, "require": { @@ -15350,7 +15309,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.0" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1" }, "funding": [ { @@ -15370,7 +15329,7 @@ "type": "tidelift" } ], - "time": "2026-05-25T11:50:50+00:00" + "time": "2026-05-26T02:25:22+00:00" }, { "name": "symfony/polyfill-uuid", @@ -17981,7 +17940,6 @@ }, { "name": "symfony/yaml", -<<<<<<< HEAD "version": "v7.4.12", "source": { "type": "git", @@ -17992,18 +17950,6 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/yaml/zipball/8b6952b56ca6417f25f7a65758cadd0ce02edc51", "reference": "8b6952b56ca6417f25f7a65758cadd0ce02edc51", -======= - "version": "v7.4.10", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "c660d6538545a3e8e65a5621ee3d7a6d352892c7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/c660d6538545a3e8e65a5621ee3d7a6d352892c7", - "reference": "c660d6538545a3e8e65a5621ee3d7a6d352892c7", ->>>>>>> dc5b8184 (Fixed mcp compatibility) "shasum": "" }, "require": { @@ -18046,11 +17992,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { -<<<<<<< HEAD "source": "https://github.com/symfony/yaml/tree/v7.4.12" -======= - "source": "https://github.com/symfony/yaml/tree/v7.4.10" ->>>>>>> dc5b8184 (Fixed mcp compatibility) }, "funding": [ { @@ -18070,11 +18012,7 @@ "type": "tidelift" } ], -<<<<<<< HEAD "time": "2026-05-20T07:20:23+00:00" -======= - "time": "2026-05-05T08:01:55+00:00" ->>>>>>> dc5b8184 (Fixed mcp compatibility) }, { "name": "symplify/easy-coding-standard", @@ -20107,11 +20045,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.55", + "version": "2.1.56", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9eaac3826ed5e9b8427350a43cac825eeca3f566", - "reference": "9eaac3826ed5e9b8427350a43cac825eeca3f566", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/93a603c9fc3be8c3c93bbc8d22170ad766685537", + "reference": "93a603c9fc3be8c3c93bbc8d22170ad766685537", "shasum": "" }, "require": { @@ -20156,7 +20094,7 @@ "type": "github" } ], - "time": "2026-05-18T11:57:34+00:00" + "time": "2026-05-26T17:04:57+00:00" }, { "name": "phpstan/phpstan-doctrine", @@ -20288,7 +20226,6 @@ }, { "name": "phpstan/phpstan-symfony", -<<<<<<< HEAD "version": "2.0.18", "source": { "type": "git", @@ -20299,18 +20236,6 @@ "type": "zip", "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/a12176b639dec54e8bfd0a5ebf5fc36ffe003b5d", "reference": "a12176b639dec54e8bfd0a5ebf5fc36ffe003b5d", -======= - "version": "2.0.17", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan-symfony.git", - "reference": "fdd0cb5f08d1980c612d6f259d825ea644ed03f4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/fdd0cb5f08d1980c612d6f259d825ea644ed03f4", - "reference": "fdd0cb5f08d1980c612d6f259d825ea644ed03f4", ->>>>>>> 3f10a123 (updated dependencies) "shasum": "" }, "require": { @@ -20369,15 +20294,9 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan-symfony/issues", -<<<<<<< HEAD "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.18" }, "time": "2026-05-18T14:51:49+00:00" -======= - "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.17" - }, - "time": "2026-05-10T08:14:07+00:00" ->>>>>>> 3f10a123 (updated dependencies) }, { "name": "phpunit/php-code-coverage", @@ -20902,30 +20821,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", -<<<<<<< HEAD -<<<<<<< HEAD - "reference": "f9f1a88a11437cacd4d26b4953416af5c5425389" + "reference": "11be66e3adc8bf2c9805209a598ad4b42ee3c0d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/f9f1a88a11437cacd4d26b4953416af5c5425389", - "reference": "f9f1a88a11437cacd4d26b4953416af5c5425389", -======= - "reference": "de95f6d567110e037eddcefa3d0d8f22d75d4053" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/de95f6d567110e037eddcefa3d0d8f22d75d4053", - "reference": "de95f6d567110e037eddcefa3d0d8f22d75d4053", ->>>>>>> dc5b8184 (Fixed mcp compatibility) -======= - "reference": "5a7fa9fd3ce6eefbc9b982d6c78d0aa15d328d6c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/5a7fa9fd3ce6eefbc9b982d6c78d0aa15d328d6c", - "reference": "5a7fa9fd3ce6eefbc9b982d6c78d0aa15d328d6c", ->>>>>>> 3f10a123 (updated dependencies) + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/11be66e3adc8bf2c9805209a598ad4b42ee3c0d6", + "reference": "11be66e3adc8bf2c9805209a598ad4b42ee3c0d6", "shasum": "" }, "conflict": { @@ -21248,11 +21149,7 @@ "georgringer/news": "<11.4.4|>=12,<12.3.2|>=13,<13.0.2|>=14,<14.0.3", "geshi/geshi": "<=1.0.9.1", "getformwork/formwork": "<=2.3.3", -<<<<<<< HEAD "getgrav/grav": "<=2.0.0.0-RC1", -======= - "getgrav/grav": "<2.0.0.0-beta4", ->>>>>>> dc5b8184 (Fixed mcp compatibility) "getgrav/grav-plugin-api": "<1.0.0.0-beta15", "getgrav/grav-plugin-form": "<9.1", "getkirby/cms": "<4.9|>=5,<5.4", @@ -21449,10 +21346,7 @@ "miraheze/ts-portal": "<=33", "mittwald/typo3_forum": "<1.2.1", "mix/mix": ">=2,<=2.2.17", -<<<<<<< HEAD "mmc/ceselector": "<3.0.3|>=4,<4.0.2|>=5,<5.0.1|>=6,<6.0.1", -======= ->>>>>>> 3f10a123 (updated dependencies) "mobiledetect/mobiledetectlib": "<2.8.32", "modx/revolution": "<=3.1", "mojo42/jirafeau": "<4.4", @@ -21556,11 +21450,7 @@ "phpmailer/phpmailer": "<6.5", "phpmussel/phpmussel": ">=1,<1.6", "phpmyadmin/phpmyadmin": "<5.2.2", -<<<<<<< HEAD "phpmyfaq/phpmyfaq": "<4.1.3", -======= - "phpmyfaq/phpmyfaq": "<=4.1.1", ->>>>>>> dc5b8184 (Fixed mcp compatibility) "phpoffice/common": "<0.2.9", "phpoffice/math": "<=0.2", "phpoffice/phpexcel": "<=1.8.2", @@ -21608,7 +21498,7 @@ "propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7", "propel/propel1": ">=1,<=1.7.1", "psy/psysh": "<=0.11.22|>=0.12,<=0.12.18", - "pterodactyl/panel": "<1.12.1", + "pterodactyl/panel": "<1.12.3", "ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2", "ptrofimov/beanstalk_console": "<1.7.14", "pubnub/pubnub": "<6.1", @@ -21720,11 +21610,7 @@ "starcitizentools/short-description": ">=4,<4.0.1", "starcitizentools/tabber-neue": ">=1.9.1,<2.7.2|>=3,<3.1.1", "starcitizenwiki/embedvideo": "<=4", -<<<<<<< HEAD "statamic/cms": "<5.73.22|>=6,<6.18.1", -======= - "statamic/cms": "<5.73.21|>=6,<6.15", ->>>>>>> dc5b8184 (Fixed mcp compatibility) "stormpath/sdk": "<9.9.99", "studio-42/elfinder": "<=2.1.67", "studiomitte/friendlycaptcha": "<0.1.4", @@ -21769,7 +21655,8 @@ "symfony/mime": ">=2,<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symfony/monolog-bridge": ">=2,<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symfony/phpunit-bridge": ">=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", - "symfony/polyfill": ">=1,<1.10", + "symfony/polyfill": ">=1,<1.10|>=1.17.1,<1.38.1", + "symfony/polyfill-intl-idn": ">=1.17.1,<1.38.1", "symfony/polyfill-php55": ">=1,<1.10", "symfony/process": "<5.4.51|>=6,<6.4.33|>=7,<7.1.7|>=7.3,<7.3.11|>=7.4,<7.4.5|>=8,<8.0.5", "symfony/proxy-manager-bridge": ">=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", @@ -21807,11 +21694,7 @@ "thelia/thelia": ">=2.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", "thinkcmf/thinkcmf": "<6.0.8", -<<<<<<< HEAD "thorsten/phpmyfaq": "<4.1.3", -======= - "thorsten/phpmyfaq": "<=4.1.1", ->>>>>>> dc5b8184 (Fixed mcp compatibility) "tikiwiki/tiki-manager": "<=17.1", "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", "tinymce/tinymce": "<7.2", @@ -22017,15 +21900,7 @@ "type": "tidelift" } ], -<<<<<<< HEAD -<<<<<<< HEAD - "time": "2026-05-24T20:23:40+00:00" -======= - "time": "2026-05-06T21:27:25+00:00" ->>>>>>> dc5b8184 (Fixed mcp compatibility) -======= - "time": "2026-05-08T23:22:52+00:00" ->>>>>>> 3f10a123 (updated dependencies) + "time": "2026-05-26T19:41:38+00:00" }, { "name": "sebastian/cli-parser", @@ -23540,17 +23415,9 @@ "time": "2025-11-17T20:03:58+00:00" } ], - "aliases": [ - { - "package": "mcp/sdk", - "version": "0.5.0.0", - "alias": "0.4.0", - "alias_normalized": "0.4.0.0" - } - ], + "aliases": [], "minimum-stability": "stable", "stability-flags": { - "api-platform/mcp": 20, "api-platform/metadata": 20, "roave/security-advisories": 20 }, From bcf439ba2274e6248d7645e35b0e0d860e2d6743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 31 May 2026 22:47:53 +0200 Subject: [PATCH 007/123] Allow to enable/disable MCP endpoint --- src/EventSubscriber/McpAccessSubscriber.php | 60 +++++++++++++++++++++ src/Settings/AISettings/AISettings.php | 3 ++ src/Settings/AISettings/McpSettings.php | 45 ++++++++++++++++ translations/messages.de.xlf | 20 ++++++- translations/messages.en.xlf | 18 +++++++ 5 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 src/EventSubscriber/McpAccessSubscriber.php create mode 100644 src/Settings/AISettings/McpSettings.php diff --git a/src/EventSubscriber/McpAccessSubscriber.php b/src/EventSubscriber/McpAccessSubscriber.php new file mode 100644 index 00000000..c7cab6e2 --- /dev/null +++ b/src/EventSubscriber/McpAccessSubscriber.php @@ -0,0 +1,60 @@ +. + */ + +declare(strict_types=1); + +namespace App\EventSubscriber; + +use App\Settings\AISettings\McpSettings; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\RequestEvent; +use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException; +use Symfony\Component\HttpKernel\KernelEvents; + +readonly class McpAccessSubscriber implements EventSubscriberInterface +{ + public function __construct(private McpSettings $mcpSettings) + { + } + + public static function getSubscribedEvents(): array + { + return [ + KernelEvents::REQUEST => ['onKernelRequest', 10], + ]; + } + + public function onKernelRequest(RequestEvent $event): void + { + if (!$event->isMainRequest()) { + return; + } + + $path = $event->getRequest()->getPathInfo(); + + if (!str_starts_with($path, '/mcp')) { + return; + } + + if (!$this->mcpSettings->enabled) { + throw new ServiceUnavailableHttpException(null, 'The MCP endpoint is disabled. Enable it in the system settings.'); + } + } +} diff --git a/src/Settings/AISettings/AISettings.php b/src/Settings/AISettings/AISettings.php index 732eb597..14544c04 100644 --- a/src/Settings/AISettings/AISettings.php +++ b/src/Settings/AISettings/AISettings.php @@ -35,6 +35,9 @@ class AISettings { use SettingsTrait; + #[EmbeddedSettings] + public ?McpSettings $mcp = null; + #[EmbeddedSettings] public ?OpenRouterSettings $openRouter = null; diff --git a/src/Settings/AISettings/McpSettings.php b/src/Settings/AISettings/McpSettings.php new file mode 100644 index 00000000..929efa41 --- /dev/null +++ b/src/Settings/AISettings/McpSettings.php @@ -0,0 +1,45 @@ +. + */ + +declare(strict_types=1); + +namespace App\Settings\AISettings; + +use App\Settings\SettingsIcon; +use Jbtronics\SettingsBundle\Metadata\EnvVarMode; +use Jbtronics\SettingsBundle\Settings\Settings; +use Jbtronics\SettingsBundle\Settings\SettingsParameter; +use Jbtronics\SettingsBundle\Settings\SettingsTrait; +use Symfony\Component\Translation\TranslatableMessage as TM; + +#[Settings(label: new TM("settings.misc.mcp"))] +#[SettingsIcon("fa-robot")] +class McpSettings +{ + use SettingsTrait; + + #[SettingsParameter( + label: new TM("settings.misc.mcp.enabled"), + description: new TM("settings.misc.mcp.enabled.help"), + envVar: "bool:MCP_ENABLED", + envVarMode: EnvVarMode::OVERWRITE, + )] + public bool $enabled = false; +} diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf index f736121a..8908dcaf 100644 --- a/translations/messages.de.xlf +++ b/translations/messages.de.xlf @@ -1,6 +1,6 @@ - + attachment_type.caption @@ -10034,6 +10034,24 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön Servereinstellungen + + + settings.misc.mcp + MCP (Model Context Protocol) Server + + + + + settings.misc.mcp.enabled + MCP-Endpunkt aktivieren + + + + + settings.misc.mcp.enabled.help + Aktiviert den MCP-Endpunkt (Model Context Protocol) unter /mcp, der es KI-Assistenten ermöglicht, mit Part-DB zu interagieren. + + settings.misc.kicad_eda diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index 11dcbd8e..760b01e1 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -10035,6 +10035,24 @@ Please note, that you can not impersonate a disabled user. If you try you will g Server settings + + + settings.misc.mcp + MCP (Model Context Protocol) Server + + + + + settings.misc.mcp.enabled + Enable MCP endpoint + + + + + settings.misc.mcp.enabled.help + Enable the MCP (Model Context Protocol) endpoint at /mcp, which allows AI assistants to interact with Part-DB. + + settings.misc.kicad_eda From 6dd08f6aeb93cf3524b53d9dcf333d6bd68940e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 31 May 2026 23:02:20 +0200 Subject: [PATCH 008/123] Added some metadata to the MCP server --- config/packages/mcp.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/config/packages/mcp.yaml b/config/packages/mcp.yaml index cabcad1b..4c2a9ea9 100644 --- a/config/packages/mcp.yaml +++ b/config/packages/mcp.yaml @@ -1,4 +1,12 @@ mcp: + app: "Part-DB" + version: "0.1.0" + description: "Part-DB is a inventory management database for electronic parts." + instructions: | + This server provides inventory information for your current user. It is mostly used for electronic parts, + but can be used for any kind of inventory. The stored objects are called parts. + If you miss some information from an search endpoint, try to retrieve more details using the ID of an entity. + client_transports: http: true stdio: false From 0c5f8dc9fd6f6ef92be68cefa8f5fc8df5cf67c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Wed, 10 Jun 2026 23:37:22 +0200 Subject: [PATCH 009/123] Updated dependencies --- composer.lock | 95 +++++++++++++++++++++++--------------------- config/reference.php | 6 +-- yarn.lock | 50 +++++++++++------------ 3 files changed, 77 insertions(+), 74 deletions(-) diff --git a/composer.lock b/composer.lock index 1c2f7dda..e7cb8570 100644 --- a/composer.lock +++ b/composer.lock @@ -2213,16 +2213,16 @@ }, { "name": "beberlei/assert", - "version": "v3.3.3", + "version": "v3.3.4", "source": { "type": "git", "url": "https://github.com/beberlei/assert.git", - "reference": "b5fd8eacd8915a1b627b8bfc027803f1939734dd" + "reference": "f193f4613c7d7fbcee2c05e4daff4061d49c040e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/beberlei/assert/zipball/b5fd8eacd8915a1b627b8bfc027803f1939734dd", - "reference": "b5fd8eacd8915a1b627b8bfc027803f1939734dd", + "url": "https://api.github.com/repos/beberlei/assert/zipball/f193f4613c7d7fbcee2c05e4daff4061d49c040e", + "reference": "f193f4613c7d7fbcee2c05e4daff4061d49c040e", "shasum": "" }, "require": { @@ -2274,9 +2274,9 @@ ], "support": { "issues": "https://github.com/beberlei/assert/issues", - "source": "https://github.com/beberlei/assert/tree/v3.3.3" + "source": "https://github.com/beberlei/assert/tree/v3.3.4" }, - "time": "2024-07-15T13:18:35+00:00" + "time": "2026-06-10T19:47:05+00:00" }, { "name": "beberlei/doctrineextensions", @@ -3349,16 +3349,16 @@ }, { "name": "doctrine/doctrine-bundle", - "version": "2.18.2", + "version": "2.18.3", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "0ff098b29b8b3c68307c8987dcaed7fd829c6546" + "reference": "241d61f6bbc77275d5a9f95d514241c058bf2d0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/0ff098b29b8b3c68307c8987dcaed7fd829c6546", - "reference": "0ff098b29b8b3c68307c8987dcaed7fd829c6546", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/241d61f6bbc77275d5a9f95d514241c058bf2d0a", + "reference": "241d61f6bbc77275d5a9f95d514241c058bf2d0a", "shasum": "" }, "require": { @@ -3395,6 +3395,7 @@ "psr/log": "^1.1.4 || ^2.0 || ^3.0", "symfony/doctrine-messenger": "^6.4 || ^7.0", "symfony/expression-language": "^6.4 || ^7.0", + "symfony/http-kernel": "^6.4 || ^7.0", "symfony/messenger": "^6.4 || ^7.0", "symfony/property-info": "^6.4 || ^7.0", "symfony/security-bundle": "^6.4 || ^7.0", @@ -3450,7 +3451,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineBundle/issues", - "source": "https://github.com/doctrine/DoctrineBundle/tree/2.18.2" + "source": "https://github.com/doctrine/DoctrineBundle/tree/2.18.3" }, "funding": [ { @@ -3466,7 +3467,7 @@ "type": "tidelift" } ], - "time": "2025-12-20T21:35:32+00:00" + "time": "2026-06-08T08:22:50+00:00" }, { "name": "doctrine/doctrine-migrations-bundle", @@ -4637,16 +4638,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.11.0", + "version": "7.11.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "c987f8ce84b8434fa430795eca0f3430663da72b" + "reference": "5af96f374e0ab4ebd747b8310888c99d3adb0a8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/c987f8ce84b8434fa430795eca0f3430663da72b", - "reference": "c987f8ce84b8434fa430795eca0f3430663da72b", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/5af96f374e0ab4ebd747b8310888c99d3adb0a8c", + "reference": "5af96f374e0ab4ebd747b8310888c99d3adb0a8c", "shasum": "" }, "require": { @@ -4665,7 +4666,7 @@ "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", "guzzle/client-integration-tests": "3.0.2", - "guzzlehttp/test-server": "^0.4", + "guzzlehttp/test-server": "^0.5", "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.52 || ^9.6.34", "psr/log": "^1.1 || ^2.0 || ^3.0" @@ -4745,7 +4746,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.11.0" + "source": "https://github.com/guzzle/guzzle/tree/7.11.1" }, "funding": [ { @@ -4761,7 +4762,7 @@ "type": "tidelift" } ], - "time": "2026-06-02T12:40:51+00:00" + "time": "2026-06-07T22:54:06+00:00" }, { "name": "guzzlehttp/promises", @@ -14477,16 +14478,16 @@ }, { "name": "symfony/polyfill-php83", - "version": "v1.38.1", + "version": "v1.38.2", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "8339098cae28673c15cce00d80734af0453054e2" + "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/8339098cae28673c15cce00d80734af0453054e2", - "reference": "8339098cae28673c15cce00d80734af0453054e2", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/796a26abb75ce49f3a84433cd81bf1009d73d5f8", + "reference": "796a26abb75ce49f3a84433cd81bf1009d73d5f8", "shasum": "" }, "require": { @@ -14533,7 +14534,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.1" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.2" }, "funding": [ { @@ -14553,7 +14554,7 @@ "type": "tidelift" } ], - "time": "2026-05-26T12:51:13+00:00" + "time": "2026-05-27T06:51:48+00:00" }, { "name": "symfony/polyfill-php84", @@ -17400,16 +17401,16 @@ }, { "name": "symplify/easy-coding-standard", - "version": "13.1.5", + "version": "13.1.6", "source": { "type": "git", - "url": "https://github.com/easy-coding-standard/ecs.git", - "reference": "96294d652c17ccffabb7d36f9d116dd5f0e6b84e" + "url": "https://github.com/ecsphp/ecs.git", + "reference": "af5d4a2475246f6acdd4d3a1fe2bb2187ec6b8a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/easy-coding-standard/ecs/zipball/96294d652c17ccffabb7d36f9d116dd5f0e6b84e", - "reference": "96294d652c17ccffabb7d36f9d116dd5f0e6b84e", + "url": "https://api.github.com/repos/ecsphp/ecs/zipball/af5d4a2475246f6acdd4d3a1fe2bb2187ec6b8a0", + "reference": "af5d4a2475246f6acdd4d3a1fe2bb2187ec6b8a0", "shasum": "" }, "require": { @@ -17444,9 +17445,9 @@ "static analysis" ], "support": { - "source": "https://github.com/easy-coding-standard/ecs/tree/13.1.5" + "source": "https://github.com/easy-coding-standard/ecs/tree/13.1.6" }, - "time": "2026-05-30T09:12:26+00:00" + "time": "2026-06-09T22:39:42+00:00" }, { "name": "tecnickcom/tc-lib-barcode", @@ -19493,21 +19494,21 @@ }, { "name": "phpstan/phpstan-doctrine", - "version": "2.0.25", + "version": "2.0.27", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-doctrine.git", - "reference": "e20e8bf3223ae6eba9c4b5987c391d922e094b3c" + "reference": "39b4ca45a07cdd6366eeefa2f7a993cddf3b9f9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/e20e8bf3223ae6eba9c4b5987c391d922e094b3c", - "reference": "e20e8bf3223ae6eba9c4b5987c391d922e094b3c", + "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/39b4ca45a07cdd6366eeefa2f7a993cddf3b9f9f", + "reference": "39b4ca45a07cdd6366eeefa2f7a993cddf3b9f9f", "shasum": "" }, "require": { "php": "^7.4 || ^8.0", - "phpstan/phpstan": "^2.1.34" + "phpstan/phpstan": "^2.2.2" }, "conflict": { "doctrine/collections": "<1.0", @@ -19564,9 +19565,9 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan-doctrine/issues", - "source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.25" + "source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.27" }, - "time": "2026-06-02T20:27:36+00:00" + "time": "2026-06-10T10:39:35+00:00" }, { "name": "phpstan/phpstan-strict-rules", @@ -20216,12 +20217,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "b000295a5fd02609ee7ad31d084cfa904af8a69a" + "reference": "21becf5973eb93d86cf68e3e724af0aa412e8129" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/b000295a5fd02609ee7ad31d084cfa904af8a69a", - "reference": "b000295a5fd02609ee7ad31d084cfa904af8a69a", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/21becf5973eb93d86cf68e3e724af0aa412e8129", + "reference": "21becf5973eb93d86cf68e3e724af0aa412e8129", "shasum": "" }, "conflict": { @@ -20611,7 +20612,7 @@ "inter-mediator/inter-mediator": "==5.5", "intercom/intercom-php": "==5.0.2", "invoiceninja/invoiceninja": "<5.13.4", - "ipl/web": "<=0.13", + "ipl/web": "<=0.10.2|>=0.11,<=0.13", "islandora/crayfish": "<4.1", "islandora/islandora": ">=2,<2.4.1", "ivankristianto/phpwhois": "<=4.3", @@ -20839,6 +20840,7 @@ "personnummer/personnummer": "<3.0.2", "ph7software/ph7builder": "<=17.9.1", "phanan/koel": "<=9.3.4", + "pheditor/pheditor": ">=2.0.1,<=2.0.3", "phenx/php-svg-lib": "<0.5.2", "php-censor/php-censor": "<2.0.13|>=2.1,<2.1.5", "php-mod/curl": "<2.3.2", @@ -20852,7 +20854,7 @@ "phpoffice/common": "<0.2.9", "phpoffice/math": "<=0.2", "phpoffice/phpexcel": "<=1.8.2", - "phpoffice/phpspreadsheet": "<=1.30.3|>=2,<=2.1.15|>=2.2,<=2.4.4|>=3,<=3.10.4|>=4,<=5.6", + "phpoffice/phpspreadsheet": "<=1.30.4|>=2,<=2.1.15|>=2.2,<=2.4.4|>=3,<=3.10.4|>=4,<=5.6", "phppgadmin/phppgadmin": "<=7.13", "phpseclib/phpseclib": "<=2.0.53|>=3,<=3.0.51", "phpservermon/phpservermon": "<3.6", @@ -20878,6 +20880,7 @@ "pocketmine/bedrock-protocol": "<8.0.2", "pocketmine/pocketmine-mp": "<5.42.1", "pocketmine/raklib": ">=0.14,<0.14.6|>=0.15,<0.15.1", + "poweradmin/poweradmin": "<4.2.4|>=4.3,<4.3.3", "pressbooks/pressbooks": "<5.18", "prestashop/autoupgrade": ">=4,<4.10.1", "prestashop/blockreassurance": "<=5.1.3", @@ -20947,7 +20950,7 @@ "shopware/core": "<6.6.10.18-dev|>=6.7,<6.7.10.1-dev", "shopware/platform": "<6.6.10.18-dev|>=6.7,<6.7.10.1-dev", "shopware/production": "<=6.3.5.2", - "shopware/shopware": "<=5.7.17|>=6.4.6,<6.6.10.10-dev|>=6.7,<6.7.6.1-dev", + "shopware/shopware": "<=6.3.5.2|>=6.4.6,<6.6.10.10-dev|>=6.7,<6.7.6.1-dev", "shopware/storefront": "<6.6.10.10-dev|>=6.7,<6.7.5.1-dev", "shopxo/shopxo": "<=6.4", "showdoc/showdoc": "<3.8.1", @@ -21300,7 +21303,7 @@ "type": "tidelift" } ], - "time": "2026-06-05T20:39:10+00:00" + "time": "2026-06-09T22:34:42+00:00" }, { "name": "sebastian/cli-parser", diff --git a/config/reference.php b/config/reference.php index 49c16f65..ecf0b0aa 100644 --- a/config/reference.php +++ b/config/reference.php @@ -718,7 +718,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * servicename?: scalar|Param|null, // Overrules dbname parameter if given and used as SERVICE_NAME or SID connection parameter for Oracle depending on the service parameter. * sessionMode?: scalar|Param|null, // The session mode to use for the oci8 driver * server?: scalar|Param|null, // The name of a running database server to connect to for SQL Anywhere. - * default_dbname?: scalar|Param|null, // Override the default database (postgres) to connect to for PostgreSQL connexion. + * default_dbname?: scalar|Param|null, // Override the default database (postgres) to connect to for PostgreSQL connection. * sslmode?: scalar|Param|null, // Determines whether or with what priority a SSL TCP/IP connection will be negotiated with the server for PostgreSQL. * sslrootcert?: scalar|Param|null, // The name of a file containing SSL certificate authority (CA) certificate(s). If the file exists, the server's certificate will be verified to be signed by one of these authorities. * sslcert?: scalar|Param|null, // The path to the SSL client certificate file for PostgreSQL. @@ -769,7 +769,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * servicename?: scalar|Param|null, // Overrules dbname parameter if given and used as SERVICE_NAME or SID connection parameter for Oracle depending on the service parameter. * sessionMode?: scalar|Param|null, // The session mode to use for the oci8 driver * server?: scalar|Param|null, // The name of a running database server to connect to for SQL Anywhere. - * default_dbname?: scalar|Param|null, // Override the default database (postgres) to connect to for PostgreSQL connexion. + * default_dbname?: scalar|Param|null, // Override the default database (postgres) to connect to for PostgreSQL connection. * sslmode?: scalar|Param|null, // Determines whether or with what priority a SSL TCP/IP connection will be negotiated with the server for PostgreSQL. * sslrootcert?: scalar|Param|null, // The name of a file containing SSL certificate authority (CA) certificate(s). If the file exists, the server's certificate will be verified to be signed by one of these authorities. * sslcert?: scalar|Param|null, // The path to the SSL client certificate file for PostgreSQL. @@ -801,7 +801,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * servicename?: scalar|Param|null, // Overrules dbname parameter if given and used as SERVICE_NAME or SID connection parameter for Oracle depending on the service parameter. * sessionMode?: scalar|Param|null, // The session mode to use for the oci8 driver * server?: scalar|Param|null, // The name of a running database server to connect to for SQL Anywhere. - * default_dbname?: scalar|Param|null, // Override the default database (postgres) to connect to for PostgreSQL connexion. + * default_dbname?: scalar|Param|null, // Override the default database (postgres) to connect to for PostgreSQL connection. * sslmode?: scalar|Param|null, // Determines whether or with what priority a SSL TCP/IP connection will be negotiated with the server for PostgreSQL. * sslrootcert?: scalar|Param|null, // The name of a file containing SSL certificate authority (CA) certificate(s). If the file exists, the server's certificate will be verified to be signed by one of these authorities. * sslcert?: scalar|Param|null, // The path to the SSL client certificate file for PostgreSQL. diff --git a/yarn.lock b/yarn.lock index 8e48638f..50a44061 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2223,9 +2223,9 @@ base64-js@^1.1.2, base64-js@^1.3.0: integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== baseline-browser-mapping@^2.10.12: - version "2.10.34" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.34.tgz#dedb606362446777cfe328d30d4ee15056d06303" - integrity sha512-IMDedajPifLnHNY0X9n8hKxRTQ6/eTHwr5bDo04WnuqxyKw6LYtQywCuuqPZwhl3aBXMvQpJov42GLCwRRdQzw== + version "2.10.35" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.35.tgz#f0f2232e0de2d2f82cc491bcf830b05ed05937c6" + integrity sha512-honAfLBde0HAFLdNyBEfuuENkF6zR+ozxqxa/2zJKHBe1qzLqyTSeRKpdPEHAP03rlDGyQOPnCSxnVpVqQo9Mg== big.js@^5.2.2: version "5.2.2" @@ -2877,9 +2877,9 @@ domhandler@^5.0.2, domhandler@^5.0.3: domelementtype "^2.3.0" dompurify@^3.0.3: - version "3.4.8" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.8.tgz#6c54f8c207160e7f83fcb7f4fd05a82ac36b1cdc" - integrity sha512-yb1cEmaOum7wFvOCSQxyfgVlv5D47Rc30iZWoMpbDIWTnJ6grDDQyu2KFJzB2k7u0pMuJcQ1zphH//fFnw2tjQ== + version "3.4.9" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.4.9.tgz#b036637b2df8997126b58837bc90f85dbcad6b2f" + integrity sha512-4dPSRMRDqHvs0V4YDFCsaIZo4if5u0xM+llyxiM2fwuZFdKArUBAF3VtI2+n8NKg9P870WMdYk0UhqQNoWXbfQ== optionalDependencies: "@types/trusted-types" "^2.0.7" @@ -2902,9 +2902,9 @@ domutils@^3.0.1: domhandler "^5.0.3" electron-to-chromium@^1.5.328: - version "1.5.368" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.368.tgz#8e8d4600c5f5f01e891f8f843b4a941afb640412" - integrity sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw== + version "1.5.371" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.371.tgz#fa5684f2a514c57368823f9e75553f9a7c5ef0be" + integrity sha512-e9htk9mAYL6AzmkEhSvVVw7IWGSBJ/Bqdn2eRyRLrj1g6sncN4WbFt5qnILYoCktktr45pyjIrOiRvBThQ808w== emoji-regex@^8.0.0: version "8.0.0" @@ -4153,25 +4153,25 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -pdfkit@^0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/pdfkit/-/pdfkit-0.18.0.tgz#573efa7f4c78a8ab1362232a05a589b97b292216" - integrity sha512-NvUwSDZ0eYEzqAiWwVQkRkjYUkZ48kcsHuCO31ykqPPIVkwoSDjDGiwIgHHNtsiwls3z3P/zy4q00hl2chg2Ug== +pdfkit@^0.19.0: + version "0.19.1" + resolved "https://registry.yarnpkg.com/pdfkit/-/pdfkit-0.19.1.tgz#633d5f031ce6f1ba6ce141325c6cf87fa6acb0a2" + integrity sha512-6Gzk+wDwTs4VSxsR5rCMTnIl5nlmkye1oWB0l2hDB1EX6ZNSIBroKQEv+2+fPPn+stVjyqzmsqRJVDfB9fo5DA== dependencies: "@noble/ciphers" "^1.0.0" "@noble/hashes" "^1.6.0" fontkit "^2.0.4" js-md5 "^0.8.3" linebreak "^1.1.0" - png-js "^1.0.0" + png-js "^1.1.0" pdfmake@^0.3.7: - version "0.3.9" - resolved "https://registry.yarnpkg.com/pdfmake/-/pdfmake-0.3.9.tgz#c837b471aa81ea0797b7cdac2a03db8ba65e1b7f" - integrity sha512-V8VIcjMG/yk7oJYhYjtvyLXvop3w3zcIB0bHdG3z1vuW8nVeemzRWu7YrOG7QA9KYaf858MZnCUG6hQ1Bei0vA== + version "0.3.10" + resolved "https://registry.yarnpkg.com/pdfmake/-/pdfmake-0.3.10.tgz#908bb4c1502fb2cf05434465a9feddebe6d51891" + integrity sha512-2dKalR/02xdIb8XFcT3UXHTBpMJjKGjY7l8fl0RRFGu93r15AsI8vEJPkPYcP+IhfJVTuMQiQFq08hNcIC7ohQ== dependencies: linebreak "^1.1.0" - pdfkit "^0.18.0" + pdfkit "^0.19.0" xmldoc "^2.0.3" picocolors@^1.0.0, picocolors@^1.1.0, picocolors@^1.1.1: @@ -4196,7 +4196,7 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -png-js@^1.0.0: +png-js@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/png-js/-/png-js-1.1.0.tgz#60a135216601f807b88a6d61ac93bd42a32c5ee1" integrity sha512-PM/uYGzGdNSzqeOgly68+6wKQDL1SY0a/N+OEa/+br6LnHWOAJB0Npiamnodfq3jd2LS/i2fMeOKSAILjA+m5Q== @@ -4423,9 +4423,9 @@ postcss-reduce-transforms@^7.0.3: postcss-value-parser "^4.2.0" postcss-selector-parser@^7.0.0, postcss-selector-parser@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz#e75d2e0d843f620e5df69076166f4e16f891cb9f" - integrity sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg== + version "7.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-7.1.2.tgz#e2dc51fc26c007a29bc3195ee9e68ca6df52e32e" + integrity sha512-Wjvt4scRFouioIInHf51IFNP4ltJ2EngJM+cZPGiqbKetBfmP3vpdPV8ID2S6JS6/jdo74N8+aEYH9lQr2C6sA== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -4733,9 +4733,9 @@ semver@^6.3.1: integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.3.2, semver@^7.3.4, semver@^7.6.3: - version "7.8.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.2.tgz#194bd65723a28cf82542d2bf176b91c26b343be1" - integrity sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ== + version "7.8.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.4.tgz#c73eceebae0616934be8dff28a7fd70757c8e696" + integrity sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA== serialize-javascript@^6.0.2: version "6.0.2" From b357ee196cc45c63df6f6e11d76db27bb1d0192b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Wed, 10 Jun 2026 23:37:57 +0200 Subject: [PATCH 010/123] Avoid usage of raw filter in javascript to minimize risk --- templates/projects/import_bom_map_fields.html.twig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/projects/import_bom_map_fields.html.twig b/templates/projects/import_bom_map_fields.html.twig index ee1e23ef..b272be64 100644 --- a/templates/projects/import_bom_map_fields.html.twig +++ b/templates/projects/import_bom_map_fields.html.twig @@ -132,8 +132,8 @@