Repository navigation
Conversation
AgentCat::track() takes the Builder before or after build() or buildStateless(), and the Mcp\Server built from it. The place of the call among the customer's calls no longer changes what AgentCat records: - AgentCat's request handlers go to the front of the Builder's list, so a tools/call or tools/list handler added before track(), or by a Symfony compiler pass, is delegated to and recorded. - AgentCat wraps the reference handler at the first call instead of at track(), so setReferenceHandler() after track() keeps the exception. - After build(), AgentCat instruments the server's tool registry and the schema validator of the library's tools/call handler, which stay mutable. Calls to unknown tools, calls with invalid arguments and calls answered by a customer's tools/call handler give no event there, and a server with a reference handler of its own is tracked only before build(). The mcp/sdk scenario suites and the HTTP and stdio end-to-end tests run for the Builder before build(), the Builder after build() and the built server.
…constructor takes a validator first
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
With
mcp/sdk, the place ofAgentCat::track()no longer changes what AgentCat records, as with the TypeScript SDK. Version 1.0.0 had four order rules, and this pull request removes them:track()must run beforebuild(); afterbuild()it logs "the mcp/sdk Builder was already built" and tracks nothing; a builtMcp\Serveris not acceptedtrack()takes the Builder before or afterbuild()orbuildStateless(), and the builtMcp\Servertools/callortools/listhandler added withaddRequestHandler()beforetrack()answers first, and AgentCat records nothingtrack()runs, and delegate to the customer'ssetReferenceHandler()aftertrack()loses the exception of a failing tooltrack()How it works
build()(McpSdkAdapter::install()): AgentCat puts its two handlers before every handler added so far (BuilderAccess::prependRequestHandlers()), and no longer callssetReferenceHandler()orsetContainer(). At the firsttools/call,Delegates::runner()copies the library'sCallToolHandleraround aCapturingReferenceHandlerof the reference handler thatbuild()gave it.build()(BuiltServer): the request handlers are fixed inreadonlymembers, so AgentCat changes the two objects they share, which stay mutable:RegistryCall. That handler takes mcp/sdk's injectedRequestContext, runs the same interception as beforebuild()with a copy of the library's handler over the tools as registered, and returns the result or rethrows the tool's exception, so the library answers and logs as it would without AgentCat.InjectedSchemaValidator), which checks the arguments without AgentCat's injected ones against the tool's own schema. The errors are the same as beforebuild().Limits after
build()The library answers these before any tool runs, so they give no event; the docs say so:
-32602, as before).tools/callhandler of the customer's answers.A server with a reference handler of the customer's is not tracked after
build(): AgentCat's tool handler would run inside it, which could run each tool twice. AgentCat logs "the mcp/sdk server has a reference handler of its own (…): track the Builder before build()".The docs change is agentcathq/agentcat-ui#256.
Two listing differences after
build():get_more_toolsis the registry's last tool, so a full last page puts it on a page of its own, andResponseEventlisteners see the injected tools.Behavior changes for 1.0.0 users
tools/callortools/listhandler added beforetrack()(or in a Symfony compiler pass) is now tracked: its listing getssession_id,contextandget_more_tools, and each call gives an event. Under PHP-FPM, such atools/listhandler also runs once for each page that AgentCat reads during atools/call.setReferenceHandler()aftertrack(), error events now carry the tool's exception.track()afterbuild()now tracks the server.Tests
CallTool,ListTools,CallErrors,Hooks,RequestContext,ResponseEvent,ListingGolden) run three times, throughEntry: the Builder beforebuild(), the Builder afterbuild(), and the built server. The tests of the limits above skip afterbuild(), with the reason.php -S) and stdio end-to-end tests also run on the built server.track(), a reference handler set aftertrack(),track()on the Builder or the server afterbuild(), tracking both, a Builder afterbuildStateless(), a custom reference handler afterbuild(), a registry that cannot be read,InjectedSchemaValidator, andDelegates::runner()with drift.Builder::$requestHandlers,Registry::$tools,CallToolHandler::$registry,$referenceHandler,$logger,$schemaValidator) and the extendedSchemaValidator.Test plan
composer check: php-cs-fixer, Rector, PHPStan (both configurations), the dependency analyser and every suitephp tests/bin/docs-samples.phpon the docs pull request: 58 PHP blocks passphp -land PHPStan