Skip to content

Conversation

mikeschinkel
Copy link

@mikeschinkel mikeschinkel commented Aug 12, 2025

Description

The file utils.go has around 50 useless allocations for what appears to be a way to use the Go compiler to ensure that all methods are implemented for the named type for the respective interfaces. Here is a section of that code:

var _ ClientRequest = &PingRequest{}
var _ ClientRequest = &InitializeRequest{}
var _ ClientRequest = &CompleteRequest{}
var _ ClientRequest = &SetLevelRequest{}
var _ ClientRequest = &GetPromptRequest{}
var _ ClientRequest = &ListPromptsRequest{}
var _ ClientRequest = &ListResourcesRequest{}
var _ ClientRequest = &ReadResourceRequest{}
var _ ClientRequest = &SubscribeRequest{}
var _ ClientRequest = &UnsubscribeRequest{}
var _ ClientRequest = &CallToolRequest{}
var _ ClientRequest = &ListToolsRequest{}

Go has a better way to do that that do not require useless allocations: (*Type)(nil). Here is what the above looks like using that technque:

var _ ClientRequest = (*PingRequest)(nil)
var _ ClientRequest = (*InitializeRequest)(nil)
var _ ClientRequest = (*CompleteRequest)(nil)
var _ ClientRequest = (*SetLevelRequest)(nil)
var _ ClientRequest = (*GetPromptRequest)(nil)
var _ ClientRequest = (*ListPromptsRequest)(nil)
var _ ClientRequest = (*ListResourcesRequest)(nil)
var _ ClientRequest = (*ReadResourceRequest)(nil)
var _ ClientRequest = (*SubscribeRequest)(nil)
var _ ClientRequest = (*UnsubscribeRequest)(nil)
var _ ClientRequest = (*CallToolRequest)(nil)
var _ ClientRequest = (*ListToolsRequest)(nil)

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • MCP spec compatibility implementation
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Code refactoring (no functional changes)
  • Performance improvement
  • Tests only (no functional changes)
  • Other (please describe):

Checklist

  • My code follows the code style of this project
  • I have performed a self-review of my own code
  • (N/A) I have added tests that prove my fix is effective or that my feature works
  • (N/A) I have updated the documentation accordingly

MCP Spec Compliance

  • This PR implements a feature defined in the MCP specification
  • Link to relevant spec section: Link text
  • Implementation follows the specification exactly

Additional Information

This change requires no testing and avoids creating unnesseary instances in the heap that are immediately thrown away.

Summary by CodeRabbit

  • Refactor

    • Standardized internal interface conformance checks to a consistent, pointer-based pattern across request, notification, and result types.
    • Improves internal consistency and clarity without changing runtime behavior or public APIs.
  • Chores

    • Minor internal cleanup to align code style and reduce potential overhead in compile-time checks.

No user-facing changes.

Copy link
Contributor

coderabbitai bot commented Aug 12, 2025

Walkthrough

Replaces compile-time interface assertion patterns from value composite literals (&Type{}) to nil pointer types ((Type)(nil)) across Client and Server* request, notification, and result types in mcp/utils.go. No runtime logic or behavior changes; only the assertion form is updated.

Changes

Cohort / File(s) Summary of changes
Client interface assertions
mcp/utils.go
Updated interface satisfaction guards for ClientRequest (PingRequest, InitializeRequest, CompleteRequest, SetLevelRequest, GetPromptRequest, ListPromptsRequest, ListResourcesRequest, ReadResourceRequest, SubscribeRequest, UnsubscribeRequest, CallToolRequest, ListToolsRequest), ClientNotification (CancelledNotification, ProgressNotification, InitializedNotification, RootsListChangedNotification), and ClientResult (EmptyResult, CreateMessageResult, ListRootsResult) from &Type{} to (*Type)(nil).
Server interface assertions
mcp/utils.go
Updated interface satisfaction guards for ServerRequest (PingRequest, CreateMessageRequest, ListRootsRequest), ServerNotification (CancelledNotification, ProgressNotification, LoggingMessageNotification, ResourceUpdatedNotification, ResourceListChangedNotification, ToolListChangedNotification, PromptListChangedNotification), and ServerResult (EmptyResult, InitializeResult, CompleteResult, GetPromptResult, ListPromptsResult, ListResourcesResult, ReadResourceResult, CallToolResult, ListToolsResult) from &Type{} to (*Type)(nil).

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Suggested reviewers

  • ezynda3
  • robert-jackson-glean
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
mcp/utils.go (1)

10-58: Optional: Group assertions into var-blocks and add a short comment for future readers

Grouping by kind improves readability and makes the intent explicit without changing behavior. Example diff for the ClientRequest block:

-// ClientRequest types
-var _ ClientRequest = (*PingRequest)(nil)
-var _ ClientRequest = (*InitializeRequest)(nil)
-var _ ClientRequest = (*CompleteRequest)(nil)
-var _ ClientRequest = (*SetLevelRequest)(nil)
-var _ ClientRequest = (*GetPromptRequest)(nil)
-var _ ClientRequest = (*ListPromptsRequest)(nil)
-var _ ClientRequest = (*ListResourcesRequest)(nil)
-var _ ClientRequest = (*ReadResourceRequest)(nil)
-var _ ClientRequest = (*SubscribeRequest)(nil)
-var _ ClientRequest = (*UnsubscribeRequest)(nil)
-var _ ClientRequest = (*CallToolRequest)(nil)
-var _ ClientRequest = (*ListToolsRequest)(nil)
+// ClientRequest types (compile-time assertions without allocation)
+var (
+	_ ClientRequest = (*PingRequest)(nil)
+	_ ClientRequest = (*InitializeRequest)(nil)
+	_ ClientRequest = (*CompleteRequest)(nil)
+	_ ClientRequest = (*SetLevelRequest)(nil)
+	_ ClientRequest = (*GetPromptRequest)(nil)
+	_ ClientRequest = (*ListPromptsRequest)(nil)
+	_ ClientRequest = (*ListResourcesRequest)(nil)
+	_ ClientRequest = (*ReadResourceRequest)(nil)
+	_ ClientRequest = (*SubscribeRequest)(nil)
+	_ ClientRequest = (*UnsubscribeRequest)(nil)
+	_ ClientRequest = (*CallToolRequest)(nil)
+	_ ClientRequest = (*ListToolsRequest)(nil)
+)

You can do the same for the other five groups if you like this style.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f16336 and 53c1eec.

📒 Files selected for processing (1)
  • mcp/utils.go (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.
📚 Learning: 2025-06-30T07:13:17.052Z
Learnt from: ezynda3
PR: mark3labs/mcp-go#461
File: server/sampling.go:22-26
Timestamp: 2025-06-30T07:13:17.052Z
Learning: In the mark3labs/mcp-go project, the MCPServer.capabilities field is a struct value (serverCapabilities), not a pointer, so it cannot be nil and doesn't require nil checking. Only pointer fields within the capabilities struct should be checked for nil.

Applied to files:

  • mcp/utils.go
🧬 Code Graph Analysis (1)
mcp/utils.go (3)
mcp/types.go (22)
  • ClientRequest (1110-1110)
  • PingRequest (507-510)
  • InitializeRequest (413-417)
  • CompleteRequest (1020-1024)
  • SetLevelRequest (748-752)
  • ListResourcesRequest (560-563)
  • ReadResourceRequest (588-592)
  • SubscribeRequest (619-623)
  • UnsubscribeRequest (634-638)
  • ClientNotification (1113-1113)
  • CancelledNotification (392-395)
  • ProgressNotification (516-519)
  • InitializedNotification (447-449)
  • RootsListChangedNotification (1105-1107)
  • ClientResult (1116-1116)
  • EmptyResult (377-377)
  • CreateMessageResult (847-854)
  • ListRootsResult (1082-1085)
  • ServerRequest (1119-1119)
  • CreateMessageRequest (827-830)
  • ListRootsRequest (1074-1077)
  • ServerNotification (1122-1122)
mcp/prompts.go (5)
  • GetPromptRequest (23-27)
  • ListPromptsRequest (9-12)
  • PromptListChangedNotification (100-102)
  • GetPromptResult (38-43)
  • ListPromptsResult (16-19)
mcp/tools.go (5)
  • CallToolRequest (54-58)
  • ListToolsRequest (18-21)
  • ToolListChangedNotification (542-544)
  • CallToolResult (40-51)
  • ListToolsResult (25-28)
🔇 Additional comments (6)
mcp/utils.go (6)

11-22: Good switch to typed nil pointers for ClientRequest assertions

Using (*T)(nil) removes the init-time allocation that &T{} would trigger while preserving the compile-time check. Semantics remain unchanged and this is idiomatic Go for these assertions.


25-28: ClientNotification assertions migrated correctly

Same benefits here: no allocation, same compile-time shape assurance. Looks good.


31-33: ClientResult assertions migrated correctly

No behavior change; avoids allocation. LGTM.


36-38: ServerRequest assertions migrated correctly

Change is consistent with the rest of the file and avoids unnecessary init-time work.


41-47: ServerNotification assertions migrated correctly

Consistent, allocation-free pattern. Looks good.


50-58: ServerResult assertions migrated correctly

Pattern applied consistently; no runtime effect, avoids allocations. LGTM.

Comment on lines 10 to +58
// ClientRequest types
var _ ClientRequest = &PingRequest{}
var _ ClientRequest = &InitializeRequest{}
var _ ClientRequest = &CompleteRequest{}
var _ ClientRequest = &SetLevelRequest{}
var _ ClientRequest = &GetPromptRequest{}
var _ ClientRequest = &ListPromptsRequest{}
var _ ClientRequest = &ListResourcesRequest{}
var _ ClientRequest = &ReadResourceRequest{}
var _ ClientRequest = &SubscribeRequest{}
var _ ClientRequest = &UnsubscribeRequest{}
var _ ClientRequest = &CallToolRequest{}
var _ ClientRequest = &ListToolsRequest{}
var _ ClientRequest = (*PingRequest)(nil)
var _ ClientRequest = (*InitializeRequest)(nil)
var _ ClientRequest = (*CompleteRequest)(nil)
var _ ClientRequest = (*SetLevelRequest)(nil)
var _ ClientRequest = (*GetPromptRequest)(nil)
var _ ClientRequest = (*ListPromptsRequest)(nil)
var _ ClientRequest = (*ListResourcesRequest)(nil)
var _ ClientRequest = (*ReadResourceRequest)(nil)
var _ ClientRequest = (*SubscribeRequest)(nil)
var _ ClientRequest = (*UnsubscribeRequest)(nil)
var _ ClientRequest = (*CallToolRequest)(nil)
var _ ClientRequest = (*ListToolsRequest)(nil)

// ClientNotification types
var _ ClientNotification = &CancelledNotification{}
var _ ClientNotification = &ProgressNotification{}
var _ ClientNotification = &InitializedNotification{}
var _ ClientNotification = &RootsListChangedNotification{}
var _ ClientNotification = (*CancelledNotification)(nil)
var _ ClientNotification = (*ProgressNotification)(nil)
var _ ClientNotification = (*InitializedNotification)(nil)
var _ ClientNotification = (*RootsListChangedNotification)(nil)

// ClientResult types
var _ ClientResult = &EmptyResult{}
var _ ClientResult = &CreateMessageResult{}
var _ ClientResult = &ListRootsResult{}
var _ ClientResult = (*EmptyResult)(nil)
var _ ClientResult = (*CreateMessageResult)(nil)
var _ ClientResult = (*ListRootsResult)(nil)

// ServerRequest types
var _ ServerRequest = &PingRequest{}
var _ ServerRequest = &CreateMessageRequest{}
var _ ServerRequest = &ListRootsRequest{}
var _ ServerRequest = (*PingRequest)(nil)
var _ ServerRequest = (*CreateMessageRequest)(nil)
var _ ServerRequest = (*ListRootsRequest)(nil)

// ServerNotification types
var _ ServerNotification = &CancelledNotification{}
var _ ServerNotification = &ProgressNotification{}
var _ ServerNotification = &LoggingMessageNotification{}
var _ ServerNotification = &ResourceUpdatedNotification{}
var _ ServerNotification = &ResourceListChangedNotification{}
var _ ServerNotification = &ToolListChangedNotification{}
var _ ServerNotification = &PromptListChangedNotification{}
var _ ServerNotification = (*CancelledNotification)(nil)
var _ ServerNotification = (*ProgressNotification)(nil)
var _ ServerNotification = (*LoggingMessageNotification)(nil)
var _ ServerNotification = (*ResourceUpdatedNotification)(nil)
var _ ServerNotification = (*ResourceListChangedNotification)(nil)
var _ ServerNotification = (*ToolListChangedNotification)(nil)
var _ ServerNotification = (*PromptListChangedNotification)(nil)

// ServerResult types
var _ ServerResult = &EmptyResult{}
var _ ServerResult = &InitializeResult{}
var _ ServerResult = &CompleteResult{}
var _ ServerResult = &GetPromptResult{}
var _ ServerResult = &ListPromptsResult{}
var _ ServerResult = &ListResourcesResult{}
var _ ServerResult = &ReadResourceResult{}
var _ ServerResult = &CallToolResult{}
var _ ServerResult = &ListToolsResult{}
var _ ServerResult = (*EmptyResult)(nil)
var _ ServerResult = (*InitializeResult)(nil)
var _ ServerResult = (*CompleteResult)(nil)
var _ ServerResult = (*GetPromptResult)(nil)
var _ ServerResult = (*ListPromptsResult)(nil)
var _ ServerResult = (*ListResourcesResult)(nil)
var _ ServerResult = (*ReadResourceResult)(nil)
var _ ServerResult = (*CallToolResult)(nil)
var _ ServerResult = (*ListToolsResult)(nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Heads-up: These lines do not enforce interface conformance because Client/Server are aliases to any**

In mcp/types.go, the following are defined as type aliases to any:

  • ClientRequest, ClientNotification, ClientResult
  • ServerRequest, ServerNotification, ServerResult

Given that, declarations like var _ ClientRequest = (*PingRequest)(nil) always type-check and do not provide compile-time interface enforcement. If these lines are meant purely as documentation/grouping, this refactor is fine. If the intent is to enforce conformance, consider replacing the any aliases with marker interfaces and implementing them on the relevant types.

Example approach (separate follow-up PR):

  • Define marker interfaces:
    • type ClientRequest interface{ isClientRequest() }
    • type ServerRequest interface{ isServerRequest() }
    • … similarly for Notification and Result
  • Add empty method receivers on each concrete type:
    • func (*PingRequest) isClientRequest() {}
    • etc.

Alternatively, if the aim is just to avoid allocations while retaining the “catalog,” consider adding a brief comment explaining that these are non-enforcing catalogs of types.

You can verify the current aliases with this script:


🏁 Script executed:

#!/bin/bash
# Verify that Client*/Server* types are aliases to `any`
set -euo pipefail

echo "Searching for any-alias declarations for Client*/Server*…"
rg -n -A 1 -B 1 $'type\\s+(ClientRequest|ClientNotification|ClientResult|ServerRequest|ServerNotification|ServerResult)\\s+any'

echo
echo "If the above matches show aliases to 'any', these assertions do not enforce interface conformance."

Length of output: 1464


Enforce compile-time checks for Client/Server types
The aliases in mcp/types.go (lines 1110–1125)

type ClientRequest any
type ClientNotification anytype ServerResult any

mean that the assertions in mcp/utils.go (lines 10–58)

var _ ClientRequest = (*PingRequest)(nil)
…
var _ ServerResult  = (*ListToolsResult)(nil)

are purely documentation and do not provide compile-time interface enforcement.

To fix this, either:

• Replace each any alias with a marker interface in mcp/types.go:

- type ClientRequest any
+ type ClientRequest interface { isClientRequest() }

(and likewise for ClientNotification, ClientResult, ServerRequest, etc.)

• Implement the empty methods on each concrete type—e.g. in mcp/utils.go:

func (*PingRequest) isClientRequest() {}
func (*InitializeRequest) isClientRequest() {}
// …and so on for every ClientRequest type

Or, if you only intended a non-enforcing catalog of types, please add a clarifying comment above the assertion block in mcp/utils.go.

🤖 Prompt for AI Agents
In mcp/utils.go around lines 10–58 the var _ Type = (*Concrete)(nil) assertions
are no-ops because the corresponding aliases in mcp/types.go (lines ~1110–1125)
use `type ClientRequest any` (and similar), so they do not enforce compile-time
checks; choose one of three fixes: (1) change each alias in mcp/types.go into a
marker interface (e.g. type ClientRequest interface { isClientRequest() }) and
keep the current assertions; or (2) implement the empty marker methods on every
concrete type listed in mcp/utils.go (e.g. add isClientRequest methods on
PingRequest, InitializeRequest, etc., and analogous methods for
ClientNotification/ClientResult/ServerRequest/ServerNotification/ServerResult)
so the assertions become real; or (3) if enforcement is not desired, add a clear
comment above the assertion block stating these are only documentation and will
not be enforced, so reviewers know it is intentional.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant