-
Notifications
You must be signed in to change notification settings - Fork 3.2k
refactor: Separate ServerTool with HandlerFunc pattern and ToolDependencies #1589
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Extract ServerTool struct into pkg/toolsets/server_tool.go - Add ToolDependencies struct for passing common dependencies to handlers - HandlerFunc allows lazy handler generation from Tool definitions - NewServerTool for new dependency-based tools - NewServerToolLegacy for backward compatibility with existing handlers - Update toolsets.go to store and pass dependencies - Update all call sites to use NewServerToolLegacy Co-authored-by: Adam Holt <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR refactors the ServerTool architecture to separate tool definitions from handler generation, introducing a dependency injection pattern through ToolDependencies and a HandlerFunc type. This enables static tool definitions that can be passed around before dependencies are available, with handlers generated on-demand during registration.
Key Changes:
- New
ToolDependenciesstruct centralizes all shared dependencies (GitHub clients, translation functions, caches, flags) HandlerFuncpattern allows lazy handler generation with dependencies injected at registration timeNewServerToolLegacyprovides backward compatibility during the migrationSetDependencies()method onToolsetenables fluent API for dependency configuration
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
pkg/toolsets/server_tool.go |
New file defining ToolDependencies, HandlerFunc, and refactored ServerTool struct with constructor functions |
pkg/toolsets/toolsets.go |
Adds deps field to Toolset, implements SetDependencies() method, updates RegisterTools to use stored deps, modifies RegisterSpecificTools signature |
pkg/toolsets/toolsets_test.go |
Updates mockTool to use new API (NewServerToolFromHandler), adds InputSchema to mock tools, passes deps to RegisterSpecificTools |
pkg/github/tools.go |
Creates ToolDependencies struct and calls SetDependencies() on all toolsets, converts all tools to use NewServerToolLegacy |
pkg/github/dynamic_tools.go |
Simplifies EnableToolset to use toolset.RegisterTools(s) instead of manual loop |
internal/ghmcp/server.go |
Updates RegisterSpecificTools call to include ToolDependencies{} parameter and imports toolsets package |
- Move ToolDependencies to pkg/github/dependencies.go with proper types - Use 'any' in toolsets package to avoid circular dependencies - Add NewTool/NewToolFromHandler helpers that isolate type assertion - Tool implementations will be fully typed with no assertions scattered - Infrastructure ready for incremental tool migration
790b435 to
187a8b6
Compare
Migration Progress UpdateAdded the first tool file migration: search.go Changes in this commit (b29546e)
Migration Pattern DemonstratedOld signature: func SearchRepositories(getClient GetClientFn, t translations.TranslationHelperFunc) (mcp.Tool, mcp.ToolHandlerFor[...])New signature: func SearchRepositories(t translations.TranslationHelperFunc) toolsets.ServerToolThe key benefit: no type assertions in tool code. The single type assertion is isolated in the |
Migrate search.go tools (SearchRepositories, SearchCode, SearchUsers, SearchOrgs) to use the new NewTool helper and ToolDependencies pattern. - Functions now take only TranslationHelperFunc and return ServerTool - Handler generation uses ToolDependencies for typed access to clients - Update tools.go call sites to remove getClient parameter - Update tests to use new Handler(deps) pattern This demonstrates the migration pattern for additional tool files. Co-authored-by: Adam Holt <[email protected]>
b29546e to
43acefe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
almaleksia
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed & tested, looks good to me. However it makes sense to release it next week along with other changes related to tool refactoring.
Summary
This PR refactors the
ServerTooltype to separate tool definitions from handler generation, enabling:HandlerFuncwhen tools are registeredToolDependenciesstructArchitecture
Avoiding Circular Dependencies
The
toolsetspackage usesanyfor dependencies to stay generic and avoid importingpkg/github. The type safety is achieved through:pkg/github/dependencies.go- DefinesToolDependencieswith proper typesNewTool/NewToolFromHandlerhelpers - Isolate the single type assertionChanges
New file:
pkg/github/dependencies.goToolDependenciesstruct with properly typed fieldsNewTool[In, Out]- typed helper for standard tool handlersNewToolFromHandler- typed helper for raw handlersUpdated:
pkg/toolsets/server_tool.goHandlerFuncusesanyfor deps to avoid circular importsNewServerTool/NewServerToolFromHandleracceptanyNewServerToolLegacyfor backward compatibility with existing handlersUpdated:
pkg/toolsets/toolsets.godepsfield typed asanySetDependencies(any)methodUpdated:
internal/ghmcp/server.gogithub.ToolDependenciesand passes to toolsetsBenefits
NewToolhelperNext Steps
Individual tool files can be incrementally migrated from
NewServerToolLegacytoNewToolin stacked PRs.Testing