From 03fce3f7c70fc563467d2c7380eef4c4981b0ee2 Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Thu, 11 Dec 2025 10:06:53 -0600 Subject: [PATCH 1/5] Add API documentation generation with phpDocumentor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add phpDocumentor configuration and `docs` Makefile target - Generate docs during CI to catch errors before releases - Set up GitHub Pages with Jekyll for hosting generated docs - Add GitHub Actions workflow to deploy docs to GitHub Pages on releases 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .github/workflows/docs.yml | 38 +++++++++++++++++++++++++++++++++ .github/workflows/pipeline.yaml | 3 +++ .gitignore | 5 +++++ Makefile | 7 +++++- composer.json | 4 +++- docs/_config.yml | 2 ++ docs/index.html | 12 +++++++++++ phpdoc.dist.xml | 25 ++++++++++++++++++++++ 8 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/docs.yml create mode 100644 docs/_config.yml create mode 100644 docs/index.html create mode 100644 phpdoc.dist.xml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..28a6f5f7 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,38 @@ +name: Deploy Documentation + +on: + release: + types: [published] + workflow_dispatch: + +permissions: + contents: write + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + coverage: "none" + + - name: Install Composer + uses: "ramsey/composer-install@v3" + + - name: Generate API Documentation + run: make docs + + - name: Copy API docs into docs directory + run: cp -r build/docs docs/api + + - name: Deploy to gh-pages branch + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs + enable_jekyll: true diff --git a/.github/workflows/pipeline.yaml b/.github/workflows/pipeline.yaml index cb769d43..90d85ad4 100644 --- a/.github/workflows/pipeline.yaml +++ b/.github/workflows/pipeline.yaml @@ -142,3 +142,6 @@ jobs: - name: PHPStan run: vendor/bin/phpstan analyse + + - name: Documentation + run: make docs diff --git a/.gitignore b/.gitignore index 45c94f10..07afa6f8 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,8 @@ examples/**/sessions tests/Conformance/results tests/Conformance/sessions tests/Conformance/logs/*.log + +# phpDocumentor +build/ +.phpdoc/ +phpDocumentor.phar diff --git a/Makefile b/Makefile index 3f62692d..159edcd7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: deps-stable deps-low cs phpstan tests unit-tests inspector-tests coverage ci ci-stable ci-lowest conformance-tests +.PHONY: deps-stable deps-low cs phpstan tests unit-tests inspector-tests coverage ci ci-stable ci-lowest conformance-tests docs deps-stable: composer update --prefer-stable @@ -36,3 +36,8 @@ ci: ci-stable ci-stable: deps-stable cs phpstan tests ci-lowest: deps-low cs phpstan tests + +docs: + vendor/bin/phpdoc + @grep -q 'No errors have been found' build/docs/reports/errors.html || \ + (echo "Documentation errors found. See build/docs/reports/errors.html" && exit 1) diff --git a/composer.json b/composer.json index e0c2edbc..643849f4 100644 --- a/composer.json +++ b/composer.json @@ -37,6 +37,7 @@ "nyholm/psr7": "^1.8", "nyholm/psr7-server": "^1.1", "php-cs-fixer/shim": "^3.91", + "phpdocumentor/shim": "^3", "phpstan/phpstan": "^2.1", "phpunit/phpunit": "^10.5", "psr/simple-cache": "^2.0 || ^3.0", @@ -69,7 +70,8 @@ }, "config": { "allow-plugins": { - "php-http/discovery": false + "php-http/discovery": false, + "phpdocumentor/shim": true }, "sort-packages": true } diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 00000000..b3611564 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,2 @@ +include: + - _* diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..c6cf2f25 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,12 @@ + + + + + + + MCP PHP SDK Documentation + + +

Redirecting to API Documentation...

+ + diff --git a/phpdoc.dist.xml b/phpdoc.dist.xml new file mode 100644 index 00000000..c9d7920d --- /dev/null +++ b/phpdoc.dist.xml @@ -0,0 +1,25 @@ + + + MCP PHP SDK + + build/docs + + + + + src + + api + + vendor/**/* + tests/**/* + + + + + From 962a0d5408ecf2a04f6d4a173af1b3a97be49d3e Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Thu, 11 Dec 2025 10:18:12 -0600 Subject: [PATCH 2/5] Fix phpDocumentor errors in type annotations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change class-string union types to use phpDocumentor-compatible syntax and reorder docblock tags so class descriptions precede `@author` tags. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/JsonRpc/MessageFactory.php | 6 +++--- src/Server/Session/Psr16StoreSession.php | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/JsonRpc/MessageFactory.php b/src/JsonRpc/MessageFactory.php index 2ca446c2..1bb82db8 100644 --- a/src/JsonRpc/MessageFactory.php +++ b/src/JsonRpc/MessageFactory.php @@ -37,7 +37,7 @@ final class MessageFactory /** * Registry of all known message classes that have methods. * - * @var array> + * @var list|class-string> */ private const REGISTERED_MESSAGES = [ Schema\Notification\CancelledNotification::class, @@ -68,7 +68,7 @@ final class MessageFactory ]; /** - * @param array> $registeredMessages + * @param list|class-string> $registeredMessages */ public function __construct( private readonly array $registeredMessages, @@ -151,7 +151,7 @@ private function createMessage(array $data): MessageInterface /** * Finds the registered message class for a given method name. * - * @return class-string + * @return class-string|class-string * * @throws InvalidInputMessageException */ diff --git a/src/Server/Session/Psr16StoreSession.php b/src/Server/Session/Psr16StoreSession.php index aacf0ffc..2f403f1a 100644 --- a/src/Server/Session/Psr16StoreSession.php +++ b/src/Server/Session/Psr16StoreSession.php @@ -17,12 +17,12 @@ use Symfony\Component\Uid\Uuid; /** - * @author luoyue <1569097443@qq.com> - * * PSR-16 compliant cache-based session store. * * This implementation uses any PSR-16 compliant cache as the storage backend * for session data. Each session is stored with a prefixed key using the session ID. + * + * @author luoyue <1569097443@qq.com> */ class Psr16StoreSession implements SessionStoreInterface { From 5f72f4562a5615593a44f7bfcbc211b896de0938 Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Thu, 11 Dec 2025 10:47:21 -0600 Subject: [PATCH 3/5] Fix CI: pin phar-io/composer-distributor ^1.0.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit phar-io/composer-distributor 1.0.0 has a bug where it uses the wrong package version when determining the phpDocumentor download URL, causing CI to fail with 404 errors when using --prefer-lowest. Version 1.0.2 fixes this issue. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 643849f4..8803947c 100644 --- a/composer.json +++ b/composer.json @@ -36,6 +36,7 @@ "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", From b0215a5013431a5c9b90fa60f2e6b2c7c7801fc3 Mon Sep 17 00:00:00 2001 From: Jonathan Hefner Date: Wed, 31 Dec 2025 14:34:44 -0600 Subject: [PATCH 4/5] Integrate markdown guides into phpDocumentor output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Configure phpDocumentor to generate both API documentation and user guides in a single unified site. This replaces the previous Jekyll-based approach where API docs were copied into the docs folder. - Add `` configuration to `phpdoc.dist.xml` - Create custom template with "Guides" navigation link - Replace `docs/index.html` redirect with `docs/index.md` guide index - Update workflow to publish `build/docs` directly without Jekyll - Track `.phpdoc/template/` while still ignoring `.phpdoc/cache/` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .github/workflows/docs.yml | 9 +++------ .gitignore | 2 +- .phpdoc/template/base.html.twig | 8 ++++++++ docs/_config.yml | 2 -- docs/index.html | 12 ------------ docs/index.md | 7 +++++++ phpdoc.dist.xml | 7 +++++++ 7 files changed, 26 insertions(+), 21 deletions(-) create mode 100644 .phpdoc/template/base.html.twig delete mode 100644 docs/_config.yml delete mode 100644 docs/index.html create mode 100644 docs/index.md diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 28a6f5f7..11875200 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -24,15 +24,12 @@ jobs: - name: Install Composer uses: "ramsey/composer-install@v3" - - name: Generate API Documentation + - name: Generate Documentation run: make docs - - name: Copy API docs into docs directory - run: cp -r build/docs docs/api - - name: Deploy to gh-pages branch uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs - enable_jekyll: true + publish_dir: ./build/docs + enable_jekyll: false diff --git a/.gitignore b/.gitignore index 07afa6f8..aaafeb02 100644 --- a/.gitignore +++ b/.gitignore @@ -12,5 +12,5 @@ tests/Conformance/logs/*.log # phpDocumentor build/ -.phpdoc/ +.phpdoc/cache/ phpDocumentor.phar diff --git a/.phpdoc/template/base.html.twig b/.phpdoc/template/base.html.twig new file mode 100644 index 00000000..e24756ae --- /dev/null +++ b/.phpdoc/template/base.html.twig @@ -0,0 +1,8 @@ +{% extends 'layout.html.twig' %} + +{% set topMenu = { + "menu": [ + { "name": "Guides", "url": "guide/docs/index.html"} + ] +} +%} diff --git a/docs/_config.yml b/docs/_config.yml deleted file mode 100644 index b3611564..00000000 --- a/docs/_config.yml +++ /dev/null @@ -1,2 +0,0 @@ -include: - - _* diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index c6cf2f25..00000000 --- a/docs/index.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - MCP PHP SDK Documentation - - -

Redirecting to API Documentation...

- - diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..32216b7b --- /dev/null +++ b/docs/index.md @@ -0,0 +1,7 @@ +# MCP PHP SDK Guides + +- [MCP Elements](mcp-elements.html) — Core capabilities (Tools, Resources, Resource Templates, and Prompts) with registration methods. +- [Server Builder](server-builder.html) — Fluent builder class for creating and configuring MCP server instances. +- [Transports](transports.html) — STDIO and HTTP transport implementations with guidance on choosing between them. +- [Client Communication](client-communication.html) — Methods for servers to communicate back to clients: sampling, logging, progress, and notifications. +- [Examples](examples.html) — Example projects demonstrating attribute-based discovery, dependency injection, HTTP transport, and more. diff --git a/phpdoc.dist.xml b/phpdoc.dist.xml index c9d7920d..ad2b3429 100644 --- a/phpdoc.dist.xml +++ b/phpdoc.dist.xml @@ -20,6 +20,13 @@ tests/**/* + + + docs + + guide + + From 5c20aa921ec3d1fb8d57f3168daf1f8bb785e0e9 Mon Sep 17 00:00:00 2001 From: Christopher Hertel Date: Sun, 1 Feb 2026 16:17:17 +0100 Subject: [PATCH 5/5] Fine-tuning for path, config, and layout --- .github/workflows/docs.yml | 2 +- .gitignore | 3 +-- .phpdoc/template/base.html.twig | 7 ++++++- .../components/header-title.html.twig | 10 ++++++++++ Makefile | 2 +- docs/index.md | 10 +++++----- ...tion.md => server-client-communication.md} | 0 phpdoc.dist.xml | 20 +++++++++++++++---- 8 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 .phpdoc/template/components/header-title.html.twig rename docs/{client-communication.md => server-client-communication.md} (100%) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 11875200..ff15d7ff 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -31,5 +31,5 @@ jobs: uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./build/docs + publish_dir: ./.phpdoc/build enable_jekyll: false diff --git a/.gitignore b/.gitignore index aaafeb02..6dc5d9ec 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,5 @@ tests/Conformance/sessions tests/Conformance/logs/*.log # phpDocumentor -build/ +.phpdoc/build/ .phpdoc/cache/ -phpDocumentor.phar diff --git a/.phpdoc/template/base.html.twig b/.phpdoc/template/base.html.twig index e24756ae..760f1652 100644 --- a/.phpdoc/template/base.html.twig +++ b/.phpdoc/template/base.html.twig @@ -2,7 +2,12 @@ {% set topMenu = { "menu": [ - { "name": "Guides", "url": "guide/docs/index.html"} + { "name": "Guides", "url": "docs/index.html"}, + { "name": "Specification", "url": "https://modelcontextprotocol.io/" } + ], + "social": [ + { "iconClass": "fab fa-github", "url": "https://github.com/modelcontextprotocol/php-sdk"}, + { "iconClass": "fab fa-discord", "url": "https://discord.gg/6CSzBmMkjX"} ] } %} diff --git a/.phpdoc/template/components/header-title.html.twig b/.phpdoc/template/components/header-title.html.twig new file mode 100644 index 00000000..fe8d091f --- /dev/null +++ b/.phpdoc/template/components/header-title.html.twig @@ -0,0 +1,10 @@ +

+ + + + + + + {{ project.name }} + +

diff --git a/Makefile b/Makefile index 159edcd7..5358de25 100644 --- a/Makefile +++ b/Makefile @@ -39,5 +39,5 @@ ci-lowest: deps-low cs phpstan tests docs: vendor/bin/phpdoc - @grep -q 'No errors have been found' build/docs/reports/errors.html || \ + @grep -q 'No errors have been found' .phpdoc/build/reports/errors.html || \ (echo "Documentation errors found. See build/docs/reports/errors.html" && exit 1) diff --git a/docs/index.md b/docs/index.md index 32216b7b..5bfe45ea 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,7 @@ # MCP PHP SDK Guides -- [MCP Elements](mcp-elements.html) — Core capabilities (Tools, Resources, Resource Templates, and Prompts) with registration methods. -- [Server Builder](server-builder.html) — Fluent builder class for creating and configuring MCP server instances. -- [Transports](transports.html) — STDIO and HTTP transport implementations with guidance on choosing between them. -- [Client Communication](client-communication.html) — Methods for servers to communicate back to clients: sampling, logging, progress, and notifications. -- [Examples](examples.html) — Example projects demonstrating attribute-based discovery, dependency injection, HTTP transport, and more. +- [MCP Elements](mcp-elements.md) — Core capabilities (Tools, Resources, Resource Templates, and Prompts) with registration methods. +- [Server Builder](server-builder.md) — Fluent builder class for creating and configuring MCP server instances. +- [Transports](transports.md) — STDIO and HTTP transport implementations with guidance on choosing between them. +- [Server-Client Communication](server-client-communication.md) — Methods for servers to communicate back to clients: sampling, logging, progress, and notifications. +- [Examples](examples.md) — Example projects demonstrating attribute-based discovery, dependency injection, HTTP transport, and more. diff --git a/docs/client-communication.md b/docs/server-client-communication.md similarity index 100% rename from docs/client-communication.md rename to docs/server-client-communication.md diff --git a/phpdoc.dist.xml b/phpdoc.dist.xml index ad2b3429..b209b815 100644 --- a/phpdoc.dist.xml +++ b/phpdoc.dist.xml @@ -7,10 +7,11 @@ > MCP PHP SDK - build/docs + .phpdoc/build - + latest + src @@ -19,14 +20,25 @@ vendor/**/* tests/**/* + + phpstan-type + phpstan-type-import + template + template-covariant + template-extends + template-implements + extends + implements + docs - guide + / - + +