Contributing to logiscape/mcp-sdk-php
July 5, 2026 · View on GitHub
Thank you for wanting to contribute. This SDK is small, community-maintained, and focused on tracking the MCP specification faithfully in pure PHP, so it runs comfortably on typical shared hosting (cPanel / Apache / PHP-FPM) in addition to CLI environments.
Before submitting code, please skim this document — it is short, and it will save everyone time.
Ways to help
- Report a bug with a minimal reproduction (new bug report).
- Propose a feature that closes a gap against the MCP spec (new feature request).
- Submit a pull request that fixes a bug, closes a conformance gap, improves documentation, or strengthens tests.
- Review other people's pull requests. Good review is scarce and valuable.
Ground rules
A handful of principles apply to every change:
- Spec-faithful, no shortcuts. Implementations must match the intent of
the MCP specification. We do not bypass SDK code paths or hand-craft
responses purely to green a conformance test. A test we cannot honestly
pass goes in the relevant track's baseline file
(
conformance/conformance-baseline.ymlfor the stable track,conformance/conformance-draft-baseline.ymlfor the2026-07-28draft track) with a documented root cause. Seeconformance/README.mdfor the longer version. - cPanel / Apache compatibility is mandatory for core MCP features. If a
change breaks a core feature under shared hosting, it's not ready. Features
that truly cannot be made shared-hosting-compatible (for instance, certain
long-lived connections) still ship — for spec alignment — but must fail
gracefully rather than crash the SDK. See
docs/compatibility.md. - Avoid breaking changes when a non-breaking alternative exists. When a
breaking change to the public API or a documented flow is genuinely
necessary, it bumps the minor version (
v1.X), not the patch (v1.7.X), and it is called out in CHANGELOG.md. - Be kind. The Code of Conduct applies.
Local development setup
Requirements:
- PHP 8.1 or later with
ext-curlandext-json(seedocs/dependency-policy.mdfor optional and dev dependencies). - Composer.
- Node.js (required to run the MCP conformance suite — the tool version is
pinned in
package.json).
Clone the repo, then:
composer install
npm install # for the conformance tests
Test stack
We take protocol behaviour seriously and maintain several overlapping
checks. The canonical, complete reference for every layer — commands,
conventions, and interpretation — is
docs/testing.md. In brief:
composer check(PHPUnit + PHPStan) — run before every PR; it must pass.- MCP Conformance suite — not part of
composer checkbecause it needs Node.js. Two tracks run during v2 development:composer conformance(stable, published-spec scenarios — the regression gate) andcomposer conformance-draft(the2026-07-28RC scenarios). Run the stable track when your change touches protocol handling, transports, session management,McpServer, or anything undersrc/Shared/; add the draft track when it touches2026-07-28behavior. Seeconformance/README.mdfor how to interpret the baselines and when it is — and is not — acceptable to update them. - Official MCP Inspector and real-world AI applications —
encouraged spot-checks for user-visible changes; recipes in
docs/testing.md.
Coding standards
- PHP 8.1+. Every file starts with
declare(strict_types=1);. - PSR-4 autoloading under the
Mcp\namespace (seecomposer.json). - Type hints are mandatory. Parameters, return types, and typed handler
callables.
mixedis allowed only where the type really is variable. - Comments: sparing. The non-obvious "why" is worth writing down; the "what" is usually obvious from the code. No multi-paragraph docblocks unless the method really needs them.
- Tests live in
tests/and mirror the source tree (tests/Server/ServerSessionTest.phptestssrc/Server/ServerSession.php). Test classes arefinaland extendPHPUnit\Framework\TestCase. - Logging: components take an optional PSR-3
LoggerInterfaceand fall back toNullLogger. Examples may use Monolog for illustration — the SDK itself does not depend on it. - Error handling: protocol errors throw
Mcp\Shared\McpError, transport errors throwRuntimeException, invalid parameters throwInvalidArgumentException. These are converted to JSON-RPC error responses automatically.
Pull request workflow
- Search existing issues and PRs to avoid duplication. If what you want to do is non-trivial, open an issue first to agree on the approach.
- Work on a branch in your fork. Keep the branch focused — one logical change per PR.
- Run
composer checkand, if your change touches protocol or transport code,composer conformanceas well. - Update documentation alongside code changes, not in a follow-up PR.
That includes
docs/server-dev.md/docs/client-dev.mdwhen public API changes,CHANGELOG.mdunder[Unreleased], and any relevant file underdocs/(see the documentation index). - Open the PR using the pull-request template. Fill in every section that applies — skipping sections often means a second round of review.
- Respond to review. Force-pushing to a PR branch is fine and sometimes
expected. Merge commits from
maininto the branch are also fine — we squash on merge.
Versioning policy
We follow Semantic Versioning, interpreted for this SDK as follows:
- Patch (
v1.7.X) — non-breaking bug fixes and minor new features or improvements. Internal refactors, documentation, and tooling changes also land here. - Minor (
v1.X) — breaking changes to the public API or documented flows, major new features, and expanded MCP protocol version support (adopting a new spec revision). Breaking changes are called out in CHANGELOG.md and in the release notes for the tag. - Major (
v2) — aligned with the wider MCP ecosystem. When the official MCP SDKs cut av2, this SDK will cut its ownv2to signal feature parity. We do not bump the major on our own cadence.
When in doubt about whether a change is breaking or "major," ask on the PR. The conservative answer is usually correct.
Releases
Releases are cut by the core maintainer. A release PR:
- moves the relevant entries from
[Unreleased]into a new version heading in CHANGELOG.md, - lands any last documentation adjustments, and
- is tagged (
vX.Y.Z) on merge.
Contributors do not need to update tags themselves — please just leave your
entries under [Unreleased] and the maintainer will handle the cut.
Issue labelling
We try to follow the
MCP SDK Working Group label conventions.
The labels we use and what they mean are documented in
docs/labels.md. If you're opening an issue, you don't need
to label it — a maintainer will.
Questions
If you're stuck on a contribution, comment on the relevant issue or PR and a maintainer or another contributor will try to help. General support questions belong in SUPPORT.md rather than in a draft PR.
Thank you
This project gets materially better every time someone takes the time to open a thoughtful issue or a clean pull request. Thank you.