-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Used typed tool handler for get_me
tool
#447
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
Conversation
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 standardizes tool handlers using NewTypedToolHandler
for the get_me
tool, boosts testing confidence with schema snapshots, and adds missing third-party licenses and entries in platform-specific license summaries.
- Refactor
GetMe
to use a typed tool handler and centralize JSON marshalling - Introduce schema snapshot tests (
toolsnaps
) and enhance existing unit tests - Add license files for new third-party dependencies and update
third-party-licenses.*.md
Reviewed Changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
pkg/github/context_tools.go | Refactored GetMe to use NewTypedToolHandler and removed manual JSON handling |
pkg/github/server.go | Added marshalledTextResult helper for consistent text results |
pkg/github/context_tools_test.go | Updated Test_GetMe to use table-driven checks and snapshot tests |
pkg/toolsets/toolsets_test.go | Renamed test for clarity and simplified assertions |
docs/testing.md | Documented usage of toolsnaps and updated test patterns |
third-party-licenses.windows.md (and linux/darwin variants) | Added entries for recently added dependencies |
Comments suppressed due to low confidence (5)
pkg/github/server.go:219
- [nitpick] The function name uses the British spelling
marshalledTextResult
. For consistency with Go'sjson.Marshal
and typical API conventions, consider renaming tomarshaledTextResult
.
func marshalledTextResult(v any) *mcp.CallToolResult {
third-party-licenses.windows.md:12
- List item indentation is inconsistent with the surrounding entries; align leading spaces (e.g., two spaces before the dash) so the markdown renders correctly.
- [github.com/go-openapi/jsonpointer](https://pkg.go.dev/github.com/go-openapi/jsonpointer) ([Apache-2.0](https://github.com/go-openapi/jsonpointer/blob/v0.19.5/LICENSE))
third-party-licenses.linux.md:12
- List item indentation is inconsistent with the surrounding entries; align leading spaces so the markdown list formatting remains uniform.
- [github.com/go-openapi/jsonpointer](https://pkg.go.dev/github.com/go-openapi/jsonpointer) ([Apache-2.0](https://github.com/go-openapi/jsonpointer/blob/v0.19.5/LICENSE))
third-party-licenses.darwin.md:12
- List item indentation is inconsistent; ensure two spaces before each dash for consistent markdown rendering across all OS-specific license files.
- [github.com/go-openapi/jsonpointer](https://pkg.go.dev/github.com/go-openapi/jsonpointer) ([Apache-2.0](https://github.com/go-openapi/jsonpointer/blob/v0.19.5/LICENSE))
docs/testing.md:29
- The line
committed.
is not indented to match the preceding list item; add two spaces before the dash or indent so it continues the markdown bullet correctly.
committed.
} | ||
type args struct{} | ||
handler := mcp.NewTypedToolHandler(func(ctx context.Context, _ mcp.CallToolRequest, _ args) (*mcp.CallToolResult, error) { | ||
client, err := getClient(ctx) |
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.
I have some ideas about having a handler function that injects:
type Clients struct {
rest..
gql..
}
Then all handlers don't have this getClient
boilerplate. Added a lot of types though, would rather feel a bit more pain.
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.
I think you just left a comment that agrees with my comment about structs, broadly I agree with this direction, and some nits, and a general question about how much we extract our types from mcp-go
types.
"type": "object" | ||
}, | ||
"name": "get_me" | ||
} |
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.
} | |
} | |
It doesn't really matter, but I do love EOF newlines being added by automation rather than omitted if it's possible.
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.
I can add it, but I don't really understand why it's useful to you? Does it help in your IDE or something?
mcp.WithString("reason", | ||
mcp.Description("Optional: the reason for requesting the user information"), | ||
), | ||
func GetMe(getClient GetClientFn, t translations.TranslationHelperFunc) (mcp.Tool, server.ToolHandlerFunc) { |
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.
Do we want to return an mcp.Tool or have our own struct that gets converted later, I suppose it's an utter pain to make versions of all their structs.
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.
I want our own types that can be adapted for mcp-go/go-sdk but I'm not paying that price right now. I want to do the move over to the typed handlers and then iterate from there.
return nil, fmt.Errorf("failed to marshal user: %w", err) | ||
} | ||
type args struct{} | ||
handler := mcp.NewTypedToolHandler(func(ctx context.Context, _ mcp.CallToolRequest, _ args) (*mcp.CallToolResult, error) { |
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.
Nice to see use of the typed handler (although this tool is not much of a showcase 😂).
I was going to ask the same thing as above, do we want to use mcp-go
structs here. I suppose we should for now.
A use case I can imagine is wrapping an existing handler with another one (to add something like chunking, or other aggregations like returning only the count). That sad part with the string output is that instead of Marshalling the data just-in-time, I would have to unmarshall the json again to process it in this form. 😓 this is a tough problem to solve without having to just re-write tools.
I had imagined we'd have a tool handler type that returns an interface (can be marshalled into json whatever that interface is called), and error. We would then give that a thin wrapper that binds it into mcp-go
. Maybe overkill for now, just something that is coming onto my radar.
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.
All good thoughts and as per #447 (comment) there's lots I do want to tackle but I want to do it piecemeal where we move over to having a struct for args, then we can look at the abstractions that make sense around that, rather than biting it all off at once.
Co-authored-by: Sam Morrow <info@sam-morrow.com>
Co-authored-by: Sam Morrow <info@sam-morrow.com>
Description
This PR is the first of many that moves handlers to use
NewTypedToolHandler
which is also a step towards the official Go SDK. While reworking this, I also took the opportunity to improve testing confidence.E2E Test