-
Notifications
You must be signed in to change notification settings - Fork 4
Prototype: MCP Mode #629
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?
Prototype: MCP Mode #629
Conversation
Add Model Context Protocol (MCP) server support to the baton-sdk, allowing connectors to expose their functionality via MCP as an alternative to gRPC. New pkg/mcp package provides: - MCPServer that wraps ConnectorServer and exposes tools via stdio transport - Dynamic tool registration based on connector capabilities - Handlers for read operations (list_resource_types, list_resources, etc.) - Handlers for provisioning (grant, revoke, create_resource, delete_resource) - Handlers for ticketing (list_ticket_schemas, create_ticket, get_ticket) Usage: connectors now support an `mcp` subcommand that starts the MCP server on stdio, enabling AI assistants to interact with the connector.
WalkthroughThis pull request introduces Model Context Protocol (MCP) server support, enabling connectors to expose their capabilities as MCP tools via stdio transport. It adds the MCP SDK as a dependency, implements protocol handlers for resource and entitlement management, and wires a new CLI subcommand to run connectors in MCP server mode. Changes
Sequence Diagram(s)sequenceDiagram
participant CLI
participant Config
participant MCPServer
participant Connector
participant MCP SDK
CLI->>Config: DefineConfigurationV2 with "mcp" subcommand
Config->>MCPServer: MakeMCPServerCommand()
MCPServer->>MCPServer: Bind flags, init logging/tracing
MCPServer->>Connector: GetConnectorFunc(ctx, name, v)
Connector-->>MCPServer: ConnectorServer instance
MCPServer->>MCPServer: NewMCPServer(ctx, name, connector)
MCPServer->>Connector: GetMetadata() to infer capabilities
Connector-->>MCPServer: capabilities (resources, provisioning, etc.)
MCPServer->>MCP SDK: Register tools conditionally by capability
MCPServer->>MCP SDK: Serve() on STDIO
MCP SDK->>MCP SDK: Listen for tool calls over stdio
MCP SDK->>MCPServer: Call tool handler (e.g., handleListResources)
MCPServer->>Connector: List/Get/Grant/Revoke/etc. via protobuf RPC
Connector-->>MCPServer: Protobuf response message
MCPServer->>MCPServer: protoToMap(response)
MCPServer-->>MCP SDK: Tool result as generic map
MCP SDK-->>Client: JSON-RPC response
sequenceDiagram
participant MCP Client as External MCP Client
participant Stdio as Stdio Transport
participant MCPServer
participant ProtoHandler as ConnectorServer
MCP Client->>Stdio: POST callTool (method=grant, params={...})
Stdio->>MCPServer: handleGrant(CallToolRequest, GrantInput)
MCPServer->>MCPServer: Parse input (entitlementID, principalID, etc.)
MCPServer->>ProtoHandler: Grant(ctx, &GrantRequest{...})
ProtoHandler-->>MCPServer: &GrantResult{} (protobuf)
MCPServer->>MCPServer: protoToMap(result)
MCPServer-->>Stdio: CallToolResult{content=[{type:text, text:JSON...}]}
Stdio-->>MCP Client: JSON-RPC response
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 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.
Actionable comments posted: 15
🤖 Fix all issues with AI agents
In @pkg/cli/commands.go:
- Line 29: The import line using the alias mcpPkg
("github.com/conductorone/baton-sdk/pkg/mcp") is improperly formatted per
goimports; fix it by running goimports to reformat the imports or manually
reorder/adjust the import block to match goimports style (ensure correct
grouping, spacing, and removal of any unused imports), e.g., run goimports -w on
the commands.go in the CLI package to apply the fix.
In @pkg/mcp/handlers.go:
- Around line 42-45: The annotations slice is being placed directly into the
result map instead of converting it with protoListToMaps, causing inconsistent
protojson handling; call protoListToMaps(resp.GetAnnotations()) into a variable
(annotations), check the error and return
mcp.NewToolResultError(fmt.Sprintf("failed to serialize annotations: %v", err)),
nil on failure, and then use annotations in the result map instead of
resp.GetAnnotations().
In @vendor/github.com/mark3labs/mcp-go/mcp/types.go:
- Around line 225-255: UnmarshalJSON in NotificationParams currently eagerly
initializes p.Meta (and p.AdditionalFields) causing MarshalJSON to emit an empty
"_meta" even when input omitted; modify UnmarshalJSON (in the NotificationParams
type) to only set p.Meta when the incoming map contains a "_meta" key and its
value is a map[string]any (leave p.Meta nil otherwise), and only initialize
p.AdditionalFields if there are actually other keys to store, so that absent
fields remain nil and are not marshaled back as empty objects.
- Around line 85-104: MarshalJSON for URITemplate can panic when t or t.Template
is nil; update URITemplate.MarshalJSON to guard that case by checking if t ==
nil || t.Template == nil and returning a safe JSON representation (for example
json.Marshal("") or json.Marshal(nil) per repo convention) instead of calling
t.Raw(); modify only the URITemplate.MarshalJSON implementation so it checks the
nil condition and returns the safe marshaled value when nil, otherwise continue
to return json.Marshal(t.Raw()).
In @vendor/github.com/mark3labs/mcp-go/mcp/utils.go:
- Around line 762-795: ParseResourceContents currently treats empty-but-present
"text" or "blob" as absent because it checks ExtractString(...) != "", causing
valid empty strings to fall through to the "unsupported resource type" error;
change the logic to detect presence of the keys in contentMap (e.g., check _,
present := contentMap["text"] and _, present := contentMap["blob"]) and when
present call ExtractString to get the value (which may be empty) and construct
the corresponding TextResourceContents or BlobResourceContents with that value,
leaving the existing _meta validation and URI/mime handling intact.
In @vendor/github.com/mark3labs/mcp-go/server/server.go:
- Around line 659-710: handleInitialize reads s.capabilities concurrently
without synchronization which can race with writers using capabilitiesMu; wrap
the entire read section in a read lock by calling s.capabilitiesMu.RLock()
before accessing s.capabilities and defer s.capabilitiesMu.RUnlock() (or the
equivalent unlock) so all reads of s.capabilities inside handleInitialize are
protected; ensure you reference the existing mutex name capabilitiesMu and
perform the lock/unlock at the start/end of the method where capabilities are
read.
- Around line 616-628: The ListTools() function is returning pointers that all
end up pointing to the same loop variable `tool`; fix it by copying the loop
value into a new local variable inside the loop and storing the address of that
copy (e.g., create `t := tool` then `toolsCopy[name] = &t`) or by allocating a
new ServerTool and copying fields, so each map entry in `toolsCopy` has its own
distinct *ServerTool pointer; keep the existing RLock/RUnlock and return
semantics.
In @vendor/github.com/mark3labs/mcp-go/server/sse.go:
- Around line 372-389: The shutdown path can double-close sseSession.done
causing a panic; add a safe close helper on sseSession (e.g., add a close()
method that uses a sync.Once or an atomic CAS to call close(session.done)
exactly once) and replace direct close(session.done) calls in SSEServer.Shutdown
and in handleSSE (and the other location around lines 493-506) with
session.close(); ensure all places use that single session.close() to avoid
races.
- Around line 399-403: Replace the hardcoded wildcard CORS header on the SSE
response by making allowed origins configurable and only echoing back the
request Origin when it matches the configured list (or omit the header by
default); specifically, stop always calling
w.Header().Set("Access-Control-Allow-Origin", "*") and instead check
r.Header.Get("Origin") against a new configuration slice (e.g., allowedOrigins)
or option passed to the SSE handler, and if it matches set
Access-Control-Allow-Origin to that origin (or do not set the header when no
match).
In @vendor/github.com/mark3labs/mcp-go/server/streamable_http.go:
- Around line 511-528: Concurrent GETs can race because when LoadOrStore returns
loaded==true the existing session may be unregistered/deleted by the original
handler’s deferred cleanup; to fix, detect loaded==true after
s.activeSessions.LoadOrStore(sessionID, newSession) and immediately reject the
second GET with HTTP 409 (Conflict) and a clear message (e.g., "session already
has an active listener"), avoiding registering or deferring deletion for the
duplicate; reference newStreamableHttpSession, s.activeSessions.LoadOrStore,
RegisterSession and UnregisterSession to locate the change.
- Around line 529-541: In the GET handler, verify the ResponseWriter implements
http.Flusher before calling w.WriteHeader and sending the 200 OK; move the
flusher check (flusher, ok := w.(http.Flusher)) and the error path
(http.Error(...)) to occur immediately after setting headers
(Content-Type/Cache-Control/Connection) but before w.WriteHeader(http.StatusOK),
and only call w.WriteHeader and flusher.Flush() after confirming ok; update the
handler code paths that reference the flusher variable (flusher.Flush()) so they
run only when ok is true.
- Around line 1024-1032: streamableHttpSession.Initialized() always returns
true; add an internal initialized flag on the streamableHttpSession struct
(e.g., initialized bool) defaulting to false, set that flag to true inside
streamableHttpSession.Initialize(), and have streamableHttpSession.Initialized()
return the flag instead of true; if session methods may be called concurrently,
protect the flag with a mutex or use atomic operations when setting/reading it
to avoid race conditions.
- Around line 654-677: handleDelete currently deletes per-session stores but
never removes the session from s.activeSessions nor from s.server.sessions,
leaving notifications and memory leaks; after the existing deletes and before
responding, remove the session entry from s.activeSessions and also
unregister/remove it from s.server.sessions (or call the server-side unregister
method if one exists) while honoring any server-side session lock/guard (use the
server's mutex or UnregisterSession helper if present) so the session is fully
deregistered and will no longer receive notifications.
In @vendor/github.com/yosida95/uritemplate/v3/escape.go:
- Around line 80-93: The pctEncode function currently splits the rune's numeric
value into 4 bytes instead of percent-encoding the rune's UTF-8 octets; update
pctEncode to first UTF-8 encode the rune (use utf8.EncodeRune or equivalent to
get the byte sequence) and then iterate over the produced bytes, writing each
byte as "%"+two hex digits to the provided strings.Builder (using the existing
hex lookup), ensuring you encode exactly the UTF-8 length returned rather than
fixed 4-byte components.
🧹 Nitpick comments (10)
vendor/github.com/mark3labs/mcp-go/server/errors.go (1)
29-36: Use a value receiver forErrDynamicPathConfig.Error()to avoid nil panics + broaden usability.
With a pointer receiver, an accidentally-nil*ErrDynamicPathConfigstored aserrorwould panic onError(). A value receiver avoids that and still supportserrors.As.Proposed diff
type ErrDynamicPathConfig struct { Method string } -func (e *ErrDynamicPathConfig) Error() string { +func (e ErrDynamicPathConfig) Error() string { return fmt.Sprintf("%s cannot be used with WithDynamicBasePath. Use dynamic path logic in your router.", e.Method) }vendor/github.com/mark3labs/mcp-go/util/logger.go (1)
15-15: Documentation mismatch with function name.The comment refers to "DefaultStdLogger" but the function is named "DefaultLogger". Since this is vendored code, consider reporting this upstream to the mcp-go project.
📝 Suggested documentation fix
-// DefaultStdLogger implements Logger using the standard library's log.Logger. +// DefaultLogger implements Logger using the standard library's log.Logger. func DefaultLogger() Logger {vendor/github.com/wk8/go-ordered-map/v2/yaml.go (1)
48-50: Error message contains domain-specific term.The error message references "pipeline" which appears to be copied from a different context. A more generic message like
"expected YAML mapping, got %v"would be clearer. This is vendored code, so it would require an upstream fix.vendor/github.com/invopop/jsonschema/.golangci.yml (1)
8-24: Minor: Duplicate linter entry.
goconstis listed twice in the linters enable list (lines 12 and 22). This is harmless but indicates a copy-paste oversight. Since this is vendored configuration, no action needed unless updating upstream.pkg/mcp/server.go (1)
67-78: Rename parameter to avoid shadowing built-in.The parameter
capshadows Go's predeclaredcap()function. While this works, it's a code smell flagged by linters and can cause confusion.Suggested fix
-func (m *MCPServer) hasCapability(cap v2.Capability) bool { +func (m *MCPServer) hasCapability(capability v2.Capability) bool { if m.caps == nil { return false } for _, c := range m.caps.GetConnectorCapabilities() { - if c == cap { + if c == capability { return true } } return false }vendor/github.com/invopop/jsonschema/utils.go (1)
13-20: Documentation inconsistency: produces kebab-case, not snake_case.The function is named
ToSnakeCaseand the comment says "snake case using dashes," but snake_case conventionally uses underscores (some_string), while this implementation produces kebab-case with dashes (some-string). This is vendored code, so the naming inconsistency is from upstream.pkg/mcp/handlers.go (2)
581-592: Missing validation forpage_sizeinput.The page size is extracted from JSON (which decodes numbers as
float64) and directly cast touint32without validation. Negative values or extremely large values could produce unexpected results.♻️ Suggested fix with bounds checking
func getPageSize(req mcp.CallToolRequest) uint32 { args := req.GetArguments() if args == nil { return defaultPageSize } if ps, ok := args["page_size"]; ok { if psFloat, ok := ps.(float64); ok { + if psFloat <= 0 || psFloat > 1000 { + return defaultPageSize + } return uint32(psFloat) } } return defaultPageSize }
486-510: Missing pagination parameters forlist_ticket_schemas.Unlike other list handlers (
handleListResourceTypes,handleListResources, etc.), this handler doesn't acceptpage_sizeorpage_tokenparameters, yet the response includesnext_page_tokenandhas_morefields. This inconsistency prevents clients from paginating through results.♻️ Suggested fix to add pagination support
func (m *MCPServer) handleListTicketSchemas(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { - resp, err := m.connector.ListTicketSchemas(ctx, &v2.TicketsServiceListTicketSchemasRequest{}) + pageSize := getPageSize(req) + pageToken := getStringArg(req, "page_token") + + resp, err := m.connector.ListTicketSchemas(ctx, &v2.TicketsServiceListTicketSchemasRequest{ + PageSize: pageSize, + PageToken: pageToken, + }) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("failed to list ticket schemas: %v", err)), nil }pkg/mcp/convert.go (1)
16-19: Remove unused functions or add comments indicating future intent.The functions
protoToJSON,jsonToProto, andmapToProtoare not called anywhere in the codebase. Theunmarshalervariable is only used within these unused functions. Either remove them to keep the codebase clean or add a comment noting they are reserved for future use.vendor/github.com/mark3labs/mcp-go/mcp/tools.go (1)
709-748:NewToolWithRawSchema+ToolOptionincompatibility is easy to misuse
Nothing prevents callers from applyingToolOptions to a raw-schema tool; consider a runtime guard in commonToolOptions (no-op ifRawInputSchema != nil) or a separate type to make it harder to mix.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (82)
go.modpkg/cli/commands.gopkg/config/config.gopkg/mcp/convert.gopkg/mcp/handlers.gopkg/mcp/server.govendor/github.com/bahlo/generic-list-go/LICENSEvendor/github.com/bahlo/generic-list-go/README.mdvendor/github.com/bahlo/generic-list-go/list.govendor/github.com/buger/jsonparser/.gitignorevendor/github.com/buger/jsonparser/.travis.ymlvendor/github.com/buger/jsonparser/Dockerfilevendor/github.com/buger/jsonparser/LICENSEvendor/github.com/buger/jsonparser/Makefilevendor/github.com/buger/jsonparser/README.mdvendor/github.com/buger/jsonparser/bytes.govendor/github.com/buger/jsonparser/bytes_safe.govendor/github.com/buger/jsonparser/bytes_unsafe.govendor/github.com/buger/jsonparser/escape.govendor/github.com/buger/jsonparser/fuzz.govendor/github.com/buger/jsonparser/oss-fuzz-build.shvendor/github.com/buger/jsonparser/parser.govendor/github.com/invopop/jsonschema/.gitignorevendor/github.com/invopop/jsonschema/.golangci.ymlvendor/github.com/invopop/jsonschema/COPYINGvendor/github.com/invopop/jsonschema/README.mdvendor/github.com/invopop/jsonschema/id.govendor/github.com/invopop/jsonschema/reflect.govendor/github.com/invopop/jsonschema/reflect_comments.govendor/github.com/invopop/jsonschema/schema.govendor/github.com/invopop/jsonschema/utils.govendor/github.com/mailru/easyjson/LICENSEvendor/github.com/mailru/easyjson/buffer/pool.govendor/github.com/mailru/easyjson/jwriter/writer.govendor/github.com/mark3labs/mcp-go/LICENSEvendor/github.com/mark3labs/mcp-go/mcp/consts.govendor/github.com/mark3labs/mcp-go/mcp/errors.govendor/github.com/mark3labs/mcp-go/mcp/prompts.govendor/github.com/mark3labs/mcp-go/mcp/resources.govendor/github.com/mark3labs/mcp-go/mcp/tools.govendor/github.com/mark3labs/mcp-go/mcp/typed_tools.govendor/github.com/mark3labs/mcp-go/mcp/types.govendor/github.com/mark3labs/mcp-go/mcp/utils.govendor/github.com/mark3labs/mcp-go/server/constants.govendor/github.com/mark3labs/mcp-go/server/ctx.govendor/github.com/mark3labs/mcp-go/server/elicitation.govendor/github.com/mark3labs/mcp-go/server/errors.govendor/github.com/mark3labs/mcp-go/server/hooks.govendor/github.com/mark3labs/mcp-go/server/http_transport_options.govendor/github.com/mark3labs/mcp-go/server/inprocess_session.govendor/github.com/mark3labs/mcp-go/server/request_handler.govendor/github.com/mark3labs/mcp-go/server/roots.govendor/github.com/mark3labs/mcp-go/server/sampling.govendor/github.com/mark3labs/mcp-go/server/server.govendor/github.com/mark3labs/mcp-go/server/session.govendor/github.com/mark3labs/mcp-go/server/sse.govendor/github.com/mark3labs/mcp-go/server/stdio.govendor/github.com/mark3labs/mcp-go/server/streamable_http.govendor/github.com/mark3labs/mcp-go/util/logger.govendor/github.com/wk8/go-ordered-map/v2/.gitignorevendor/github.com/wk8/go-ordered-map/v2/.golangci.ymlvendor/github.com/wk8/go-ordered-map/v2/CHANGELOG.mdvendor/github.com/wk8/go-ordered-map/v2/LICENSEvendor/github.com/wk8/go-ordered-map/v2/Makefilevendor/github.com/wk8/go-ordered-map/v2/README.mdvendor/github.com/wk8/go-ordered-map/v2/json.govendor/github.com/wk8/go-ordered-map/v2/orderedmap.govendor/github.com/wk8/go-ordered-map/v2/yaml.govendor/github.com/yosida95/uritemplate/v3/LICENSEvendor/github.com/yosida95/uritemplate/v3/README.rstvendor/github.com/yosida95/uritemplate/v3/compile.govendor/github.com/yosida95/uritemplate/v3/equals.govendor/github.com/yosida95/uritemplate/v3/error.govendor/github.com/yosida95/uritemplate/v3/escape.govendor/github.com/yosida95/uritemplate/v3/expression.govendor/github.com/yosida95/uritemplate/v3/machine.govendor/github.com/yosida95/uritemplate/v3/match.govendor/github.com/yosida95/uritemplate/v3/parse.govendor/github.com/yosida95/uritemplate/v3/prog.govendor/github.com/yosida95/uritemplate/v3/uritemplate.govendor/github.com/yosida95/uritemplate/v3/value.govendor/modules.txt
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-06-02T21:28:25.367Z
Learnt from: MarcusGoldschmidt
Repo: ConductorOne/baton-sdk PR: 393
File: pkg/test/integration_wrapper.go:54-54
Timestamp: 2025-06-02T21:28:25.367Z
Learning: The `connectorbuilder.NewConnector` function in the baton-sdk already validates the connector parameter using a type switch and returns appropriate errors for nil or invalid connectors in the default case, so additional nil checks are not needed before calling this function.
Applied to files:
pkg/cli/commands.go
📚 Learning: 2025-06-02T21:28:25.367Z
Learnt from: MarcusGoldschmidt
Repo: ConductorOne/baton-sdk PR: 393
File: pkg/test/integration_wrapper.go:54-54
Timestamp: 2025-06-02T21:28:25.367Z
Learning: The `connectorbuilder.NewConnector` function in the baton-sdk already validates the connector parameter and returns appropriate errors for nil or invalid connectors, so additional nil checks are not needed before calling this function.
Applied to files:
pkg/cli/commands.go
📚 Learning: 2025-10-13T01:59:43.800Z
Learnt from: pquerna
Repo: ConductorOne/baton-sdk PR: 511
File: vendor/google.golang.org/grpc/health/server.go:115-133
Timestamp: 2025-10-13T01:59:43.800Z
Learning: Do not flag issues or suggest changes in vendored code (files under vendor/ directory). Vendored code is third-party dependencies that should not be modified locally. If issues exist in vendored code, they should be addressed upstream.
Applied to files:
vendor/github.com/wk8/go-ordered-map/v2/.gitignore
📚 Learning: 2025-10-24T20:32:19.985Z
Learnt from: kans
Repo: ConductorOne/baton-sdk PR: 531
File: pkg/session/json_session.go:38-42
Timestamp: 2025-10-24T20:32:19.985Z
Learning: In the baton-sdk repository, SetManyJSON and similar batch operations in pkg/session/json_session.go should not add early-return guards for empty inputs. The design preference is to let server-side validation errors (such as min_pairs:1) propagate rather than silently succeeding on the client side.
Applied to files:
vendor/github.com/mark3labs/mcp-go/server/streamable_http.go
🧬 Code graph analysis (35)
vendor/github.com/mark3labs/mcp-go/util/logger.go (1)
vendor/google.golang.org/grpc/rpc_util.go (1)
Errorf(973-975)
vendor/github.com/buger/jsonparser/escape.go (1)
vendor/github.com/buger/jsonparser/parser.go (1)
MalformedStringEscapeError(20-20)
pkg/cli/commands.go (3)
pkg/cli/cli.go (1)
MakeGenericConfiguration(42-60)pkg/field/decode_hooks.go (1)
FileUploadDecodeHook(48-66)vendor/github.com/mark3labs/mcp-go/server/server.go (1)
NewMCPServer(345-373)
vendor/github.com/mark3labs/mcp-go/server/roots.go (2)
vendor/github.com/mark3labs/mcp-go/mcp/types.go (2)
ListRootsRequest(1155-1157)ListRootsResult(1162-1165)vendor/github.com/mark3labs/mcp-go/server/session.go (2)
ClientSessionFromContext(112-117)SessionWithRoots(86-90)
vendor/github.com/yosida95/uritemplate/v3/equals.go (1)
vendor/github.com/yosida95/uritemplate/v3/uritemplate.go (1)
Template(29-38)
vendor/github.com/buger/jsonparser/bytes_safe.go (2)
vendor/github.com/buger/jsonparser/parser.go (1)
ParseFloat(1265-1271)vendor/github.com/buger/jsonparser/bytes_unsafe.go (1)
StringToBytes(35-44)
vendor/github.com/buger/jsonparser/oss-fuzz-build.sh (1)
vendor/github.com/buger/jsonparser/fuzz.go (14)
FuzzParseString(3-9)FuzzEachKey(11-28)FuzzDelete(30-33)FuzzSet(35-41)FuzzObjectEach(43-48)FuzzParseFloat(50-56)FuzzParseInt(58-64)FuzzParseBool(66-72)FuzzTokenStart(74-77)FuzzGetString(79-85)FuzzGetFloat(87-93)FuzzGetInt(95-101)FuzzGetBoolean(103-109)FuzzGetUnsafeString(111-117)
vendor/github.com/mark3labs/mcp-go/server/elicitation.go (3)
vendor/github.com/mark3labs/mcp-go/server/server.go (1)
MCPServer(142-169)vendor/github.com/mark3labs/mcp-go/mcp/types.go (2)
ElicitationRequest(857-860)ElicitationResult(871-874)vendor/github.com/mark3labs/mcp-go/server/session.go (2)
ClientSessionFromContext(112-117)SessionWithElicitation(79-83)
vendor/github.com/mark3labs/mcp-go/server/request_handler.go (4)
vendor/github.com/mark3labs/mcp-go/server/server.go (1)
UnparsableMessageError(91-95)vendor/github.com/mark3labs/mcp-go/mcp/types.go (9)
JSONRPCMessage(109-109)MCPMethod(15-15)PARSE_ERROR(378-378)JSONRPC_VERSION(122-122)MethodInitialize(20-20)MethodPing(24-24)MethodSetLogLevel(56-56)METHOD_NOT_FOUND(384-384)MethodResourcesList(28-28)vendor/google.golang.org/grpc/rpc_util.go (1)
Errorf(973-975)vendor/github.com/mark3labs/mcp-go/server/errors.go (1)
ErrUnsupported(10-10)
vendor/github.com/wk8/go-ordered-map/v2/json.go (3)
vendor/github.com/wk8/go-ordered-map/v2/orderedmap.go (1)
OrderedMap(23-26)vendor/github.com/mailru/easyjson/jwriter/writer.go (1)
Writer(22-28)vendor/github.com/buger/jsonparser/parser.go (3)
String(561-561)ObjectEach(1054-1158)ValueType(557-557)
pkg/mcp/server.go (4)
pkg/types/types.go (1)
ConnectorServer(11-27)vendor/github.com/mark3labs/mcp-go/server/server.go (2)
MCPServer(142-169)NewMCPServer(345-373)vendor/github.com/mark3labs/mcp-go/server/stdio.go (1)
ServeStdio(857-877)vendor/github.com/mark3labs/mcp-go/mcp/tools.go (6)
NewTool(709-731)WithDescription(752-756)WithNumber(1054-1072)Description(900-904)WithString(1076-1094)Required(908-912)
vendor/github.com/buger/jsonparser/bytes_unsafe.go (2)
vendor/github.com/buger/jsonparser/parser.go (1)
ParseFloat(1265-1271)vendor/github.com/buger/jsonparser/bytes_safe.go (1)
StringToBytes(23-25)
vendor/github.com/mark3labs/mcp-go/mcp/typed_tools.go (2)
vendor/github.com/mark3labs/mcp-go/mcp/tools.go (2)
CallToolRequest(54-58)CallToolResult(40-51)vendor/github.com/mark3labs/mcp-go/mcp/utils.go (2)
NewToolResultError(393-403)NewToolResultStructuredOnly(317-336)
vendor/github.com/yosida95/uritemplate/v3/parse.go (1)
vendor/github.com/yosida95/uritemplate/v3/uritemplate.go (1)
Template(29-38)
vendor/github.com/yosida95/uritemplate/v3/expression.go (2)
vendor/github.com/yosida95/uritemplate/v3/value.go (1)
Values(15-15)vendor/github.com/buger/jsonparser/parser.go (1)
Get(936-939)
vendor/github.com/yosida95/uritemplate/v3/compile.go (1)
vendor/github.com/yosida95/uritemplate/v3/uritemplate.go (1)
Template(29-38)
vendor/github.com/invopop/jsonschema/schema.go (2)
vendor/github.com/invopop/jsonschema/id.go (1)
ID(12-12)vendor/github.com/wk8/go-ordered-map/v2/orderedmap.go (1)
OrderedMap(23-26)
vendor/github.com/invopop/jsonschema/reflect_comments.go (1)
vendor/github.com/invopop/jsonschema/reflect.go (1)
Reflector(73-171)
vendor/github.com/mark3labs/mcp-go/mcp/errors.go (2)
vendor/github.com/mark3labs/mcp-go/mcp/types.go (8)
JSONRPCErrorDetails(364-373)PARSE_ERROR(378-378)INVALID_REQUEST(381-381)METHOD_NOT_FOUND(384-384)INVALID_PARAMS(387-387)INTERNAL_ERROR(390-390)REQUEST_INTERRUPTED(393-393)RESOURCE_NOT_FOUND(399-399)vendor/github.com/mark3labs/mcp-go/server/errors.go (1)
ErrResourceNotFound(11-11)
pkg/config/config.go (2)
pkg/cli/cli.go (1)
AddCommand(73-84)pkg/cli/commands.go (1)
MakeMCPServerCommand(603-669)
vendor/github.com/wk8/go-ordered-map/v2/yaml.go (1)
vendor/github.com/wk8/go-ordered-map/v2/orderedmap.go (1)
OrderedMap(23-26)
vendor/github.com/mark3labs/mcp-go/server/sampling.go (3)
vendor/github.com/mark3labs/mcp-go/mcp/types.go (2)
CreateMessageRequest(908-911)CreateMessageResult(928-935)vendor/github.com/mark3labs/mcp-go/server/session.go (2)
ClientSessionFromContext(112-117)ClientSession(12-21)vendor/github.com/mark3labs/mcp-go/server/inprocess_session.go (1)
SamplingHandler(14-16)
vendor/github.com/yosida95/uritemplate/v3/uritemplate.go (1)
vendor/github.com/yosida95/uritemplate/v3/value.go (2)
Values(15-15)String(191-196)
vendor/github.com/yosida95/uritemplate/v3/error.go (1)
vendor/google.golang.org/grpc/rpc_util.go (1)
Errorf(973-975)
vendor/github.com/mark3labs/mcp-go/mcp/prompts.go (2)
vendor/github.com/mark3labs/mcp-go/mcp/types.go (8)
PaginatedRequest(572-575)PaginatedResult(583-589)Request(179-182)Params(188-188)Result(257-261)Meta(132-144)Content(965-967)Notification(190-193)vendor/github.com/mark3labs/mcp-go/mcp/tools.go (2)
Description(900-904)Required(908-912)
vendor/github.com/buger/jsonparser/fuzz.go (1)
vendor/github.com/buger/jsonparser/parser.go (13)
ParseString(1255-1262)ValueType(557-557)Delete(698-774)Set(785-856)ObjectEach(1054-1158)ParseFloat(1265-1271)ParseInt(1274-1283)ParseBoolean(1243-1252)GetString(1173-1190)GetFloat(1195-1207)GetInt(1211-1223)GetBoolean(1228-1240)GetUnsafeString(1161-1169)
vendor/github.com/mailru/easyjson/buffer/pool.go (1)
vendor/github.com/mailru/easyjson/jwriter/writer.go (1)
Writer(22-28)
vendor/github.com/buger/jsonparser/parser.go (2)
vendor/github.com/buger/jsonparser/escape.go (1)
Unescape(130-173)vendor/github.com/buger/jsonparser/bytes_safe.go (1)
StringToBytes(23-25)
vendor/github.com/mailru/easyjson/jwriter/writer.go (1)
vendor/github.com/mailru/easyjson/buffer/pool.go (1)
Buffer(68-75)
vendor/github.com/mark3labs/mcp-go/server/inprocess_session.go (2)
vendor/github.com/mark3labs/mcp-go/mcp/types.go (10)
CreateMessageRequest(908-911)CreateMessageResult(928-935)ElicitationRequest(857-860)ElicitationResult(871-874)ListRootsRequest(1155-1157)ListRootsResult(1162-1165)JSONRPCNotification(343-346)Implementation(531-535)ClientCapabilities(482-494)LoggingLevel(820-820)vendor/github.com/mark3labs/mcp-go/server/session.go (5)
ClientSession(12-21)SessionWithLogging(24-30)SessionWithClientInfo(66-76)SessionWithElicitation(79-83)SessionWithRoots(86-90)
vendor/github.com/mark3labs/mcp-go/mcp/types.go (2)
vendor/github.com/mark3labs/mcp-go/mcp/prompts.go (1)
Role(81-81)vendor/github.com/mark3labs/mcp-go/mcp/consts.go (5)
ContentTypeText(4-4)ContentTypeImage(5-5)ContentTypeAudio(6-6)ContentTypeLink(7-7)ContentTypeResource(8-8)
vendor/github.com/mark3labs/mcp-go/server/sse.go (4)
vendor/github.com/mark3labs/mcp-go/mcp/types.go (7)
JSONRPCNotification(343-346)Request(179-182)LoggingLevelError(827-827)LoggingLevel(820-820)JSONRPCRequest(335-340)NewRequestId(270-272)INVALID_REQUEST(381-381)vendor/github.com/mark3labs/mcp-go/server/server.go (4)
ServerResource(67-70)ServerResourceTemplate(73-76)ServerTool(55-58)MCPServer(142-169)vendor/github.com/mark3labs/mcp-go/server/session.go (4)
ClientSession(12-21)SessionWithTools(33-41)SessionWithResources(44-52)SessionWithResourceTemplates(55-63)vendor/github.com/mark3labs/mcp-go/server/errors.go (1)
ErrDynamicPathConfig(30-32)
vendor/github.com/mark3labs/mcp-go/server/streamable_http.go (4)
vendor/github.com/mark3labs/mcp-go/mcp/types.go (13)
Request(179-182)MCPMethod(15-15)MethodInitialize(20-20)JSONRPCRequest(335-340)NewRequestId(270-272)MethodSamplingCreateMessage(901-901)Params(188-188)CreateMessageParams(913-922)MethodElicitationCreate(60-60)MethodListRoots(64-64)CreateMessageRequest(908-911)ListRootsRequest(1155-1157)Content(965-967)vendor/github.com/mark3labs/mcp-go/server/constants.go (1)
HeaderKeySessionID(5-5)vendor/github.com/mark3labs/mcp-go/server/session.go (8)
ClientSession(12-21)SessionWithTools(33-41)SessionWithResources(44-52)SessionWithResourceTemplates(55-63)SessionWithLogging(24-30)SessionWithStreamableHTTPConfig(93-106)SessionWithElicitation(79-83)SessionWithRoots(86-90)vendor/github.com/mark3labs/mcp-go/mcp/utils.go (1)
ParseContent(569-633)
vendor/github.com/invopop/jsonschema/reflect.go (3)
vendor/github.com/invopop/jsonschema/schema.go (3)
Schema(14-82)Definitions(94-94)Version(10-10)vendor/github.com/invopop/jsonschema/id.go (2)
ID(12-12)EmptyID(15-15)vendor/github.com/invopop/jsonschema/utils.go (2)
ToSnakeCase(16-20)NewProperties(24-26)
vendor/github.com/mark3labs/mcp-go/mcp/utils.go (4)
vendor/github.com/mark3labs/mcp-go/mcp/types.go (26)
ReadResourceResult(639-642)TextContent(971-978)TextContent(980-980)ImageContent(984-993)ImageContent(995-995)AudioContent(999-1008)AudioContent(1010-1010)EmbeddedResource(1032-1038)EmbeddedResource(1040-1040)TextResourceContents(752-763)TextResourceContents(765-765)BlobResourceContents(767-777)BlobResourceContents(779-779)RequestId(265-267)Result(257-261)JSONRPCResponse(349-353)ProgressToken(125-125)Content(965-967)ResourceContents(748-750)Resource(694-711)Cursor(128-128)PaginatedResult(583-589)ResourceTemplate(720-739)Annotations(943-956)Meta(132-144)NewMetaFromMap(167-177)vendor/github.com/mark3labs/mcp-go/mcp/prompts.go (7)
GetPromptResult(38-43)ListPromptsResult(16-19)Role(81-81)PromptMessage(92-95)Prompt(49-59)RoleUser(84-84)RoleAssistant(85-85)vendor/github.com/mark3labs/mcp-go/mcp/tools.go (3)
CallToolResult(40-51)Description(900-904)Tool(557-574)vendor/github.com/mark3labs/mcp-go/mcp/consts.go (5)
ContentTypeText(4-4)ContentTypeImage(5-5)ContentTypeAudio(6-6)ContentTypeLink(7-7)ContentTypeResource(8-8)
🪛 checkmake (0.2.2)
vendor/github.com/wk8/go-ordered-map/v2/Makefile
[warning] 30-30: Missing required phony target "clean"
(minphony)
vendor/github.com/buger/jsonparser/Makefile
[warning] 1-1: Missing required phony target "all"
(minphony)
[warning] 1-1: Missing required phony target "clean"
(minphony)
[warning] 1-1: Missing required phony target "test"
(minphony)
🪛 GitHub Check: go-lint
pkg/cli/commands.go
[failure] 29-29:
File is not properly formatted (goimports)
pkg/mcp/convert.go
[failure] 68-68:
func mapToProto is unused (unused)
[failure] 63-63:
func jsonToProto is unused (unused)
[failure] 38-38:
func protoToJSON is unused (unused)
[failure] 16-16:
var unmarshaler is unused (unused)
pkg/mcp/server.go
[failure] 68-68:
param cap has same name as predeclared identifier (predeclared)
🪛 Hadolint (2.14.0)
vendor/github.com/buger/jsonparser/Dockerfile
[error] 12-12: Use COPY instead of ADD for files and folders
(DL3020)
🪛 LanguageTool
vendor/github.com/buger/jsonparser/README.md
[grammar] ~7-~7: Use a hyphen to join words.
Context: ...or a project that relies on a lot of 3rd party APIs that can be unpredictable and...
(QB_NEW_EN_HYPHEN)
[grammar] ~8-~8: Ensure spelling is correct
Context: ...simplicity and prefer to avoid external dependecies. encoding/json requires you to know e...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[style] ~8-~8: To elevate your writing, try using a synonym here.
Context: ...ce{}` instead, it will be very slow and hard to manage. I investigated what's on the...
(HARD_TO)
[uncategorized] ~15-~15: The official name of this software platform is spelled with a capital “H”.
Context: ...extract the user's full name, number of github followers and avatar. ```go import "gi...
(GITHUB)
[style] ~99-~99: As an alternative to the over-used intensifier ‘really’, consider replacing this phrase.
Context: ...mail.com. ## Reference Library API is really simple. You just need the Get method to perf...
(EN_WEAK_ADJECTIVE)
[grammar] ~116-~116: Ensure spelling is correct
Context: ... specify path to JSON value (in case of quering nested structures). If no keys are prov...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[style] ~262-~262: To elevate your writing, try using a synonym here.
Context: ...(require some code generation). It's hard to fully comparejsonparserandeasy...
(HARD_TO)
[style] ~264-~264: Consider using a more formal and expressive alternative to ‘amazing’.
Context: ...nwhile keeping structs,easyjson` is an amazing choice. If you want to process dynamic ...
(AWESOME)
[grammar] ~264-~264: Ensure spelling is correct
Context: ...nt to process dynamic JSON, have memory constrains, or more control over your data you sho...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[style] ~319-~319: Possibly, ‘actually’ is redundant. Consider using “only”.
Context: ...ing/json and map[string]interface{} and actually only helpers for unstructured JSON, their pe...
(ADVERB_ONLY)
[style] ~340-~340: For a more polite and respectful tone, consider rephrasing with ‘please’.
Context: ...** | jsonparser now is a winner, but do not forget that it is way more lightweight parser ...
(DONT_FORGET)
[grammar] ~340-~340: Ensure spelling is correct
Context: ...it of unsafe package to reduce memory consuption (in theory it can lead to some unexpect...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[uncategorized] ~346-~346: The official name of this software platform is spelled with a capital “H”.
Context: ...eports and suggestions should go though Github Issues. ## Contributing 1. Fork it 2....
(GITHUB)
vendor/github.com/invopop/jsonschema/README.md
[style] ~14-~14: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...gth, maxLength, pattern, format, etc. - Supports simple string and numeric enums. - Supp...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~15-~15: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...orts simple string and numeric enums. - Supports custom property fields via the `jsonsch...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~20-~20: Consider a more concise word here.
Context: ...cally from the current Go package's URL in order to be unique, and can be disabled with the...
(IN_ORDER_TO_PREMIUM)
[style] ~125-~125: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ... tags has now been removed. If you feel very strongly about this, we've opened a discussion t...
(EN_WEAK_ADJECTIVE)
[grammar] ~136-~136: Use a hyphen to join words.
Context: ...dStruct If set to true, makes the top level struct not to reference itself in ...
(QB_NEW_EN_HYPHEN)
🪛 markdownlint-cli2 (0.18.1)
vendor/github.com/wk8/go-ordered-map/v2/CHANGELOG.md
3-3: Link and image reference definitions should be needed
Unused link or image reference definition: "comment"
(MD053, link-image-reference-definitions)
vendor/github.com/invopop/jsonschema/README.md
60-60: Hard tabs
Column: 1
(MD010, no-hard-tabs)
69-69: Hard tabs
Column: 1
(MD010, no-hard-tabs)
95-95: Bare URL used
(MD034, no-bare-urls)
112-112: Hard tabs
Column: 16
(MD010, no-hard-tabs)
167-167: Hard tabs
Column: 1
(MD010, no-hard-tabs)
181-181: Hard tabs
Column: 1
(MD010, no-hard-tabs)
182-182: Hard tabs
Column: 1
(MD010, no-hard-tabs)
183-183: Hard tabs
Column: 1
(MD010, no-hard-tabs)
184-184: Hard tabs
Column: 1
(MD010, no-hard-tabs)
189-189: Hard tabs
Column: 1
(MD010, no-hard-tabs)
190-190: Hard tabs
Column: 1
(MD010, no-hard-tabs)
191-191: Hard tabs
Column: 1
(MD010, no-hard-tabs)
192-192: Hard tabs
Column: 1
(MD010, no-hard-tabs)
193-193: Hard tabs
Column: 1
(MD010, no-hard-tabs)
194-194: Hard tabs
Column: 1
(MD010, no-hard-tabs)
195-195: Hard tabs
Column: 1
(MD010, no-hard-tabs)
196-196: Hard tabs
Column: 1
(MD010, no-hard-tabs)
197-197: Hard tabs
Column: 1
(MD010, no-hard-tabs)
198-198: Hard tabs
Column: 1
(MD010, no-hard-tabs)
199-199: Hard tabs
Column: 1
(MD010, no-hard-tabs)
200-200: Hard tabs
Column: 1
(MD010, no-hard-tabs)
246-246: Bare URL used
(MD034, no-bare-urls)
247-247: Bare URL used
(MD034, no-bare-urls)
248-248: Bare URL used
(MD034, no-bare-urls)
249-249: Bare URL used
(MD034, no-bare-urls)
250-250: Bare URL used
(MD034, no-bare-urls)
251-251: Bare URL used
(MD034, no-bare-urls)
252-252: Bare URL used
(MD034, no-bare-urls)
253-253: Bare URL used
(MD034, no-bare-urls)
254-254: Bare URL used
(MD034, no-bare-urls)
255-255: Bare URL used
(MD034, no-bare-urls)
257-257: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4
(MD001, heading-increment)
275-275: Bare URL used
(MD034, no-bare-urls)
300-300: Bare URL used
(MD034, no-bare-urls)
302-302: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
302-302: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
303-303: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
303-303: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
304-304: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
304-304: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
305-305: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
305-305: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
306-306: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
306-306: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
307-307: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
307-307: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
308-308: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
308-308: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
309-309: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
309-309: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
310-310: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
310-310: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
311-311: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
311-311: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
312-312: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
312-312: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
313-313: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
313-313: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
314-314: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
314-314: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
315-315: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
315-315: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
329-329: Bare URL used
(MD034, no-bare-urls)
331-331: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
331-331: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
332-332: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
332-332: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
333-333: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
333-333: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
334-334: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
334-334: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
335-335: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
335-335: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
336-336: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
336-336: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
337-337: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
337-337: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
338-338: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected leading pipe
(MD055, table-pipe-style)
338-338: Table pipe style
Expected: no_leading_or_trailing; Actual: leading_and_trailing; Unexpected trailing pipe
(MD055, table-pipe-style)
vendor/github.com/wk8/go-ordered-map/v2/README.md
39-39: Hard tabs
Column: 1
(MD010, no-hard-tabs)
41-41: Hard tabs
Column: 1
(MD010, no-hard-tabs)
45-45: Hard tabs
Column: 1
(MD010, no-hard-tabs)
47-47: Hard tabs
Column: 1
(MD010, no-hard-tabs)
48-48: Hard tabs
Column: 1
(MD010, no-hard-tabs)
49-49: Hard tabs
Column: 1
(MD010, no-hard-tabs)
51-51: Hard tabs
Column: 1
(MD010, no-hard-tabs)
52-52: Hard tabs
Column: 1
(MD010, no-hard-tabs)
54-54: Hard tabs
Column: 1
(MD010, no-hard-tabs)
55-55: Hard tabs
Column: 1
(MD010, no-hard-tabs)
56-56: Hard tabs
Column: 1
(MD010, no-hard-tabs)
57-57: Hard tabs
Column: 1
(MD010, no-hard-tabs)
58-58: Hard tabs
Column: 1
(MD010, no-hard-tabs)
59-59: Hard tabs
Column: 1
(MD010, no-hard-tabs)
60-60: Hard tabs
Column: 1
(MD010, no-hard-tabs)
62-62: Hard tabs
Column: 1
(MD010, no-hard-tabs)
63-63: Hard tabs
Column: 1
(MD010, no-hard-tabs)
64-64: Hard tabs
Column: 1
(MD010, no-hard-tabs)
65-65: Hard tabs
Column: 1
(MD010, no-hard-tabs)
66-66: Hard tabs
Column: 1
(MD010, no-hard-tabs)
67-67: Hard tabs
Column: 1
(MD010, no-hard-tabs)
68-68: Hard tabs
Column: 1
(MD010, no-hard-tabs)
69-69: Hard tabs
Column: 1
(MD010, no-hard-tabs)
70-70: Hard tabs
Column: 1
(MD010, no-hard-tabs)
71-71: Hard tabs
Column: 1
(MD010, no-hard-tabs)
72-72: Hard tabs
Column: 1
(MD010, no-hard-tabs)
80-80: Hard tabs
Column: 1
(MD010, no-hard-tabs)
84-84: Hard tabs
Column: 1
(MD010, no-hard-tabs)
86-86: Hard tabs
Column: 1
(MD010, no-hard-tabs)
87-87: Hard tabs
Column: 1
(MD010, no-hard-tabs)
89-89: Hard tabs
Column: 1
(MD010, no-hard-tabs)
90-90: Hard tabs
Column: 1
(MD010, no-hard-tabs)
91-91: Hard tabs
Column: 1
(MD010, no-hard-tabs)
92-92: Hard tabs
Column: 1
(MD010, no-hard-tabs)
93-93: Hard tabs
Column: 1
(MD010, no-hard-tabs)
95-95: Hard tabs
Column: 1
(MD010, no-hard-tabs)
96-96: Hard tabs
Column: 1
(MD010, no-hard-tabs)
97-97: Hard tabs
Column: 1
(MD010, no-hard-tabs)
98-98: Hard tabs
Column: 1
(MD010, no-hard-tabs)
99-99: Hard tabs
Column: 1
(MD010, no-hard-tabs)
111-111: Hard tabs
Column: 1
(MD010, no-hard-tabs)
112-112: Hard tabs
Column: 1
(MD010, no-hard-tabs)
113-113: Hard tabs
Column: 1
(MD010, no-hard-tabs)
114-114: Hard tabs
Column: 1
(MD010, no-hard-tabs)
115-115: Hard tabs
Column: 1
(MD010, no-hard-tabs)
116-116: Hard tabs
Column: 1
(MD010, no-hard-tabs)
117-117: Hard tabs
Column: 1
(MD010, no-hard-tabs)
118-118: Hard tabs
Column: 1
(MD010, no-hard-tabs)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: go-test (1.25.2, ubuntu-latest)
- GitHub Check: go-test (1.25.2, windows-latest)
| v1 "github.com/conductorone/baton-sdk/pb/c1/connector_wrapper/v1" | ||
| baton_v1 "github.com/conductorone/baton-sdk/pb/c1/connectorapi/baton/v1" | ||
| "github.com/conductorone/baton-sdk/pkg/connectorrunner" | ||
| mcpPkg "github.com/conductorone/baton-sdk/pkg/mcp" |
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.
Fix import formatting.
The static analysis tool flagged this line as improperly formatted per goimports standards.
Run goimports -w pkg/cli/commands.go to fix the formatting.
🧰 Tools
🪛 GitHub Check: go-lint
[failure] 29-29:
File is not properly formatted (goimports)
🤖 Prompt for AI Agents
In @pkg/cli/commands.go at line 29, The import line using the alias mcpPkg
("github.com/conductorone/baton-sdk/pkg/mcp") is improperly formatted per
goimports; fix it by running goimports to reformat the imports or manually
reorder/adjust the import block to match goimports style (ensure correct
grouping, spacing, and removal of any unused imports), e.g., run goimports -w on
the commands.go in the CLI package to apply the fix.
pkg/mcp/handlers.go
Outdated
| result := map[string]any{ | ||
| "valid": true, | ||
| "annotations": resp.GetAnnotations(), | ||
| } |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# First, let's find the file and understand its structure
cd pkg/mcp
ls -la
# Check the handlers.go file structure
echo "=== handlers.go overview ==="
wc -l handlers.go
head -50 handlers.go
# Search for GetAnnotations usage
echo ""
echo "=== GetAnnotations usage ==="
rg -n "GetAnnotations" --type=go handlers.go -C2Repository: ConductorOne/baton-sdk
Length of output: 2035
🏁 Script executed:
#!/bin/bash
# Let's search for the ConnectorServiceValidateResponse type definition
echo "=== Searching for ConnectorServiceValidateResponse ==="
rg -n "ConnectorServiceValidateResponse" --type=go -C3
# Also check what types are imported
echo ""
echo "=== Imports in handlers.go ==="
head -20 pkg/mcp/handlers.go | grep -A20 "^import"Repository: ConductorOne/baton-sdk
Length of output: 36711
🏁 Script executed:
#!/bin/bash
# Look for protoToMap and protoListToMaps to understand conversion patterns
echo "=== protoToMap and protoListToMaps definitions ==="
rg -n "protoToMap\|protoListToMaps" --type=go -A5
# Check how other handlers serialize protobuf values
echo ""
echo "=== Handler patterns in handlers.go ==="
rg -n "result := map\[string\]any" pkg/mcp/handlers.go -A3Repository: ConductorOne/baton-sdk
Length of output: 1348
🏁 Script executed:
#!/bin/bash
# Search for protoToMap definition
echo "=== protoToMap definition ==="
rg -n "func.*protoToMap" --type=go -A10
# Also check convert.go since handlers imports it
echo ""
echo "=== convert.go content ==="
cat pkg/mcp/convert.goRepository: ConductorOne/baton-sdk
Length of output: 2361
🏁 Script executed:
#!/bin/bash
# Look for how resourceTypes, resources, entitlements, grants are created
echo "=== Checking handleListResourceTypes ==="
sed -n '55,90p' pkg/mcp/handlers.go
echo ""
echo "=== Checking handleListResources ==="
sed -n '95,140p' pkg/mcp/handlers.go
echo ""
echo "=== Check if protoListToMaps is used ==="
rg -n "protoListToMaps" pkg/mcp/handlers.go -B2 -A2Repository: ConductorOne/baton-sdk
Length of output: 4113
Use protoListToMaps() to convert annotations for consistency.
The GetAnnotations() returns []*anypb.Any, a slice of protobuf messages. Other handlers consistently convert proto slices using protoListToMaps() (e.g., handleListResourceTypes, handleListResources, handleListEntitlements), but this handler places annotations directly in the result map. While json.Marshal() will serialize the protobuf messages, this bypasses the configured protojson.MarshalOptions and creates inconsistency with the rest of the codebase.
Replace line 44 with:
annotations, err := protoListToMaps(resp.GetAnnotations())
if err != nil {
return mcp.NewToolResultError(fmt.Sprintf("failed to serialize annotations: %v", err)), nil
}Then use annotations in the result map.
🤖 Prompt for AI Agents
In @pkg/mcp/handlers.go around lines 42 - 45, The annotations slice is being
placed directly into the result map instead of converting it with
protoListToMaps, causing inconsistent protojson handling; call
protoListToMaps(resp.GetAnnotations()) into a variable (annotations), check the
error and return mcp.NewToolResultError(fmt.Sprintf("failed to serialize
annotations: %v", err)), nil on failure, and then use annotations in the result
map instead of resp.GetAnnotations().
| type URITemplate struct { | ||
| *uritemplate.Template | ||
| } | ||
|
|
||
| func (t *URITemplate) MarshalJSON() ([]byte, error) { | ||
| return json.Marshal(t.Raw()) | ||
| } | ||
|
|
||
| func (t *URITemplate) UnmarshalJSON(data []byte) error { | ||
| var raw string | ||
| if err := json.Unmarshal(data, &raw); err != nil { | ||
| return err | ||
| } | ||
| template, err := uritemplate.New(raw) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| t.Template = template | ||
| return nil | ||
| } |
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.
URITemplate.MarshalJSON will panic if t.Template is nil
If a ResourceTemplate is constructed with URITemplate: &URITemplate{} (or nil Template), marshaling will panic. Guard nil.
Proposed fix
func (t *URITemplate) MarshalJSON() ([]byte, error) {
- return json.Marshal(t.Raw())
+ if t == nil || t.Template == nil {
+ return []byte("null"), nil
+ }
+ return json.Marshal(t.Raw())
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| type URITemplate struct { | |
| *uritemplate.Template | |
| } | |
| func (t *URITemplate) MarshalJSON() ([]byte, error) { | |
| return json.Marshal(t.Raw()) | |
| } | |
| func (t *URITemplate) UnmarshalJSON(data []byte) error { | |
| var raw string | |
| if err := json.Unmarshal(data, &raw); err != nil { | |
| return err | |
| } | |
| template, err := uritemplate.New(raw) | |
| if err != nil { | |
| return err | |
| } | |
| t.Template = template | |
| return nil | |
| } | |
| type URITemplate struct { | |
| *uritemplate.Template | |
| } | |
| func (t *URITemplate) MarshalJSON() ([]byte, error) { | |
| if t == nil || t.Template == nil { | |
| return []byte("null"), nil | |
| } | |
| return json.Marshal(t.Raw()) | |
| } | |
| func (t *URITemplate) UnmarshalJSON(data []byte) error { | |
| var raw string | |
| if err := json.Unmarshal(data, &raw); err != nil { | |
| return err | |
| } | |
| template, err := uritemplate.New(raw) | |
| if err != nil { | |
| return err | |
| } | |
| t.Template = template | |
| return nil | |
| } |
🤖 Prompt for AI Agents
In @vendor/github.com/mark3labs/mcp-go/mcp/types.go around lines 85 - 104,
MarshalJSON for URITemplate can panic when t or t.Template is nil; update
URITemplate.MarshalJSON to guard that case by checking if t == nil || t.Template
== nil and returning a safe JSON representation (for example json.Marshal("") or
json.Marshal(nil) per repo convention) instead of calling t.Raw(); modify only
the URITemplate.MarshalJSON implementation so it checks the nil condition and
returns the safe marshaled value when nil, otherwise continue to return
json.Marshal(t.Raw()).
| // UnmarshalJSON implements custom JSON unmarshaling | ||
| func (p *NotificationParams) UnmarshalJSON(data []byte) error { | ||
| // Create a map to hold all fields | ||
| var m map[string]any | ||
| if err := json.Unmarshal(data, &m); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Initialize maps if they're nil | ||
| if p.Meta == nil { | ||
| p.Meta = make(map[string]any) | ||
| } | ||
| if p.AdditionalFields == nil { | ||
| p.AdditionalFields = make(map[string]any) | ||
| } | ||
|
|
||
| // Process all fields | ||
| for k, v := range m { | ||
| if k == "_meta" { | ||
| // Handle Meta field | ||
| if meta, ok := v.(map[string]any); ok { | ||
| p.Meta = meta | ||
| } | ||
| } else { | ||
| // Handle additional fields | ||
| p.AdditionalFields[k] = v | ||
| } | ||
| } | ||
|
|
||
| return nil | ||
| } |
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.
NotificationParams round-trip may add _meta: {} unexpectedly
UnmarshalJSON initializes Meta even when absent; MarshalJSON then emits _meta. Consider leaving Meta as nil unless present in input.
🤖 Prompt for AI Agents
In @vendor/github.com/mark3labs/mcp-go/mcp/types.go around lines 225 - 255,
UnmarshalJSON in NotificationParams currently eagerly initializes p.Meta (and
p.AdditionalFields) causing MarshalJSON to emit an empty "_meta" even when input
omitted; modify UnmarshalJSON (in the NotificationParams type) to only set
p.Meta when the incoming map contains a "_meta" key and its value is a
map[string]any (leave p.Meta nil otherwise), and only initialize
p.AdditionalFields if there are actually other keys to store, so that absent
fields remain nil and are not marshaled back as empty objects.
| // UnmarshalContent implements custom JSON unmarshaling for Content interface | ||
| func UnmarshalContent(data []byte) (Content, error) { | ||
| var raw map[string]any | ||
| if err := json.Unmarshal(data, &raw); err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| contentType, ok := raw["type"].(string) | ||
| if !ok { | ||
| return nil, fmt.Errorf("missing or invalid type field") | ||
| } | ||
|
|
||
| switch contentType { | ||
| case ContentTypeText: | ||
| var content TextContent | ||
| err := json.Unmarshal(data, &content) | ||
| return content, err | ||
| case ContentTypeImage: | ||
| var content ImageContent | ||
| err := json.Unmarshal(data, &content) | ||
| return content, err | ||
| case ContentTypeAudio: | ||
| var content AudioContent | ||
| err := json.Unmarshal(data, &content) | ||
| return content, err | ||
| case ContentTypeLink: | ||
| var content ResourceLink | ||
| err := json.Unmarshal(data, &content) | ||
| return content, err | ||
| case ContentTypeResource: | ||
| var content EmbeddedResource | ||
| err := json.Unmarshal(data, &content) | ||
| return content, err | ||
| default: | ||
| return nil, fmt.Errorf("unknown content type: %s", contentType) | ||
| } | ||
| } |
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.
UnmarshalContent for EmbeddedResource likely fails (interface field)
EmbeddedResource.Resource is ResourceContents (interface). json.Unmarshal into EmbeddedResource will typically error when resource is an object. Parse resource into TextResourceContents/BlobResourceContents explicitly (similar to ParseResourceContents in mcp/utils.go).
| // Get or create session atomically to prevent TOCTOU races | ||
| // where concurrent GETs could both create and register duplicate sessions | ||
| var session *streamableHttpSession | ||
| newSession := newStreamableHttpSession(sessionID, s.sessionTools, s.sessionResources, s.sessionResourceTemplates, s.sessionLogLevels) | ||
| actual, loaded := s.activeSessions.LoadOrStore(sessionID, newSession) | ||
| session = actual.(*streamableHttpSession) | ||
|
|
||
| if !loaded { | ||
| // We created a new session, need to register it | ||
| if err := s.server.RegisterSession(r.Context(), session); err != nil { | ||
| s.activeSessions.Delete(sessionID) | ||
| http.Error(w, fmt.Sprintf("Session registration failed: %v", err), http.StatusBadRequest) | ||
| return | ||
| } | ||
| defer s.server.UnregisterSession(r.Context(), sessionID) | ||
| defer s.activeSessions.Delete(sessionID) | ||
| } | ||
|
|
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.
Multiple concurrent GETs for the same sessionID look unsafe
When loaded == true, this handler neither registers/unregisters nor deletes the session; if the original GET disconnects, its defers will unregister/delete, breaking this handler mid-stream. Either reject concurrent GET listeners per session (e.g., 409) or implement ref-counted lifecycle.
🤖 Prompt for AI Agents
In @vendor/github.com/mark3labs/mcp-go/server/streamable_http.go around lines
511 - 528, Concurrent GETs can race because when LoadOrStore returns
loaded==true the existing session may be unregistered/deleted by the original
handler’s deferred cleanup; to fix, detect loaded==true after
s.activeSessions.LoadOrStore(sessionID, newSession) and immediately reject the
second GET with HTTP 409 (Conflict) and a clear message (e.g., "session already
has an active listener"), avoiding registering or deferring deletion for the
duplicate; reference newStreamableHttpSession, s.activeSessions.LoadOrStore,
RegisterSession and UnregisterSession to locate the change.
| // Set the client context before handling the message | ||
| w.Header().Set("Content-Type", "text/event-stream") | ||
| w.Header().Set("Cache-Control", "no-cache") | ||
| w.Header().Set("Connection", "keep-alive") | ||
| w.WriteHeader(http.StatusOK) | ||
|
|
||
| flusher, ok := w.(http.Flusher) | ||
| if !ok { | ||
| http.Error(w, "Streaming unsupported", http.StatusInternalServerError) | ||
| return | ||
| } | ||
| flusher.Flush() | ||
|
|
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.
Check http.Flusher before WriteHeader in GET handler
You send 200 OK before verifying streaming support; if Flusher is missing you can’t reliably return an error.
Proposed fix
- w.Header().Set("Content-Type", "text/event-stream")
- w.Header().Set("Cache-Control", "no-cache")
- w.Header().Set("Connection", "keep-alive")
- w.WriteHeader(http.StatusOK)
-
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported", http.StatusInternalServerError)
return
}
+ w.Header().Set("Content-Type", "text/event-stream")
+ w.Header().Set("Cache-Control", "no-cache")
+ w.Header().Set("Connection", "keep-alive")
+ w.WriteHeader(http.StatusOK)
flusher.Flush()🤖 Prompt for AI Agents
In @vendor/github.com/mark3labs/mcp-go/server/streamable_http.go around lines
529 - 541, In the GET handler, verify the ResponseWriter implements http.Flusher
before calling w.WriteHeader and sending the 200 OK; move the flusher check
(flusher, ok := w.(http.Flusher)) and the error path (http.Error(...)) to occur
immediately after setting headers (Content-Type/Cache-Control/Connection) but
before w.WriteHeader(http.StatusOK), and only call w.WriteHeader and
flusher.Flush() after confirming ok; update the handler code paths that
reference the flusher variable (flusher.Flush()) so they run only when ok is
true.
| func (s *StreamableHTTPServer) handleDelete(w http.ResponseWriter, r *http.Request) { | ||
| // delete request terminate the session | ||
| sessionID := r.Header.Get(HeaderKeySessionID) | ||
| sessionIdManager := s.sessionIdManagerResolver.ResolveSessionIdManager(r) | ||
| notAllowed, err := sessionIdManager.Terminate(sessionID) | ||
| if err != nil { | ||
| http.Error(w, fmt.Sprintf("Session termination failed: %v", err), http.StatusInternalServerError) | ||
| return | ||
| } | ||
| if notAllowed { | ||
| http.Error(w, "Session termination not allowed", http.StatusMethodNotAllowed) | ||
| return | ||
| } | ||
|
|
||
| // remove the session relateddata from the sessionToolsStore | ||
| s.sessionTools.delete(sessionID) | ||
| s.sessionResources.delete(sessionID) | ||
| s.sessionResourceTemplates.delete(sessionID) | ||
| s.sessionLogLevels.delete(sessionID) | ||
| // remove current session's requstID information | ||
| s.sessionRequestIDs.Delete(sessionID) | ||
|
|
||
| w.WriteHeader(http.StatusOK) | ||
| } |
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.
DELETE doesn’t unregister sessions / clear activeSessions
handleDelete clears per-session stores but leaves activeSessions and s.server.sessions untouched, so notifications can keep targeting a “terminated” session and memory can leak.
Sketch fix
func (s *StreamableHTTPServer) handleDelete(w http.ResponseWriter, r *http.Request) {
...
s.sessionRequestIDs.Delete(sessionID)
+
+ if sessionID != "" {
+ // Best-effort cleanup of registered/persistent session
+ s.activeSessions.Delete(sessionID)
+ s.server.UnregisterSession(r.Context(), sessionID)
+ }
w.WriteHeader(http.StatusOK)
}🤖 Prompt for AI Agents
In @vendor/github.com/mark3labs/mcp-go/server/streamable_http.go around lines
654 - 677, handleDelete currently deletes per-session stores but never removes
the session from s.activeSessions nor from s.server.sessions, leaving
notifications and memory leaks; after the existing deletes and before
responding, remove the session entry from s.activeSessions and also
unregister/remove it from s.server.sessions (or call the server-side unregister
method if one exists) while honoring any server-side session lock/guard (use the
server's mutex or UnregisterSession helper if present) so the session is fully
deregistered and will no longer receive notifications.
| func (s *streamableHttpSession) Initialize() { | ||
| // do nothing | ||
| // the session is ephemeral, no real initialized action needed | ||
| } | ||
|
|
||
| func (s *streamableHttpSession) Initialized() bool { | ||
| // the session is ephemeral, no real initialized action needed | ||
| return true | ||
| } |
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.
streamableHttpSession.Initialized() always true breaks session-state checks
This makes server methods that require initialization (e.g., logging/setLevel gate in server/server.go) effectively always allowed for HTTP sessions, including before initialize. Track an initialized flag and set it in Initialize().
Proposed fix
type streamableHttpSession struct {
sessionID string
+ initialized atomic.Bool
notificationChannel chan mcp.JSONRPCNotification
...
}
func (s *streamableHttpSession) Initialize() {
- // do nothing
- // the session is ephemeral, no real initialized action needed
+ s.initialized.Store(true)
}
func (s *streamableHttpSession) Initialized() bool {
- // the session is ephemeral, no real initialized action needed
- return true
+ return s.initialized.Load()
}🤖 Prompt for AI Agents
In @vendor/github.com/mark3labs/mcp-go/server/streamable_http.go around lines
1024 - 1032, streamableHttpSession.Initialized() always returns true; add an
internal initialized flag on the streamableHttpSession struct (e.g., initialized
bool) defaulting to false, set that flag to true inside
streamableHttpSession.Initialize(), and have streamableHttpSession.Initialized()
return the flag instead of true; if session methods may be called concurrently,
protect the flag with a mutex or use atomic operations when setting/reading it
to avoid race conditions.
| func pctEncode(w *strings.Builder, r rune) { | ||
| if s := r >> 24 & 0xff; s > 0 { | ||
| w.Write([]byte{'%', hex[s/16], hex[s%16]}) | ||
| } | ||
| if s := r >> 16 & 0xff; s > 0 { | ||
| w.Write([]byte{'%', hex[s/16], hex[s%16]}) | ||
| } | ||
| if s := r >> 8 & 0xff; s > 0 { | ||
| w.Write([]byte{'%', hex[s/16], hex[s%16]}) | ||
| } | ||
| if s := r & 0xff; s > 0 { | ||
| w.Write([]byte{'%', hex[s/16], hex[s%16]}) | ||
| } | ||
| } |
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.
🧩 Analysis chain
🌐 Web query:
RFC 6570 URI template percent encoding specification
💡 Result:
Key points from RFC 6570 (URI Template) about percent-encoding:
- Unreserved characters (ALPHA / DIGIT / "-" / "." / "_" / "~") may appear unencoded in expansions; other characters must be percent-encoded unless the operator allows reserved chars. [1]. (rfc-editor.org)
- The "+" (reserved) and "#" (fragment) operators allow the union of unreserved, reserved, and pct-encoded characters to be passed through without pct-encoding; other operators allow only unreserved characters unencoded (so reserved chars are pct-encoded). [1]. (rfc-editor.org)
- The percent character "%" is only permitted as part of a valid pct-encoded triplet; for expression types other than "+" and "#", a literal "%" in a value MUST be pct-encoded as "%25". [1]. (rfc-editor.org)
- RFC 3986 defines the reserved vs. unreserved character sets used by RFC 6570; implementations should follow RFC 3986 for which chars must be pct-encoded. [2]. (ietf.org)
Sources: RFC 6570 (URI Template) and RFC 3986 (URI Generic Syntax). [1][2]. (rfc-editor.org)
Citations:
- 1: https://www.rfc-editor.org/rfc/rfc6570.html?utm_source=openai
- 2: https://www.rfc-editor.org/rfc/rfc6570.html?utm_source=openai
- 3: https://www.rfc-editor.org/rfc/rfc6570.html?utm_source=openai
- 4: https://www.ietf.org/rfc/rfc3986.html?utm_source=openai
- 5: https://www.rfc-editor.org/rfc/rfc6570.html?utm_source=openai
🏁 Script executed:
# First, let me examine the actual vendored file to understand the context better
cat -n vendor/github.com/yosida95/uritemplate/v3/escape.go | head -100Repository: ConductorOne/baton-sdk
Length of output: 3361
Fix percent-encoding to handle UTF-8 bytes, not Unicode code points.
The pctEncode function encodes a rune's numeric value byte-by-byte rather than its UTF-8 representation, violating RFC 6570 Section 3.3 and RFC 3986. Non-ASCII characters like 'é' (U+00E9) incorrectly encode as %E9 instead of the UTF-8 percent-encoding %C3%A9.
RFC 6570 requires that non-ASCII characters be UTF-8 encoded first, then percent-encoded as octets. The function must be updated to encode the UTF-8 byte representation of the rune, not its numeric value.
🤖 Prompt for AI Agents
In @vendor/github.com/yosida95/uritemplate/v3/escape.go around lines 80 - 93,
The pctEncode function currently splits the rune's numeric value into 4 bytes
instead of percent-encoding the rune's UTF-8 octets; update pctEncode to first
UTF-8 encode the rune (use utf8.EncodeRune or equivalent to get the byte
sequence) and then iterate over the produced bytes, writing each byte as "%"+two
hex digits to the provided strings.Builder (using the existing hex lookup),
ensuring you encode exactly the UTF-8 length returned rather than fixed 4-byte
components.
Replace the community MCP SDK with the official modelcontextprotocol/go-sdk. This provides: - Typed input/output structs with jsonschema tags for tool definitions - Cleaner handler signatures: func(ctx, req, Input) (Result, Output, error) - Official protocol support Updated all handlers to use typed structs instead of manual argument parsing.
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.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@pkg/mcp/handlers.go`:
- Around line 167-191: The int->uint32 conversion for PageSize in
handleListResourceTypes (and the same pattern in handleListResources,
handleListEntitlements, handleListGrants) can overflow when input.PageSize >
math.MaxUint32; add a small helper (e.g., safePageSize(size int, defaultSize
uint32) uint32) that returns defaultSize for <=0, clamps values > math.MaxUint32
to math.MaxUint32, otherwise casts to uint32, import math, and replace the
direct conversion in each handler to use safePageSize(input.PageSize,
defaultPageSize).
In `@vendor/github.com/google/jsonschema-go/jsonschema/infer.go`:
- Around line 152-153: The empty if block `if t.Key().Kind() != reflect.String {
}` in infer.go is dead code and should be removed; locate the check around the
use of `t.Key().Kind()` (same area where `reflect.String` is already validated)
and delete the redundant empty conditional, or alternatively raise an issue with
upstream `google/jsonschema-go` if you intend to keep the fork but not modify
behavior.
In `@vendor/github.com/modelcontextprotocol/go-sdk/mcp/logging.go`:
- Around line 183-206: The buffer bytes are read outside the mutex
(h.buf.Bytes()) causing races when clones created via WithAttrs/WithGroup call
Handle concurrently; fix by capturing a safe copy of the buffer while holding
h.mu (e.g., lock h.mu, call h.buf.Bytes(), make a new byte slice copy, then
unlock) and use that copy when constructing LoggingMessageParams.Data before
calling h.ss.Log(ctx, params); ensure the read and reset interactions around
h.buf are all protected by h.mu to prevent interleaving/corruption.
In `@vendor/modules.txt`:
- Around line 560-561: The oauth2 module is pinned at golang.org/x/oauth2
v0.30.0; update it to v0.34.0 by changing the module requirement to v0.34.0 and
regenerating modules (e.g., run `go get golang.org/x/oauth2@v0.34.0` or edit
go.mod to require v0.34.0 and run `go mod tidy` / `go mod vendor`) so
vendor/modules.txt and the build reflect the new version.
♻️ Duplicate comments (2)
pkg/cli/commands.go (1)
29-29: Import formatting issue already flagged.pkg/mcp/handlers.go (1)
155-165: UseprotoListToMaps()to convert annotations for consistency.The
GetAnnotations()returns[]*anypb.Any. Other handlers convert proto slices usingprotoListToMaps(), but this handler places annotations directly in the result. This bypasses the configuredprotojson.MarshalOptionsand creates inconsistency.
🧹 Nitpick comments (7)
pkg/mcp/server.go (2)
68-78: Rename parametercapto avoid shadowing the predeclaredcapidentifier.The parameter name
capshadows Go's built-incap()function. While this doesn't cause a bug here, it's flagged by linters and can cause confusion.♻️ Suggested fix
-func (m *MCPServer) hasCapability(cap v2.Capability) bool { +func (m *MCPServer) hasCapability(capability v2.Capability) bool { if m.caps == nil { return false } for _, c := range m.caps.GetConnectorCapabilities() { - if c == cap { + if c == capability { return true } } return false }
28-34: Consider making the version configurable or deriving it from build info.The version
"1.0.0"is hardcoded. For a prototype this is acceptable, but for production you may want to derive this from build-time variables or pass it as a parameter.vendor/github.com/modelcontextprotocol/go-sdk/mcp/resource.go (1)
158-163: Template parse errors are silently swallowed.The
Matchesmethod returnsfalsewhen the URI template fails to parse. This is a reasonable default for a matching function but could mask configuration errors in resource templates.Consider whether template validation should happen earlier (e.g., at registration time) to surface invalid templates promptly.
vendor/github.com/modelcontextprotocol/go-sdk/mcp/sse.go (2)
164-178: Connect() lacks synchronization for double-connect prevention.The check
if t.incoming != nil(Line 165) is not protected by a mutex. While the documentation states each transport connects at most once, concurrent calls toConnect()could race past this check.Consider adding mutex protection
func (t *SSEServerTransport) Connect(context.Context) (Connection, error) { + t.mu.Lock() if t.incoming != nil { + t.mu.Unlock() return nil, fmt.Errorf("already connected") } t.incoming = make(chan jsonrpc.Message, 100) t.done = make(chan struct{}) + t.mu.Unlock() _, err := writeEvent(t.Response, Event{
433-443: Redundant isDone() check after select.The
isDone()check at Line 435 appears redundant sincec.doneis already handled in theselectstatement above. The TODO comment indicates the author is uncertain about this as well.This is defensive coding and harmless, but could be simplified.
vendor/github.com/modelcontextprotocol/go-sdk/mcp/content.go (2)
52-58: Comment about "base64-encoded" may be misleading.The comment states
Data []byte // base64-encoded, but the field contains raw bytes. The base64 encoding happens automatically during JSON marshaling. Consumers reading this comment might incorrectly pre-encode data.This is a documentation clarity issue in the vendored SDK.
91-105: Inconsistent receiver type for MarshalJSON.
AudioContent.MarshalJSONuses a value receiver(c AudioContent)while other content types use pointer receivers(c *TextContent),(c *ImageContent), etc. This works correctly but creates style inconsistency.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (66)
go.modpkg/cli/commands.gopkg/mcp/handlers.gopkg/mcp/server.govendor/github.com/google/jsonschema-go/LICENSEvendor/github.com/google/jsonschema-go/jsonschema/annotations.govendor/github.com/google/jsonschema-go/jsonschema/doc.govendor/github.com/google/jsonschema-go/jsonschema/infer.govendor/github.com/google/jsonschema-go/jsonschema/json_pointer.govendor/github.com/google/jsonschema-go/jsonschema/resolve.govendor/github.com/google/jsonschema-go/jsonschema/schema.govendor/github.com/google/jsonschema-go/jsonschema/util.govendor/github.com/google/jsonschema-go/jsonschema/validate.govendor/github.com/modelcontextprotocol/go-sdk/LICENSEvendor/github.com/modelcontextprotocol/go-sdk/auth/auth.govendor/github.com/modelcontextprotocol/go-sdk/auth/client.govendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/conn.govendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/frame.govendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/jsonrpc2.govendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/messages.govendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/net.govendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/serve.govendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/wire.govendor/github.com/modelcontextprotocol/go-sdk/internal/util/util.govendor/github.com/modelcontextprotocol/go-sdk/internal/xcontext/xcontext.govendor/github.com/modelcontextprotocol/go-sdk/jsonrpc/jsonrpc.govendor/github.com/modelcontextprotocol/go-sdk/mcp/client.govendor/github.com/modelcontextprotocol/go-sdk/mcp/cmd.govendor/github.com/modelcontextprotocol/go-sdk/mcp/content.govendor/github.com/modelcontextprotocol/go-sdk/mcp/event.govendor/github.com/modelcontextprotocol/go-sdk/mcp/features.govendor/github.com/modelcontextprotocol/go-sdk/mcp/logging.govendor/github.com/modelcontextprotocol/go-sdk/mcp/mcp.govendor/github.com/modelcontextprotocol/go-sdk/mcp/prompt.govendor/github.com/modelcontextprotocol/go-sdk/mcp/protocol.govendor/github.com/modelcontextprotocol/go-sdk/mcp/requests.govendor/github.com/modelcontextprotocol/go-sdk/mcp/resource.govendor/github.com/modelcontextprotocol/go-sdk/mcp/resource_go124.govendor/github.com/modelcontextprotocol/go-sdk/mcp/resource_pre_go124.govendor/github.com/modelcontextprotocol/go-sdk/mcp/server.govendor/github.com/modelcontextprotocol/go-sdk/mcp/session.govendor/github.com/modelcontextprotocol/go-sdk/mcp/shared.govendor/github.com/modelcontextprotocol/go-sdk/mcp/sse.govendor/github.com/modelcontextprotocol/go-sdk/mcp/streamable.govendor/github.com/modelcontextprotocol/go-sdk/mcp/streamable_client.govendor/github.com/modelcontextprotocol/go-sdk/mcp/streamable_server.govendor/github.com/modelcontextprotocol/go-sdk/mcp/tool.govendor/github.com/modelcontextprotocol/go-sdk/mcp/transport.govendor/github.com/modelcontextprotocol/go-sdk/mcp/util.govendor/github.com/modelcontextprotocol/go-sdk/oauthex/auth_meta.govendor/github.com/modelcontextprotocol/go-sdk/oauthex/dcr.govendor/github.com/modelcontextprotocol/go-sdk/oauthex/oauth2.govendor/github.com/modelcontextprotocol/go-sdk/oauthex/oauthex.govendor/github.com/modelcontextprotocol/go-sdk/oauthex/resource_meta.govendor/golang.org/x/oauth2/clientcredentials/clientcredentials.govendor/golang.org/x/oauth2/internal/doc.govendor/golang.org/x/oauth2/internal/oauth2.govendor/golang.org/x/oauth2/internal/token.govendor/golang.org/x/oauth2/internal/transport.govendor/golang.org/x/oauth2/jws/jws.govendor/golang.org/x/oauth2/jwt/jwt.govendor/golang.org/x/oauth2/oauth2.govendor/golang.org/x/oauth2/pkce.govendor/golang.org/x/oauth2/token.govendor/golang.org/x/oauth2/transport.govendor/modules.txt
✅ Files skipped from review due to trivial changes (8)
- vendor/github.com/google/jsonschema-go/LICENSE
- vendor/github.com/modelcontextprotocol/go-sdk/mcp/util.go
- vendor/github.com/modelcontextprotocol/go-sdk/LICENSE
- vendor/github.com/google/jsonschema-go/jsonschema/doc.go
- vendor/golang.org/x/oauth2/pkce.go
- vendor/github.com/modelcontextprotocol/go-sdk/mcp/streamable_server.go
- vendor/github.com/modelcontextprotocol/go-sdk/oauthex/oauthex.go
- vendor/github.com/modelcontextprotocol/go-sdk/mcp/mcp.go
🚧 Files skipped from review as they are similar to previous changes (1)
- go.mod
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-01-30T19:29:21.573Z
Learnt from: ggreer
Repo: ConductorOne/baton-sdk PR: 295
File: pkg/crypto/providers/jwk/jwk_test.go:0-0
Timestamp: 2025-01-30T19:29:21.573Z
Learning: JWKEncryptionProvider in pkg/crypto/providers/jwk does not support symmetric keys, it only works with asymmetric keys.
Applied to files:
vendor/golang.org/x/oauth2/jws/jws.go
📚 Learning: 2025-06-02T21:28:25.367Z
Learnt from: MarcusGoldschmidt
Repo: ConductorOne/baton-sdk PR: 393
File: pkg/test/integration_wrapper.go:54-54
Timestamp: 2025-06-02T21:28:25.367Z
Learning: The `connectorbuilder.NewConnector` function in the baton-sdk already validates the connector parameter using a type switch and returns appropriate errors for nil or invalid connectors in the default case, so additional nil checks are not needed before calling this function.
Applied to files:
pkg/cli/commands.go
📚 Learning: 2025-06-02T21:28:25.367Z
Learnt from: MarcusGoldschmidt
Repo: ConductorOne/baton-sdk PR: 393
File: pkg/test/integration_wrapper.go:54-54
Timestamp: 2025-06-02T21:28:25.367Z
Learning: The `connectorbuilder.NewConnector` function in the baton-sdk already validates the connector parameter and returns appropriate errors for nil or invalid connectors, so additional nil checks are not needed before calling this function.
Applied to files:
pkg/cli/commands.go
📚 Learning: 2025-10-24T20:32:19.985Z
Learnt from: kans
Repo: ConductorOne/baton-sdk PR: 531
File: pkg/session/json_session.go:38-42
Timestamp: 2025-10-24T20:32:19.985Z
Learning: In the baton-sdk repository, SetManyJSON and similar batch operations in pkg/session/json_session.go should not add early-return guards for empty inputs. The design preference is to let server-side validation errors (such as min_pairs:1) propagate rather than silently succeeding on the client side.
Applied to files:
pkg/mcp/handlers.go
🧬 Code graph analysis (14)
vendor/github.com/modelcontextprotocol/go-sdk/mcp/session.go (2)
vendor/go.opentelemetry.io/otel/semconv/v1.27.0/attribute_group.go (1)
SessionID(7931-7933)vendor/github.com/modelcontextprotocol/go-sdk/mcp/protocol.go (3)
InitializeParams(443-454)InitializedParams(505-509)LoggingLevel(653-653)
vendor/github.com/modelcontextprotocol/go-sdk/mcp/prompt.go (2)
vendor/github.com/modelcontextprotocol/go-sdk/mcp/requests.go (1)
GetPromptRequest(12-12)vendor/github.com/modelcontextprotocol/go-sdk/mcp/protocol.go (1)
Prompt(782-798)
vendor/github.com/google/jsonschema-go/jsonschema/infer.go (1)
vendor/github.com/google/jsonschema-go/jsonschema/schema.go (2)
Schema(42-128)Ptr(352-352)
vendor/github.com/modelcontextprotocol/go-sdk/mcp/tool.go (2)
vendor/github.com/modelcontextprotocol/go-sdk/mcp/requests.go (1)
CallToolRequest(10-10)vendor/github.com/modelcontextprotocol/go-sdk/mcp/protocol.go (1)
Tool(1043-1095)
vendor/github.com/google/jsonschema-go/jsonschema/json_pointer.go (1)
vendor/github.com/google/jsonschema-go/jsonschema/schema.go (1)
Schema(42-128)
vendor/github.com/modelcontextprotocol/go-sdk/auth/auth.go (2)
vendor/github.com/modelcontextprotocol/go-sdk/oauthex/resource_meta.go (1)
ResourceMetadataURL(115-122)vendor/github.com/modelcontextprotocol/go-sdk/oauthex/oauthex.go (1)
ProtectedResourceMetadata(15-92)
pkg/cli/commands.go (4)
pkg/field/validation.go (2)
Configurable(323-329)WithAuthMethod(337-341)pkg/cli/cli.go (3)
GetConnectorFunc2(26-26)MakeGenericConfiguration(42-60)RunTimeOpts(18-21)pkg/field/decode_hooks.go (1)
FileUploadDecodeHook(48-66)pkg/mcp/server.go (1)
NewMCPServer(21-44)
vendor/golang.org/x/oauth2/oauth2.go (1)
vendor/golang.org/x/oauth2/internal/transport.go (1)
ContextClient(21-28)
vendor/github.com/google/jsonschema-go/jsonschema/resolve.go (1)
vendor/github.com/google/jsonschema-go/jsonschema/schema.go (1)
Schema(42-128)
vendor/github.com/google/jsonschema-go/jsonschema/validate.go (2)
vendor/github.com/google/jsonschema-go/jsonschema/resolve.go (1)
Resolved(24-30)vendor/github.com/google/jsonschema-go/jsonschema/schema.go (1)
Schema(42-128)
vendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/messages.go (1)
vendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/wire.go (3)
ErrParse(16-16)WireError(67-74)ErrInvalidRequest(18-18)
vendor/github.com/modelcontextprotocol/go-sdk/mcp/content.go (2)
vendor/github.com/modelcontextprotocol/go-sdk/mcp/shared.go (1)
Meta(425-425)vendor/github.com/modelcontextprotocol/go-sdk/mcp/protocol.go (1)
Icon(767-779)
pkg/mcp/handlers.go (2)
pkg/mcp/server.go (1)
MCPServer(14-18)vendor/github.com/modelcontextprotocol/go-sdk/mcp/requests.go (1)
CallToolRequest(10-10)
vendor/github.com/modelcontextprotocol/go-sdk/mcp/protocol.go (2)
vendor/github.com/modelcontextprotocol/go-sdk/mcp/shared.go (1)
Meta(425-425)vendor/github.com/modelcontextprotocol/go-sdk/mcp/content.go (3)
Content(18-21)TextContent(24-28)ResourceContents(188-194)
🪛 GitHub Check: go-lint
pkg/mcp/server.go
[failure] 68-68:
param cap has same name as predeclared identifier (predeclared)
pkg/cli/commands.go
[failure] 29-29:
File is not properly formatted (goimports)
pkg/mcp/handlers.go
[failure] 283-283:
G115: integer overflow conversion int -> uint32 (gosec)
[failure] 251-251:
G115: integer overflow conversion int -> uint32 (gosec)
[failure] 196-196:
G115: integer overflow conversion int -> uint32 (gosec)
[failure] 170-170:
G115: integer overflow conversion int -> uint32 (gosec)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: go-test (1.25.2, windows-latest)
- GitHub Check: go-test (1.25.2, ubuntu-latest)
🔇 Additional comments (80)
vendor/golang.org/x/oauth2/internal/oauth2.go (1)
15-19: LGTM!This is a standard vendor update reflecting upstream changes in
golang.org/x/oauth2. The only modification is a doc comment syntax update to use Go's doc link format ([*rsa.PrivateKey]), which enables clickable documentation links. No functional changes to the parsing logic.vendor/golang.org/x/oauth2/internal/transport.go (1)
12-13: LGTM!This is a standard vendor dependency update. The comment changes update the documentation to use Go's doc link syntax (
[context.WithValue],[*http.Client]) for improved godoc rendering. No functional changes.vendor/github.com/modelcontextprotocol/go-sdk/internal/xcontext/xcontext.go (1)
1-23: LGTM!This is vendored code from the official
modelcontextprotocol/go-sdk. The implementation correctly follows the standard detached context pattern - preserving value lookups via delegation to the parent while returning no-op values for cancellation (Done()→nil), deadline (Deadline()→ zero), and error (Err()→nil). This is useful for operations that need to continue beyond the lifetime of the original context.vendor/golang.org/x/oauth2/internal/doc.go (1)
5-6: LGTM!Standard upstream vendor update with Go 1.19+ doc comment linking syntax.
vendor/golang.org/x/oauth2/clientcredentials/clientcredentials.go (1)
56-85: LGTM!Upstream vendor update with Go 1.19+ doc comment bracketed references for
[oauth2.HTTPClient],[http.Client],[oauth2.TokenSource], and[Config.Client]. Documentation-only changes with no functional impact.vendor/golang.org/x/oauth2/transport.go (2)
14-19: LGTM - Documentation improvements from upstream dependency.These documentation updates use Go 1.19+ doc comment link syntax for proper cross-references. Standard upstream library improvements.
50-55: LGTM - Improved request cloning using standard library.The change from an internal
cloneRequesthelper toreq.Clone(req.Context())is a clean upstream improvement. The standard library method properly handles header copying and request duplication. The body closing logic with thereqBodyClosedflag correctly handles cleanup if an error occurs before the baseRoundTrippertakes ownership.vendor/github.com/modelcontextprotocol/go-sdk/oauthex/oauth2.go (1)
1-91: Vendored SDK code looks appropriate for its purpose.This file is part of the vendored
modelcontextprotocol/go-sdkdependency. The OAuth extension utilities implement:
- RFC 9728/8414 compliant path prepending for well-known endpoints
- JSON fetching with size limits and strict content-type validation
- XSS-safe URL scheme validation (blocking
javascript:,data:,vbscript:)The implementation follows standard patterns with proper resource cleanup and error handling. As vendored code, modifications should be avoided in favor of upstream contributions if issues arise.
vendor/golang.org/x/oauth2/jwt/jwt.go (1)
71-71: Vendor updates look correct.These are standard Go modernization changes from an upstream
golang.org/x/oauth2update:
interface{}→any(Go 1.18+ alias)ioutil.ReadAll→io.ReadAll(deprecated since Go 1.16)- Struct embedding of
oauth2.Tokenfor cleaner field accessAll changes are functionally equivalent to the previous implementation.
Also applies to: 138-138, 150-151, 160-160
vendor/golang.org/x/oauth2/jws/jws.go (1)
1-198: Vendored dependency update from upstream looks good.This is a standard vendor update from
golang.org/x/oauth2. The changes reflect upstream improvements:
- Modern Go idioms (
anyalias,strings.Cut)- Cleaner token parsing via the new
parseTokenhelper- Improved robustness in
DecodeandVerifyfunctionsvendor/github.com/modelcontextprotocol/go-sdk/mcp/event.go (1)
1-429: Vendored dependency from official MCP Go SDK — looks good.This is vendored code from
modelcontextprotocol/go-sdk, the official MCP protocol SDK. The SSE implementation is well-structured with:
- Thread-safe
MemoryEventStorewith proper mutex usage- Bounded memory via configurable
maxBytesand purge logic- Clean iterator pattern in
scanEventsandAftermethods- Proper error handling for purged events via
ErrEventsPurgedNo modifications should be made directly to vendored files. If issues arise with this dependency, they should be addressed upstream or by updating the vendored version.
vendor/golang.org/x/oauth2/oauth2.go (1)
354-367: Vendor update from golang.org/x/oauth2 v0.30.0 - LGTM.The notable behavioral change in this file is
NewClientnow copyingCheckRedirect,Jar, andTimeoutfrom the context-provided HTTP client (lines 364-366), in addition to theTransport. This is an improvement that ensures the returned OAuth2 client better inherits the configuration of any custom HTTP client passed via context. The remaining changes are documentation updates using Go 1.19+ bracketed type references.vendor/golang.org/x/oauth2/token.go (3)
61-61: Vendor update:interface{}→anytype alias - LGTM.The
rawfield,WithExtraparameter, andExtrareturn type are updated to useanyinstead ofinterface{}. These are semantically identical (Go 1.18+ type alias) and represent a modernization of the API surface.Also applies to: 98-98, 108-109
166-166: NewExpiresInfield mapping - LGTM.The
ExpiresInfield is now propagated from the internal token, allowing consumers to access the rawexpires_inwire format value from OAuth2 responses. This is useful for applications that need to handle token expiry calculations themselves.
176-181: Enhanced error handling with typedRetrieveError- LGTM.The
retrieveTokenfunction now converts*internal.RetrieveErrorto the public*RetrieveErrortype, enabling callers to use type assertions for structured error handling and access RFC 6749 error fields (ErrorCode,ErrorDescription,ErrorURI).vendor/golang.org/x/oauth2/internal/token.go (5)
28-62: Vendored oauth2 library update looks correct.The
Tokenstruct changes align with modern Go idioms (anyvsinterface{}) and improve OAuth2 spec compliance by exposingExpiresIn. These are standard updates from the official golang.org/x/oauth2 library.
144-176: Auth style cache keying improvement.The composite key
authStyleCacheKey{url, clientID}is a correctness improvement—different OAuth2 clients may require different auth styles for the same token URL. This prevents potential cache collisions.
216-248: RetrieveToken correctly passes clientID to cache operations.The flow is consistent with the auth style cache refactor, ensuring cache lookups and storage are scoped per-client.
263-263: Good: Usesio.ReadAllinstead of deprecatedioutil.ReadAll.Standard Go modernization.
318-321: Token construction correctly populatesExpiresInandRaw.The cast from
expirationTime(int32) to int64 is safe. InitializingRawasmap[string]anybefore unmarshaling ensures the token carries extra OAuth2 response metadata.vendor/github.com/modelcontextprotocol/go-sdk/auth/client.go (1)
1-123: Vendored SDK code looks well-implemented.This is vendored code from
modelcontextprotocol/go-sdk. The OAuth transport implementation correctly handles:
- Request body preservation and replay for retries after 401.
- Double-checked locking pattern for thread-safe Base transport upgrade.
- Prevention of infinite retry loops when already using oauth2.Transport.
The acknowledged TODO (lines 105-106) about holding the mutex during the OAuth flow is a known trade-off in the upstream SDK.
vendor/github.com/modelcontextprotocol/go-sdk/auth/auth.go (1)
1-168: Vendored SDK code looks well-implemented.This is vendored code from the official
modelcontextprotocol/go-sdkpackage. The implementation:
- Follows standard Go patterns for HTTP middleware and context propagation
- Implements proper bearer token validation per RFC 6750
- Correctly handles OAuth protected resource metadata per RFC 9728
- Documents the intentionally permissive CORS policy for metadata discovery
The security checks in
verify()(expiration validation, scope verification, sentinel error handling) are appropriate for authentication middleware.vendor/github.com/google/jsonschema-go/jsonschema/annotations.go (1)
1-76: Vendored code from Google's jsonschema-go library looks good.Clean implementation of annotation tracking for JSON Schema validation. The lazy map initialization pattern and generic merge helper are well-implemented.
vendor/github.com/google/jsonschema-go/jsonschema/json_pointer.go (1)
1-146: Vendored JSON Pointer implementation is correct.Properly implements RFC 6901 with appropriate escaping, validation of array indices (including rejection of leading zeros and the "-" segment), and schema-aware traversal.
vendor/github.com/google/jsonschema-go/jsonschema/util.go (1)
1-463: Vendored utility code is well-implemented.Comprehensive JSON Schema utilities including mathematical number equality (via
big.Rat), deterministic hashing, and struct-with-map marshaling for extension fields. The sync.Map caching for JSON field names is appropriate.vendor/github.com/google/jsonschema-go/jsonschema/infer.go (1)
1-151: Schema inference implementation is well-designed.Good type-to-schema mapping with proper cycle detection, pointer handling (nullable types), and support for custom type schemas via
ForOptions.TypeSchemas. TheinitialSchemaMapinitialization for stdlib types is appropriate.Also applies to: 154-248
vendor/github.com/google/jsonschema-go/jsonschema/schema.go (1)
1-436: Comprehensive JSON Schema 2020-12 implementation.Well-structured Schema type with proper handling of:
- Type/Types mutual exclusivity
- Boolean schema shorthand (
true/false↔{}/{"not":{}})- Const with JSON null values
- Integer fields that may arrive as floats (e.g.,
1.0)- Deep cloning of schema trees
The reflection-based traversal utilities (
every,everyChild,all,children) are cleanly implemented.vendor/github.com/google/jsonschema-go/jsonschema/resolve.go (1)
1-548: Vendored dependency looks appropriate for MCP support.This is a vendored file from
github.com/google/jsonschema-gothat provides JSON Schema resolution capabilities required by the MCP SDK. The implementation follows the JSON Schema draft-2020-12 specification and includes comprehensive validation, URI handling, and reference resolution.As a third-party dependency from a reputable source (Google), this is appropriate to vendor for the MCP mode feature.
vendor/github.com/google/jsonschema-go/jsonschema/validate.go (1)
1-789: Vendored validation engine is comprehensive and appropriate.This vendored file from
github.com/google/jsonschema-goprovides a complete JSON Schema validation engine supporting draft-2020-12. Key features include:
- Full keyword support (type constraints, numeric/string validation, array/object handling)
- Dynamic reference resolution for complex schema composition
- Default value application via
ApplyDefaults()- Performance optimizations (hash-based uniqueness checks, cached struct metadata)
Note: Struct validation (lines 404-406) intentionally returns an error, directing users to a tracked issue. This is a known limitation of the library.
vendor/modules.txt (3)
313-321: v1.2.0 is the latest release of modelcontextprotocol/go-sdk. No known security vulnerabilities.
236-238: No concerns found. google/jsonschema-go v0.3.0 is the latest released version with no known security vulnerabilities.
416-418: No action required.The uritemplate/v3 v3.0.2 dependency is valid with no known security vulnerabilities. It is an indirect dependency and the Go 1.14 requirement is compatible with modern versions.
vendor/github.com/modelcontextprotocol/go-sdk/internal/util/util.go (1)
1-44: LGTM - Clean utility functions.These vendored utility functions are well-implemented with proper generic constraints and efficient memory pre-allocation in
KeySlice.vendor/github.com/modelcontextprotocol/go-sdk/mcp/features.go (1)
17-114: LGTM - Well-designed lazy-sorted feature set.The implementation uses efficient lazy sorting with a cached
sortedKeysslice that's invalidated on mutations. The design decision to not include internal synchronization is documented (lines 21-22), delegating thread-safety to callers when concurrent access is needed.vendor/github.com/modelcontextprotocol/go-sdk/mcp/tool.go (1)
1-139: LGTM - Solid tool handling and validation.The implementation provides thorough validation with good error messages. The
validateToolNamefunction correctly collects all invalid characters before reporting, improving developer experience. TheapplySchemafunction safely handles the nil schema case.vendor/github.com/modelcontextprotocol/go-sdk/mcp/cmd.go (2)
66-108: LGTM - Graceful shutdown follows MCP spec.The shutdown sequence correctly implements the MCP stdio transport spec: close stdin → wait for exit → SIGTERM if unresponsive → SIGKILL as last resort. The buffered
resChan(capacity 1) prevents the goroutine from leaking when the process exits during shutdown.
12-13: Platform-specific import: Unix-only signals.The
syscallimport forSIGTERM(line 95) and theKill()method make this transport Unix-specific. This file won't compile on Windows.If Windows support is needed for the MCP mode feature, verify whether the upstream SDK provides a platform-agnostic alternative or consider whether MCP mode should be disabled on Windows.
#!/bin/bash # Check if there are any build constraints or Windows-specific alternatives in the vendor rg -l "//go:build" vendor/github.com/modelcontextprotocol/go-sdk/ rg -l "windows" vendor/github.com/modelcontextprotocol/go-sdk/vendor/github.com/modelcontextprotocol/go-sdk/mcp/logging.go (1)
91-106: Good defensive pattern for nil logger.The
ensureLoggerfunction withdiscardHandlerprovides a safe fallback when a nil logger is passed. The TODO noting future use ofslog.DiscardHandler(Go 1.24+) is appropriate.vendor/github.com/modelcontextprotocol/go-sdk/mcp/session.go (1)
1-29: LGTM - Official MCP SDK session state types.This vendor file from the official
modelcontextprotocol/go-sdkintroduces session state management types. TheServerSessionStatestruct properly references the protocol types (InitializeParams,InitializedParams,LoggingLevel) and includes appropriate JSON serialization tags.vendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/wire.go (1)
1-97: LGTM - Standard JSON-RPC 2.0 wire protocol implementation.This vendor file correctly implements the JSON-RPC 2.0 specification with standard error codes and a structured
WireErrortype. The custom extension codes (-32000 to -32005) properly fall within the server error range allowed by the spec.vendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/messages.go (1)
1-212: LGTM - Comprehensive JSON-RPC 2.0 message handling.This vendor file provides a complete message encoding/decoding layer. Key observations:
IDtype correctly handles the spec's allowed types (string, integer, null)DecodeMessageproperly distinguishes between Request (has method) and Response (no method, has ID)toWireErrorpreserves error codes when wrappingWireErrorinstancesmarshalToRawcorrectly handles nil payloadsvendor/github.com/modelcontextprotocol/go-sdk/jsonrpc/jsonrpc.go (1)
1-56: LGTM - Clean public API wrapper.This vendor file provides a stable public API surface that re-exports internal types. The approach of using type aliases and wrapper functions allows the SDK to evolve its internal implementation while maintaining API stability for transport authors.
vendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/conn.go (1)
1-841: LGTM - Robust JSON-RPC connection management.This vendor file implements sophisticated bidirectional JSON-RPC connection handling with several notable patterns:
- Thread-safe state management: The
updateInFlightpattern ensures all state mutations are properly synchronized- Graceful shutdown: The
shuttingDownmethod checks multiple error conditions, and in-flight requests are properly retired when the reader exits- Async request handling: The
releaserpattern allows handlers to opt into concurrent execution viaAsync(ctx)- Cancellation isolation: The
notDonecontext wrapper prevents connection-level cancellation from propagating inappropriatelyThe implementation handles edge cases well, including duplicate request IDs (line 612-616), write failures (line 797-813), and proper cleanup of cancelled requests.
vendor/github.com/modelcontextprotocol/go-sdk/mcp/resource_pre_go124.go (1)
1-25: Vendor file from modelcontextprotocol/go-sdk - no changes required.This is third-party vendored code. The noted lack of path traversal protection (line 16) is intentional for pre-Go1.24 builds; the Go1.24+ variant (
resource_go124.go) usesos.OpenRootfor secure path handling.vendor/github.com/modelcontextprotocol/go-sdk/mcp/prompt.go (1)
1-17: Vendor file from modelcontextprotocol/go-sdk - no changes required.Standard MCP SDK handler type definitions.
vendor/github.com/modelcontextprotocol/go-sdk/mcp/resource_go124.go (1)
1-29: Vendor file from modelcontextprotocol/go-sdk - no changes required.This Go 1.24+ variant uses
os.OpenRootfor secure path traversal protection, complementing the pre-1.24 fallback.pkg/cli/commands.go (1)
603-669: LGTM - Clean implementation following established patterns.The
MakeMCPServerCommandfunction correctly mirrors the initialization flow used byMakeGRPCServerCommand(flag binding, logger/otel setup, config validation) while appropriately serving via stdio for MCP mode.pkg/mcp/server.go (1)
80-171: Tool registrations are well-structured and all handlers are properly implemented.The capability-based conditional registration pattern is appropriate, and all 14 referenced handler methods (
handleGetMetadata,handleValidate,handleListResourceTypes,handleListResources,handleGetResource,handleListEntitlements,handleListGrants,handleGrant,handleRevoke,handleCreateResource,handleDeleteResource,handleListTicketSchemas,handleCreateTicket,handleGetTicket) are implemented inhandlers.go.vendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/net.go (1)
37-40: Context parameter unused in Accept method.The
Acceptmethod accepts acontext.Contextparameter but doesn't use it. This is a known limitation sincenet.Listener.Accept()doesn't support context cancellation. The caller should be aware that cancellation won't interrupt a blocking Accept call on network listeners (only works fornetPiper).This appears to be intentional in the SDK design to maintain interface consistency.
vendor/github.com/modelcontextprotocol/go-sdk/oauthex/auth_meta.go (1)
1-187: Vendored OAuth metadata implementation looks correct.The implementation properly follows RFC 8414 for Authorization Server Metadata:
- Enforces PKCE support requirement (security best practice)
- Validates URL schemes to prevent XSS attacks
- Checks issuer consistency per section 3.3 of the RFC
- Tries multiple well-known paths in correct order
Note: Line 29 has a minor doc comment typo with an extra parenthesis in the URL, but this is vendored SDK code.
vendor/github.com/modelcontextprotocol/go-sdk/mcp/streamable_client.go (1)
1-226: Design documentation file - no implementation to review.This file contains comprehensive design documentation for the streamable HTTP client transport. The actual implementation resides in
streamable.go. The documentation clearly explains:
- Connection lifecycle phases
- Message flow via POST/SSE
- Session management and resumption
- Error handling strategies
Good practice to have this architectural documentation alongside the implementation.
vendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/jsonrpc2.go (1)
89-121: Well-designed async helper pattern.The
asynctype implements a clean pattern for coordinating asynchronous operations:
- Uses a 1-buffered channel as a mutex for error storage
wait()correctly allows multiple goroutines to retrieve the same errorsetError()properly implements first-error-wins semanticsThe interface abstractions (
Preempter,Handler) with functional adapters follow Go idioms well.vendor/github.com/modelcontextprotocol/go-sdk/mcp/streamable.go (7)
78-114: Session timeout management with reference counting.The
startPOST/endPOSTpattern correctly manages timer pause/resume with reference counting. The defensive assertion on line 110 catches mismatched calls. The mutex usage properly protects the timer and refs fields.
250-258: Good session hijacking prevention.The code properly prevents session hijacking by validating that subsequent requests come from the same user who created the session. This is an important security measure for the streamable transport.
1366-1380: Close implementation with acknowledged context limitation.The
Closemethod correctly guards against double-close withisDone. The use ofcontext.TODO()foreventStore.SessionClosed(line 1376) is acknowledged by the SDK authors as a known limitation that could benefit from a proper context or timeout.
1989-2010: Client close with proper cleanup sequence.The close implementation correctly:
- Uses
sync.Oncefor idempotent closes- Skips DELETE request if session is already gone (errSessionMissing)
- Cancels context after attempting cleanup to stop background goroutines
- Closes done channel to signal completion
The DELETE request is best-effort; if the context is already cancelled, the request may fail but that's acceptable for cleanup.
2012-2026: Exponential backoff with additive jitter.The reconnect delay calculation implements exponential backoff. Note that the jitter is additive (line 2025:
backoffDuration + jitter), meaning actual delays range frombackoffDurationto2*backoffDuration. This is a valid approach, though differs from the more common "full jitter" pattern where the delay would berand.N(backoffDuration)alone.
1731-1748: Test authentication helper noted as temporary.The
testAuthglobal variable is test infrastructure for authentication testing. While having test code in production files isn't ideal, it's:
- Thread-safe (atomic.Bool)
- Disabled by default
- Acknowledged by SDK authors as temporary (TODO comment)
This won't affect production unless explicitly enabled.
1-35: Comprehensive MCP streamable HTTP transport implementation.This is a substantial implementation of the MCP streamable HTTP transport specification. Key strengths:
- Proper separation between
StreamableHTTPHandler,StreamableServerTransport, andStreamableClientTransport- Session hijacking prevention
- Stream resumption support via EventStore
- Distinction between transient and terminal errors
- Well-documented with MCP spec references
The implementation is complex but appropriate for the protocol requirements.
vendor/github.com/modelcontextprotocol/go-sdk/oauthex/dcr.go (1)
1-261: Vendored SDK file - DCR implementation looks correct.This vendored file implements RFC 7591 Dynamic Client Registration with proper URL validation to prevent XSS attacks. The implementation includes appropriate error handling and time serialization for Unix timestamps.
Note: The
checkURLSchemehelper function (Lines 238, 256) is defined elsewhere in theoauthexpackage and is used for validating URL schemes.vendor/github.com/modelcontextprotocol/go-sdk/oauthex/resource_meta.go (1)
1-281: Vendored SDK file - RFC 9728 implementation with proper header parsing.This file implements Protected Resource Metadata retrieval per RFC 9728 with:
- HTTPS enforcement for resource URLs
- WWW-Authenticate header parsing per RFC 9110
- Authorization server URL validation to prevent XSS
The code includes AI-generated portions (noted in comments) that have been human-reviewed.
vendor/github.com/modelcontextprotocol/go-sdk/mcp/resource.go (1)
42-48: JSON data field construction is safe.The use of
%qformat specifier infmt.Sprintfproperly escapes the URI for JSON string embedding, preventing injection issues.vendor/github.com/modelcontextprotocol/go-sdk/mcp/sse.go (1)
446-467: TOCTOU between isDone() check and HTTP POST.The
isDone()check at Line 451 can become stale before the HTTP request completes. However, this is acceptable because the POST will fail with a network error if the connection closes, and the error is properly propagated.vendor/github.com/modelcontextprotocol/go-sdk/mcp/content.go (2)
18-21: Unexported method in exported interface is intentional.The
fromWiremethod being unexported prevents external packages from implementing theContentinterface, effectively creating a sealed type hierarchy. This is a deliberate design pattern to ensure only SDK-defined content types are valid.
196-223: ResourceContents validation ensures mutual exclusivity.The
MarshalJSONmethod properly validates that:
- URI is required (Line 198-200)
- Text and Blob are mutually exclusive (Line 207-209)
This prevents invalid wire representations.
vendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/frame.go (1)
1-208: LGTM - Vendored JSON-RPC 2.0 framing implementation.This is well-structured code from the official MCP SDK providing two framing strategies (raw JSON and header-based LSP-style). Thread safety is properly handled with mutexes on writers, and context cancellation is checked before I/O operations.
vendor/github.com/modelcontextprotocol/go-sdk/mcp/client.go (1)
1-1075: LGTM - Comprehensive MCP client implementation.This vendored code provides a complete MCP client with proper session lifecycle management, capability negotiation, middleware support, and pagination helpers. Thread safety is correctly handled throughout.
Minor note: There's a typo at line 595 ("defalts" instead of "defaults") that could be reported upstream to the SDK maintainers.
vendor/github.com/modelcontextprotocol/go-sdk/mcp/requests.go (1)
1-38: LGTM - Clean request type aliases.This file provides well-organized type aliases for server and client request types using Go generics, making the MCP protocol API more ergonomic.
vendor/github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2/serve.go (1)
1-330: LGTM - Well-designed JSON-RPC 2.0 server framework.This vendored code implements a robust server lifecycle with:
- Graceful shutdown coordination using atomic flags and
sync.Once- Idle timeout listener wrapper with sophisticated channel-based state management
- Defensive finalizer to detect unclosed connections
- Proper
WaitGrouptracking for active connectionsThe idle listener pattern (lines 125-294) is particularly well-designed, handling edge cases around concurrent Accept/Close and timer expiration.
vendor/github.com/modelcontextprotocol/go-sdk/mcp/shared.go (1)
1-610: LGTM - Well-structured shared MCP infrastructure.This vendored code provides the foundational abstractions for the MCP SDK including:
- Protocol version negotiation across multiple supported versions
- Type-safe method handler wiring using generics
- Middleware pipeline for request/response interception
- Progress token support and keepalive mechanism
The code appropriately uses reflection only where generics cannot express the required type relationships (line 306 for
newResult).pkg/mcp/handlers.go (7)
1-12: LGTM!Package declaration and imports are clean.
14-81: LGTM!Input types are well-structured with appropriate jsonschema tags that will help AI assistants understand the tool parameters.
82-137: LGTM!Output types are consistent with good pagination support via
NextPageTokenandHasMorefields.
141-153: LGTM!Handler correctly calls the connector and serializes the response using
protoToMap.
229-310: LGTM!These handlers correctly construct protobuf request objects, call the connector, and serialize responses using
protoToMap/protoListToMaps.
312-414: LGTM!Grant, revoke, create, and delete resource handlers are well-implemented with proper error handling. The optional parent resource handling in
handleCreateResourcecorrectly uses proto's nil-safeGetId()method.
416-470: LGTM!Ticket handlers follow the same consistent patterns as other handlers with proper serialization.
vendor/github.com/modelcontextprotocol/go-sdk/mcp/transport.go (1)
1-655: Vendored dependency - no changes needed.This is an external dependency from
github.com/modelcontextprotocol/go-sdk. The transport implementation includes proper concurrency handling, JSON-RPC batching support, and clean interface definitions.vendor/github.com/modelcontextprotocol/go-sdk/mcp/server.go (1)
1-1497: Vendored dependency - no changes needed.This is an external dependency providing the MCP server implementation with comprehensive session management, capability negotiation, and feature registration. The implementation handles concurrent access properly with appropriate mutex usage.
vendor/github.com/modelcontextprotocol/go-sdk/mcp/protocol.go (1)
1-1357: Vendored dependency - no changes needed.This is an external dependency defining the MCP protocol types with comprehensive JSON marshaling support and backward compatibility adapters for client/server capabilities.
| func (m *MCPServer) handleListResourceTypes(ctx context.Context, req *mcp.CallToolRequest, input PaginationInput) (*mcp.CallToolResult, ListResourceTypesOutput, error) { | ||
| pageSize := uint32(defaultPageSize) | ||
| if input.PageSize > 0 { | ||
| pageSize = uint32(input.PageSize) | ||
| } | ||
|
|
||
| resp, err := m.connector.ListResourceTypes(ctx, &v2.ResourceTypesServiceListResourceTypesRequest{ | ||
| PageSize: pageSize, | ||
| PageToken: input.PageToken, | ||
| }) | ||
| if err != nil { | ||
| return nil, ListResourceTypesOutput{}, fmt.Errorf("failed to list resource types: %w", err) | ||
| } | ||
|
|
||
| resourceTypes, err := protoListToMaps(resp.GetList()) | ||
| if err != nil { | ||
| return nil, ListResourceTypesOutput{}, fmt.Errorf("failed to serialize resource types: %w", err) | ||
| } | ||
|
|
||
| return nil, ListResourceTypesOutput{ | ||
| ResourceTypes: resourceTypes, | ||
| NextPageToken: resp.GetNextPageToken(), | ||
| HasMore: resp.GetNextPageToken() != "", | ||
| }, nil | ||
| } |
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.
Guard against integer overflow when converting PageSize to uint32.
The static analysis flagged G115: integer overflow conversion int -> uint32 at line 170. While the > 0 check prevents negative values, an int larger than math.MaxUint32 would silently truncate. This same pattern appears in handleListResources (line 196), handleListEntitlements (line 251), and handleListGrants (line 283).
Consider adding a helper function to safely convert and clamp the page size:
🔧 Suggested helper function
import "math"
func safePageSize(size int, defaultSize uint32) uint32 {
if size <= 0 {
return defaultSize
}
if size > math.MaxUint32 {
return math.MaxUint32
}
return uint32(size)
}Then use it in handlers:
-pageSize := uint32(defaultPageSize)
-if input.PageSize > 0 {
- pageSize = uint32(input.PageSize)
-}
+pageSize := safePageSize(input.PageSize, defaultPageSize)🧰 Tools
🪛 GitHub Check: go-lint
[failure] 170-170:
G115: integer overflow conversion int -> uint32 (gosec)
🤖 Prompt for AI Agents
In `@pkg/mcp/handlers.go` around lines 167 - 191, The int->uint32 conversion for
PageSize in handleListResourceTypes (and the same pattern in
handleListResources, handleListEntitlements, handleListGrants) can overflow when
input.PageSize > math.MaxUint32; add a small helper (e.g., safePageSize(size
int, defaultSize uint32) uint32) that returns defaultSize for <=0, clamps values
> math.MaxUint32 to math.MaxUint32, otherwise casts to uint32, import math, and
replace the direct conversion in each handler to use
safePageSize(input.PageSize, defaultPageSize).
| if t.Key().Kind() != reflect.String { | ||
| } |
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.
Dead code: empty if block.
This condition was already checked at line 146. The empty block here appears to be leftover from refactoring in the upstream library.
if t.Key().Kind() != reflect.String {
}Consider reporting this to the upstream google/jsonschema-go repository or removing it if maintaining a fork.
🤖 Prompt for AI Agents
In `@vendor/github.com/google/jsonschema-go/jsonschema/infer.go` around lines 152
- 153, The empty if block `if t.Key().Kind() != reflect.String { }` in infer.go
is dead code and should be removed; locate the check around the use of
`t.Key().Kind()` (same area where `reflect.String` is already validated) and
delete the redundant empty conditional, or alternatively raise an issue with
upstream `google/jsonschema-go` if you intend to keep the fork but not modify
behavior.
| func() { | ||
| h.mu.Lock() | ||
| defer h.mu.Unlock() | ||
| h.buf.Reset() | ||
| err = h.handler.Handle(ctx, r) | ||
| }() | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| h.mu.Lock() | ||
| h.lastMessageSent = time.Now() | ||
| h.mu.Unlock() | ||
|
|
||
| params := &LoggingMessageParams{ | ||
| Logger: h.opts.LoggerName, | ||
| Level: slogLevelToMCP(r.Level), | ||
| Data: json.RawMessage(h.buf.Bytes()), | ||
| } | ||
| // We pass the argument context to Notify, even though slog.Handler.Handle's | ||
| // documentation says not to. | ||
| // In this case logging is a service to clients, not a means for debugging the | ||
| // server, so we want to cancel the log message. | ||
| return h.ss.Log(ctx, params) |
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.
🧩 Analysis chain
🏁 Script executed:
# First, verify the file exists and examine the relevant section
if [ -f "vendor/github.com/modelcontextprotocol/go-sdk/mcp/logging.go" ]; then
echo "=== File found. Examining lines 175-210 ==="
sed -n '175,210p' vendor/github.com/modelcontextprotocol/go-sdk/mcp/logging.go | cat -n
else
echo "File not found at expected location"
# Try to find it
find . -name "logging.go" -path "*modelcontextprotocol*" 2>/dev/null
fiRepository: ConductorOne/baton-sdk
Length of output: 1241
🏁 Script executed:
# Get the full LoggingHandler Handle method to understand synchronization
sed -n '175,230p' vendor/github.com/modelcontextprotocol/go-sdk/mcp/logging.go | cat -nRepository: ConductorOne/baton-sdk
Length of output: 1197
🏁 Script executed:
# Look for all mutex operations around this code section
grep -n "mu\." vendor/github.com/modelcontextprotocol/go-sdk/mcp/logging.go | head -20Repository: ConductorOne/baton-sdk
Length of output: 223
🏁 Script executed:
# Check the structure of LoggingHandler to understand the mutex and buffer
sed -n '1,100p' vendor/github.com/modelcontextprotocol/go-sdk/mcp/logging.go | grep -A 10 "type LoggingHandler"Repository: ConductorOne/baton-sdk
Length of output: 832
🌐 Web query:
modelcontextprotocol go-sdk LoggingHandler thread safety race condition
💡 Result:
Short answer: the SDK’s logging plumbing calls user-provided handlers from goroutines, so you must assume handlers may be invoked concurrently — protect shared state (mutex/atomic) inside your LoggingHandler. The SDK provides a server-side slog.Handler wrapper (mcp.NewLoggingHandler) that batches/filters by MinInterval but does not remove the need for handler-side synchronization; examples in the repo show using atomic.Int32 in handlers. Run your code with go test -race and wrap any mutable state inside sync.Mutex or sync/atomic to avoid races.
Sources: mcp package docs (LoggingHandler, LoggingHandlerOptions and example showing atomic use) and client package docs (LoggingHandler type). [1][2]
References
[1] mcp package — LoggingHandler, LoggingHandlerOptions, example (shows atomic usage).
[2] client package — ClientFeatures.LoggingHandler type and usage.
Race condition: buffer read outside mutex protects against concurrent Reset().
Line 200 reads h.buf.Bytes() outside the mutex lock. Since handlers created via WithAttrs/WithGroup share the same mutex and buffer (via pointer), another goroutine calling Handle on a clone could acquire the lock at line 184, call Reset() at line 186, and write new data via handler.Handle() at line 188—while this goroutine is still using the byte slice from line 200.
The result is not just out-of-order delivery but actual data corruption: the bytes passed to Log at line 206 could contain partial or mixed data from a concurrent operation.
The SDK's concurrent handler invocation is intentional (per public documentation), so this is a real issue in the vendored code. Report this upstream to the modelcontextprotocol/go-sdk repository, or implement handler-level synchronization in your integration to prevent concurrent Handle calls on clones.
🤖 Prompt for AI Agents
In `@vendor/github.com/modelcontextprotocol/go-sdk/mcp/logging.go` around lines
183 - 206, The buffer bytes are read outside the mutex (h.buf.Bytes()) causing
races when clones created via WithAttrs/WithGroup call Handle concurrently; fix
by capturing a safe copy of the buffer while holding h.mu (e.g., lock h.mu, call
h.buf.Bytes(), make a new byte slice copy, then unlock) and use that copy when
constructing LoggingMessageParams.Data before calling h.ss.Log(ctx, params);
ensure the read and reset interactions around h.buf are all protected by h.mu to
prevent interleaving/corruption.
| # golang.org/x/oauth2 v0.30.0 | ||
| ## explicit; go 1.23.0 |
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify oauth2 version and project Go requirements
# Check project's go.mod for minimum Go version
echo "=== Project's Go version requirement ==="
if [ -f "go.mod" ]; then
grep "^go " go.mod
else
echo "go.mod not found"
fi
# Check vendor/modules.txt for oauth2 version
echo -e "\n=== Current oauth2 entry in vendor/modules.txt ==="
grep -A 2 "golang.org/x/oauth2" vendor/modules.txt | head -3Repository: ConductorOne/baton-sdk
Length of output: 241
🌐 Web query:
golang.org/x/oauth2 latest version 2025
💡 Result:
As of January 14, 2026 the latest tagged release of golang.org/x/oauth2 is v0.34.0. [1][2]
Sources:
[1] go.googlesource.com/oauth2 (tags list showing v0.34.0).
[2] pkg.go.dev/golang.org/x/oauth2 (package documentation).
Consider updating oauth2 to v0.34.0.
The oauth2 library is currently at v0.30.0, but v0.34.0 is available. Go version compatibility is not a concern since the project requires go 1.25.2, which exceeds oauth2's go 1.23.0 minimum. However, given the library's security-sensitive nature, consider updating to the latest available version.
🤖 Prompt for AI Agents
In `@vendor/modules.txt` around lines 560 - 561, The oauth2 module is pinned at
golang.org/x/oauth2 v0.30.0; update it to v0.34.0 by changing the module
requirement to v0.34.0 and regenerating modules (e.g., run `go get
golang.org/x/oauth2@v0.34.0` or edit go.mod to require v0.34.0 and run `go mod
tidy` / `go mod vendor`) so vendor/modules.txt and the build reflect the new
version.
Add an MCP mode option, allowing connectors to expose an MCP server interface as an alternative to gRPC.
New
pkg/mcppackage provides:Usage: connectors now support an
mcpsubcommand that starts the MCP server on stdio, enabling AI assistants to interact with the connector.Summary by CodeRabbit
New Features
Dependencies
✏️ Tip: You can customize this high-level summary in your review settings.