* [Docs] Render guides with Zensical, deploy via GitHub Pages actions phpDocumentor's guide renderer copies the markdown through mostly verbatim: relative links between pages keep pointing at `*.md` targets that do not exist in the built site, and nothing validates them, so the published guides are full of dead links. Zensical (the Material for MkDocs team's successor to MkDocs) resolves internal links against the page tree and fails the build on a broken one. `zensical build --strict` already found four dead links on the first run — three repo-relative links escaping docs/ (fixed to point at GitHub) and one wrong in-page anchor. phpDocumentor stays on for the class-level API reference only; `make docs` builds the guides into site/ and mounts the reference at site/api/, so its two header links back to the guides now target the site root. Deployment moves from pushing a gh-pages branch to the official GitHub Pages actions, and from release-only to every push on main, with pull requests building (but not deploying) so a broken link fails review instead of the site. NOTE: this needs the repository's Pages source switched to "GitHub Actions" (Settings -> Pages) once. * [Docs] Adopt the Python SDK's documentation look and feel The docs site now uses the same theme configuration as https://py.sdk.modelcontextprotocol.io/ so the language SDKs read as one set of docs: the MCP mark as logo and favicon, Inter/JetBrains Mono, the black/slate palette with a three-way (system/light/dark) toggle, instant navigation, code copy/annotate, and a right-hand table of contents. The markdown extension set is widened to the same list (tabbed blocks, task lists, footnotes, emoji/icons, mermaid fences), which the content restructure builds on. Styling is otherwise stock: no custom stylesheet, and Zensical's own `modern` theme variant, pinned explicitly rather than left to the default. The one departure is code highlighting, which is broken out of the box here: Pygments only highlights PHP after a `<?php` tag, so the guides — whose code blocks are almost all fragments — rendered as flat plain text. The `php` lexer is extended with `startinline`, and complete-file blocks use a `php-file` lexer that keeps the literal open tag highlighted. * [Docs] Restructure the guides into task-oriented sections The guides were ten flat pages, each opening with a hand-maintained table of contents and each mixing several audiences: `mcp-elements.md` covered tools, prompts, schema generation and handler-side logging, `transports.md` covered both transports plus framework integration, and `server-builder.md` covered configuration, sessions and custom message handlers. They are now split along the same lines as the Python SDK's documentation (https://py.sdk.modelcontextprotocol.io/), one topic per page: Get started installation, first server, the Inspector Servers tools, resources, resource templates, prompts, completions, schema generation, registration Inside your handler the ClientGateway, logging Running your server builder, STDIO, HTTP, framework integration, sessions, authorization Clients connecting, transports, capabilities, server-initiated requests, error handling Advanced events, protocol extensions, custom message handlers Prose is carried over as-is apart from the seams; what is new is the landing page and one index page per section, which say what the section is for and where to go next, so no page is a dead end. The per-page "Table of Contents" lists are gone — the theme renders one from the headings — and GitHub's `> [!IMPORTANT]` blockquotes became admonitions, which Zensical renders as callouts rather than plain quotes. Every code sample and factual claim was then checked against src/ and the runnable examples, which turned up long-standing errors in the carried-over prose. Samples that could not run: a prompt using a `system` role (MCP has only user/assistant), `Mcp\Schema\PromptMessage` (it is under `Schema\Content`) constructed with an array instead of a single content object, `Mcp\Capability\Prompt\Completion\ProviderInterface` (it is `Mcp\Capability\Completion\ProviderInterface`), `new EmbeddedResource(type:, resource: [...])` (neither parameter exists), a `: resource` return type (not a PHP type), `#[McpResource]` with a `{path}` variable (that is a template), a stray quote in the builder example, a `middlewares:` argument (it is `middleware:`), and `getRequest()->getAttribute()` in the OAuth guide (no such method — the values arrive on the request meta). Claims corrected: sampling's `system_prompt` option (it is `systemPrompt`), `SampleMessage` (it is `SamplingMessage`), `Notification` called an interface (abstract class), "parameter order matters" for URI templates (bound by name), full RFC 6570 support (only simple `{var}`), the tool description fallback chain, `void` returning empty content, a non-zero STDIO exit code, `ErrorEvent` being null for parse errors, handlers being "prepended", `Psr16StoreSession`, and PSR-3 log context being sent to the client (it is dropped). Sixteen `examples/` paths were missing their `server/` segment. README, the OAuth ADR and one source comment now point at the published site instead of at markdown files that moved. * [Docs] Run the docs workflow unfiltered, keep README links relative The `paths:` filters were mostly noise: `src/**` had to be in the list for the phpDocumentor build, which meant the workflow ran on nearly every PR anyway. They also missed two real inputs — `.phpdoc/template/**` and `composer.lock` — so a template tweak or a phpDocumentor bump could change the rendered site without triggering a build. README links go back to relative repo paths. The README is not part of the Zensical site (`docs_dir` is `docs/`), so those links are only ever resolved by GitHub and Packagist, where absolute URLs break in-repo navigation for no gain. The site pointer and the generated API reference stay absolute. * [Docs] Adopt the doc changes that landed on main into the new structure Twelve commits landed while the restructure was open, seven of them touching the flat guides this branch replaces. Renames merged on their own; the three files that were split apart needed their new sections placed by hand: - Connection retries, protocol version negotiation, sampling with tools and roots from `client.md` into `client/connecting.md` and `client/server-requests.md` - `ResourceLink` and structured output from `mcp-elements.md` into `servers/tools.md` - Protocol version negotiation from `server-builder.md` into `run/server-builder.md` The `setMaxRetries()` note claiming the value is never acted on is gone — #413 implemented it. Callouts became admonitions and cross-links were repointed at the new paths, as everywhere else in this branch. * [Docs] Document the elicitation and roots client examples Both were missing from the examples guide: the elicitation client predates this branch, the roots client arrived with #395. * [Docs] Fold the 2026-07-28 lifecycle into the new structure Main's stateless-lifecycle.md becomes a docs/lifecycle/ section, and the pages main touched — deprecations, the middleware split, the client's modern era — land where the restructure moved them. * [Docs] Link the Inspector to its documentation, not its repo * [Docs] Distribute the 2026-07-28 material into the task sections The Python and TypeScript SDKs file each feature where the task lives and keep only an era comparison on its own page. Follow them: input-required moves next to the other handler concerns, caching, subscriptions and era routing to "Running your server", and one Protocol versions page carries the rest. * [Docs] Move protocol version negotiation onto the Protocol versions page The builder page keeps the setProtocolVersion() knob and links out; how a revision is agreed now sits beside the era it belongs to. * [Docs] Slim the README to a funnel, turn Examples into an index * [Docs] Fix the code samples and API listings flagged by the audit * [Docs] Link the negotiation spec section at latest, not draft
21 KiB
21 KiB
Changelog
All notable changes to mcp/sdk will be documented in this file.
0.8.0
- Speak the 2026-07-28 lifecycle from the client:
Clientopens withserver/discoverinstead ofinitializeon that revision, stamps each request's_metawith the protocol version, its own capabilities and client info, and sends the standardMcp-Method/Mcp-Name/Mcp-Param-*headers an intermediary routes on — the last from the newMcp\Client\Stateless\ToolCatalog, which knows from the tool list which arguments a call must mirror. Aninput_requiredresult is answered automatically byInputRequestResolver, which asks the host's elicitation, sampling and roots handlers and retries the same request withinputResponsesand therequestStatethe server sent.Mcp\Schema\Wire\McpHeaderholds the header names and the=?base64?…?=sentinel both sides share. - Serve both protocol eras from one endpoint:
StreamableHttpTransportclassifies each request — a2026-07-28envelope, aninitializehandshake, or a session-bound follow-up — through the newMcp\Server\Wire\InboundClassifierand routes it to the dispatcher that owns it, so a single URL answers a modern client and a handshake-era one alike.Server::builder()->build()now carries both dispatchers;Builder::withoutModernEra()opts out andBuilder::setModernVersions()narrows what the modern leg answers for.Mcp\Server\InputRequiredShimlets a handler written for multi round-trip requests also serve a handshake-era client, by turning each ask into the request/response exchange that era has. - Carry W3C trace context through a request (SEP-414):
traceparent,tracestateandbaggagein a request's_metaare exposed to handlers asRequestContext::getTraceContext()and echoed onto the notifications that request causes, so a span stays joined across the response stream. Values pass through exactly as they arrived, and no OpenTelemetry dependency is added. - Deliver notifications on a
subscriptions/listenstream (SEP-2575), which previously acknowledged and then carried nothing for the rest of its life. NewMcp\Server\Subscription\NotificationBusInterfacewith two implementations —InMemoryNotificationBusfor stdio and persistent runtimes,Psr16NotificationBusfor PHP-FPM, where the worker holding the stream open and the worker publishing are different processes — set withBuilder::setNotificationBus(). Registry changes are published automatically through aPublishingEventDispatcherthat wraps whatever PSR-14 dispatcher was configured.Builder::setSubscriptionLifetime()replaces the hard-coded 30-second ceiling, where0means "until the client or the runtime ends it". - Add
Mcp\Server\Wire\CachePolicy, set withBuilder::setCachePolicy(), to configure the SEP-2549 caching hints the 2026-07-28 lifecycle stamps on a cacheable result. The conservativettlMs: 0, cacheScope: privatestays the default, sincepubliclets a shared proxy serve one caller's answer to another and only the operator can make that call. AReadResourceResultmay also carry its ownttlMs/cacheScope, which win over the policy. - Add typed readers to
Mcp\Server\Stateless\InputContext:elicitResult(),samplingResult()androotsResult()deserialize a multi round-trip answer instead of handing back the raw arrayresponse()returns. A malformed answer reads as absent rather than throwing, so a handler asks again — which is what the spec says a server SHOULD do when the information it needs is still missing. - Answer a request over a response stream under the 2026-07-28 lifecycle:
StatelessProtocolruns handlers in a fiber, so$gateway->progress()and$gateway->log()work there as they do in the handshake era. The stream opens only if the handler actually emits something and the client'sAcceptadmitstext/event-stream, and the choice is made after the handler's first suspension, so a request that turns out to need-32021or-32602is still answered with the status the spec fixes for it. - Honour
io.modelcontextprotocol/logLevel(SEP-2575), which replaced thelogging/setLevelRPC: a request naming no level receives nonotifications/messageat all, one naming a level receives the messages at or above it. AddsLoggingLevel::severity()andLoggingLevel::isAtLeast(). - [BC Break] Answer a not-found subject with
-32602(Invalid params) instead of-32002, which the 2026-07-28 revision reserves and forbids emitting (SEP-2164).resources/readpicks the code from the revision serving the request —-32602with the uri inerror.datafrom2026-07-28on,-32002below.prompts/getfor an unknown prompt,completion/completefor an unknown reference andtools/callfor an unknown tool switch to-32602in every revision:-32002was never the code for those. AddsProtocolVersion::usesInvalidParamsForResourceNotFound(). - Add the multi round-trip requests pattern for the 2026-07-28 lifecycle (SEP-2322): a
tools/callorprompts/gethandler returningMcp\Schema\Result\InputRequiredResultcomes back asresultType: "input_required"carrying theinputRequestsit needs answered and an opaquerequestState; the client retries the same request withinputResponses, which the handler reads throughRequestContext::getInputContext().Mcp\Server\Stateless\RequestStateCodecsigns and time-bounds the state — set the key withBuilder::setRequestState(). - Validate the standard MCP request headers under the 2026-07-28 lifecycle (SEP-2243):
Mcp\Server\Stateless\StandardHeaderValidator, set withBuilder::setHeaderValidator(), checks thatMcp-MethodandMcp-Nameagree with the body they travel with and that aMcp-Param-*mirrors the argument its tool markedx-mcp-header, answering-32020when they disagree. Intermediaries route on these headers, so a value contradicting the body has to be refused rather than ignored. - [BC Break]
Mcp\Schema\JsonRpc\Erroracceptsnullas its$id, andgetId()may return it. An error response whose id could not be read now omits the member instead of sending"id": ""— which claimed the peer had issued a request with an empty-string id. All thefor*()factories default tonull,fromArray()accepts a missing or explicitly-null id, andMessageFactorydecodes both as an id-less error rather than rejecting them. - Preserve the original request
idon an invalid-but-parseable message (-32600) instead of answering it id-less:InvalidInputMessageExceptionnow carries the recoverable id viagetRequestId()/setRequestId(), threaded fromMessageFactorythrough to the error response. - [BC Break] Add the extensions framework SEP-2133 defines, which MCP Apps sits on.
ExtensionInterface::getId()now returns the newMcp\Schema\Extension\ExtensionIdentifiervalue object instead of a string, which validates the identifier against the_metakey naming rules at construction time.ExtensionInterfacealso gainsgetMessages()/getRequestHandlers(), so an extension can contribute the message classes its methods decode into — without which its methods cannot be decoded at all — and the handlers serving them; extensions that only announce a capability can extend the newMcp\Schema\Extension\AbstractExtensionand skip both.MessageFactory::make()takes an$additionallist of message classes, andRequestHandlerInterface's result template is now covariant. - [BC Break] Drop the SDK-only name pattern on
ResourceDefinition/ResourceTemplate$name— the spec allows any string (its own examples usemain.rsandProject Files). URI/URI-template validation is unchanged. - Add
ClientGateway::supportsExtension(),Client\Builder::enableExtension(), andClientCapabilities::withExtensions()so clients can negotiate and check protocol extensions (e.g. MCP Apps) the same way servers already do. [BC Break]ServerExtensionInterfaceis replaced by the side-agnosticMcp\Schema\Extension\ExtensionInterface. - Deprecate Roots, Sampling and Logging per SEP-2577 (protocol revision
2026-07-28, earliest removal2027-07-28). They keep working but using them now triggers a deprecation notice — migrate to tool arguments/resource URIs, a direct LLM provider API, and stderr/OpenTelemetry respectively. - [BC Break] Gate
structuredContenton the negotiated protocol revision: a tool result that's a PHP list (or an object serializing to a JSON array) is now only sent asstructuredContenton protocol revisions2026-07-28+; older revisions omit it and keep the JSON-encoded value incontent. - Add protocol revision negotiation during
initialize: the server counter-offers a revision it supports, and the client now fails the handshake instead of continuing on an unagreed revision. AddsClient::getProtocolVersion()and the2026-07-28revision. - Add sampling-with-tools support: sampling requests can include tools and tool-choice preferences, messages support tool-use/tool-result content blocks, and clients advertise
sampling.context/sampling.toolsviaClientGateway::supportsSamplingTools()/supportsSamplingContext(). A request that violates the spec's tool-flow rules is now rejected with a proper JSON-RPC error instead of being left unanswered. - [BC Break]
SamplingMessage::$contentandCreateSamplingMessageResult::$contentmay now be a list of content blocks instead of just one — use the newgetContentBlocks()to always get a list. - [BC Break]
CreateSamplingMessageResultnow rejects any role other thanassistant, and rejects empty content, per spec. - Close the remaining schema gaps for
2025-06-18/2025-11-25and add the2026-07-28surface (SEP-2106): url-mode elicitation (ClientGateway::elicitUrl()/supportsElicitationUrl()),Implementation::title, andoutputSchema/structuredContentaccepting any JSON value rather than only objects. - Add
Mcp\Schema\Content\ResourceLink— reference a resource by URI/name in tool results and prompt messages without embedding its contents. - Add client-side Roots support:
RootsCallbackInterface,Client::sendRootsListChanged(), and server-sideClientGateway::listRoots()/supportsRoots(). - Add
ClientGateway::supportsSampling()to check the client's advertised capabilities before sending a sampling request, matchingsupportsRoots()/supportsElicitation(). - Fix empty tool/resource schemas serializing as
[]instead of{}ininputSchema/outputSchema. - Fix
PromptResultFormatterdroppingannotations,_meta, andmimeTypewhen a prompt generator returns content as a plain array. - Add
annotationssupport toImageContent, matchingTextContent/AudioContent.
0.7.0
- Add client-side elicitation support:
ElicitationCallbackInterface,ElicitationRequestHandler, andElicitationExceptionlet clients respond to server elicitation requests. - Defer element loading to the first registry read: loaders now run at request time (first
has*/get*call) instead of eagerly atBuilder::build(), fixing empty registries under persistent runtimes (e.g. FrankenPHP worker mode) where a loader's data source is not ready at build time. AddsBuilder::setLazyLoading()(default on), a publicRegistry::load(), and an optionalLoaderInterfaceconstructor argument onRegistry. - [BC Break] Element loading is lazy by default: loader failures now surface on the first request rather than at
Builder::build(), andinitializeadvertises capabilities from the configured sources rather than the loaded registry. CallBuilder::setLazyLoading(false)to restore eager build-time loading. - Allow
[$instance, 'methodName']as an element handler inBuilder::addTool(),addResource(),addResourceTemplate(), andaddPrompt(). Unblocks handlers with constructor dependencies that the container-lessnew $className()fallback cannot build. - Always emit an
itemsschema for array tool parameters: untyped arrays getitems: {}and nullable typed arrays (e.g.string[]|null) keep their element type. Fixes strict clients rejecting tools with "array type must have items" (#151). - Harden JSON-RPC input parsing: single-message vs batch is now decided from the decoded JSON type (object → single, list array → batch) instead of the raw first byte. Scalars, empty payloads, and non-object batch elements are surfaced as
InvalidInputMessageExceptionentries instead of triggering warnings or aTypeError. - Add
maxBatchSize(default100) toMessageFactory— oversized JSON-RPC batches are rejected before any message is constructed, guarding against amplification. - Add
maxBodyBytes(default 4 MiB) toStreamableHttpTransport— POST bodies exceeding the cap are rejected with413. Unknown-size/chunked bodies are read incrementally and stopped at the cap so they cannot exhaust memory. - Reject malformed
Mcp-Session-Idheaders with a400response: a repeated header or a value that is not a valid UUID is now rejected up front instead of surfacing as an uncaughtUuid::fromString()error. - Extract RFC 9728 metadata serving into
ProtectedResourceMetadataHandler, a transport-neutral PSR-15RequestHandlerInterfacethat can be mounted directly as a Symfony/Laravel controller;ProtectedResourceMetadataMiddlewarenow delegates to it (no BC break).
0.6.0
- Add
Builder::add(Tool|ResourceDefinition|ResourceTemplate|Prompt $definition, ElementHandlerInterface $handler)for explicit registration of elements whose schema is only known at runtime. - Add handler interfaces
ToolHandlerInterface,ResourceHandlerInterface,ResourceTemplateHandlerInterface,PromptHandlerInterface, and theElementHandlerInterfacemarker. - [BC Break] Renamed
Mcp\Schema\ResourcetoMcp\Schema\ResourceDefinition. No alias. - [BC Break] Renamed
Mcp\Capability\Registry\Loader\ArrayLoadertoMcp\Capability\Registry\Loader\ReflectedElementLoader. - [BC Break] Bump default protocol version to
2025-11-25 - Add support for MCP Apps extension in schema and server
- Add
extensionstoServerCapabilitiesandClientCapabilitiesandBuilder::enableExtension() - Allow overriding the default name pattern for Discovery
- Add configurable session garbage collection (
gcProbability/gcDivisor) - Add optional
titlefield toResourceDefinitionandResourceTemplatefor MCP spec compliance - Add
ChainLoaderto compose multipleLoaderInterfaceimplementations via explicit ordering. - Add
RegistryInterface::unregisterTool(),unregisterResource(),unregisterResourceTemplate(),unregisterPrompt()— idempotent removals. - Add
RegistryInterface::hasTool(),hasResource(),hasResourceTemplate(),hasPrompt()— by-name existence checks. DiscoveryLoadernow refreshes only its own previously written entries; manual registrations (viaBuilder::addTool()etc. or runtime$registry->registerTool()calls) survive rediscovery, and a same-name manual registration takes precedence over discovery on collision.- [BC Break] Removed
ElementReference::$isManualpublic property and thebool $isManualparameter from all*Referenceconstructors. Origin tracking is no longer carried on the element; manual-over-discovered precedence is encoded by loader execution order. - [BC Break]
RegistryInterface::registerTool(),registerResource(),registerResourceTemplate(),registerPrompt()lost their trailingbool $isManual = falseparameter. Callers using positional arguments must drop the flag. - [BC Break] Removed
RegistryInterface::clear(),getDiscoveryState(),setDiscoveryState(). Rediscovery now goes throughDiscoveryLoader::load()directly. Registry::register*()semantics changed to plain last-write-wins (overwrites silently) and the methods now return the stored*Reference. The previous "discovered registration is ignored when a manual one already exists" precedence rule still applies, but is now enforced byDiscoveryLoadervia reference-identity tracking — and still emits a debug log when a discovery is skipped due to a conflicting registration.- Add optional
titleparameter toBuilder::addResource()andBuilder::addResourceTemplate()for MCP spec compliance - [BC Break]
Builder::addResource()signature changed —$titleparameter added between$nameand$description. Callers using positional arguments must switch to named arguments. - [BC Break]
Builder::addResourceTemplate()signature changed —$titleparameter added between$nameand$description. Callers using positional arguments must switch to named arguments. - Add
CorsMiddleware,DnsRebindingProtectionMiddleware, andProtocolVersionMiddlewareforStreamableHttpTransport, composed automatically as the default stack viaStreamableHttpTransport::defaultMiddleware() - [BC BREAK]
StreamableHttpTransportconstructor:$corsHeadersparameter removed; CORS is now configured viaCorsMiddleware. The$middlewareparameter is nullable —null(or omitted) installs the default stack;[]disables all defaults. DefaultAccess-Control-Allow-Originis no longer set (was*). - [BC Break]
ResourceDefinition::__construct()signature changed —$titleparameter added between$nameand$description. Callers using positional arguments must switch to named arguments. - [BC Break]
ResourceTemplate::__construct()signature changed —$titleparameter added between$nameand$description. Callers using positional arguments must switch to named arguments. - [BC Break]
McpResourceandMcpResourceTemplateattribute signatures changed —$titleparameter added between$nameand$description. Callers using positional arguments must switch to named arguments.
0.5.0
- Add built-in authentication middleware for HTTP transport using OAuth
- Add client component for building MCP clients
- Add
Builder::setReferenceHandler()to allow customReferenceHandlerInterfaceimplementations (e.g. authorization decorators) - Add elicitation enum schema types per SEP-1330:
TitledEnumSchemaDefinition,MultiSelectEnumSchemaDefinition,TitledMultiSelectEnumSchemaDefinition - [BC break] Make Symfony Finder component optional. Users would need to install
symfony/findernow themselves - Add
LenientOidcDiscoveryMetadataPolicyfor identity providers that omitcode_challenge_methods_supported(e.g. FusionAuth, Microsoft Entra ID) - Add OAuth 2.0 Dynamic Client Registration middleware (RFC 7591)
- Add optional
titlefield toPromptandMcpPromptfor MCP spec compliance - [BC Break]
Builder::addPrompt()signature changed —$titleparameter added between$nameand$description. Callers using positional arguments for$descriptionmust switch to named arguments. - Add optional
titlefield toToolandMcpToolfor MCP spec compliance - [BC Break]
Tool::__construct()signature changed —$titleparameter added between$nameand$inputSchema. Callers using positional arguments must switch to named arguments or passnullfor$title. - [BC Break]
McpToolattribute signature changed —$titleparameter added between$nameand$description. Callers using positional arguments for$descriptionmust switch to named arguments. - [BC Break]
Builder::addTool()signature changed —$titleparameter added between$nameand$description. Callers using positional arguments for$descriptionmust switch to named arguments.
0.4.0
- Rename
Mcp\Server\Session\Psr16StoreSessiontoMcp\Server\Session\Psr16SessionStore - Add missing handlers for resource subscribe/unsubscribe and persist subscriptions via session
- Introduce
SessionManagerto encapsulate session handling (replacesSessionFactory) and move garbage collection logic fromProtocol.
0.3.0
- Add output schema support to MCP tools
- Add validation of the input parameters given to a Tool.
- Rename
Mcp\Capability\Registry\ResourceReference::$schematoMcp\Capability\Registry\ResourceReference::$resource. - Introduce
SchemaGeneratorInterfaceandDiscovererInterfaceto allow custom schema generation and discovery implementations. - Remove
DocBlockParser::getSummary()method, useDocBlockParser::getDescription()instead.
0.2.2
- Throw exception when trying to inject parameter with the unsupported names
$_sessionor$_request. Throwableobjects are passed to log context instead of the exception message.
0.2.1
- Add
RunnerControlforStdioTransportto allow break out from continuously listening for new input. - Open range of supported Symfony versions to include v5.4
0.2.0
- Make
Protocolstateless by decouple if fromTransportInterface. RemovedProtocol::getTransport(). - Change signature of
Builder::addLoaders(...$loaders)toBuilder::addLoaders(iterable $loaders). - Removed
ClientAwareInterfacein favor of injecting aRequestContextwith argument injection. - The
ClientGatewaycannot be injected with argument injection anymore. UseRequestContextinstead. - Removed
ClientAwareTrait - Removed
Protocol::getTransport() - Added parameter for
TransportInterfacetoProtocol::processInput()
0.1.0
- First tagged release of package
- Support for implementing MCP server