Skip to content

refactor: Pull out Annotations structure rather than being an anonymous inner struct #203

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

Merged
merged 1 commit into from
Apr 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions mcp/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,7 @@ func WithMIMEType(mimeType string) ResourceOption {
func WithAnnotations(audience []Role, priority float64) ResourceOption {
return func(r *Resource) {
if r.Annotations == nil {
r.Annotations = &struct {
Audience []Role `json:"audience,omitempty"`
Priority float64 `json:"priority,omitempty"`
}{}
r.Annotations = &Annotations{}
}
r.Annotations.Audience = audience
r.Annotations.Priority = priority
Expand Down Expand Up @@ -94,10 +91,7 @@ func WithTemplateMIMEType(mimeType string) ResourceTemplateOption {
func WithTemplateAnnotations(audience []Role, priority float64) ResourceTemplateOption {
return func(t *ResourceTemplate) {
if t.Annotations == nil {
t.Annotations = &struct {
Audience []Role `json:"audience,omitempty"`
Priority float64 `json:"priority,omitempty"`
}{}
t.Annotations = &Annotations{}
}
t.Annotations.Audience = audience
t.Annotations.Priority = priority
Expand Down
30 changes: 16 additions & 14 deletions mcp/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -659,24 +659,26 @@ type SamplingMessage struct {
Content interface{} `json:"content"` // Can be TextContent or ImageContent
}

type Annotations struct {
// Describes who the intended customer of this object or data is.
//
// It can include multiple entries to indicate content useful for multiple
// audiences (e.g., `["user", "assistant"]`).
Audience []Role `json:"audience,omitempty"`

// Describes how important this data is for operating the server.
//
// A value of 1 means "most important," and indicates that the data is
// effectively required, while 0 means "least important," and indicates that
// the data is entirely optional.
Priority float64 `json:"priority,omitempty"`
}

// Annotated is the base for objects that include optional annotations for the
// client. The client can use annotations to inform how objects are used or
// displayed
type Annotated struct {
Annotations *struct {
// Describes who the intended customer of this object or data is.
//
// It can include multiple entries to indicate content useful for multiple
// audiences (e.g., `["user", "assistant"]`).
Audience []Role `json:"audience,omitempty"`

// Describes how important this data is for operating the server.
//
// A value of 1 means "most important," and indicates that the data is
// effectively required, while 0 means "least important," and indicates that
// the data is entirely optional.
Priority float64 `json:"priority,omitempty"`
} `json:"annotations,omitempty"`
Annotations *Annotations `json:"annotations,omitempty"`
}
Comment on lines 680 to 682
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

Consider documenting this breaking change.

Changing Annotations from an inline anonymous struct to a pointer to a named struct is a breaking change that could affect existing code. Any code that directly accessed the fields of the anonymous struct now needs to handle potential nil pointers.


🏁 Script executed:

#!/bin/bash
# Search for code that might be affected by this change
rg -A2 "\.Annotations\." --type go

Length of output: 329


🏁 Script executed:

#!/bin/bash
# Inspect context around usage of r.Annotations.Audience
rg -n -C3 "r\.Annotations\.Audience" mcp/resources.go

# Inspect context around usage of t.Annotations.Audience
rg -n -C3 "t\.Annotations\.Audience" mcp/resources.go

# Search for nil-checks or initialization of Annotations pointers
rg -n -C3 "Annotations == nil" --type go
rg -n -C3 "Annotations = &Annotations" --type go

Length of output: 2195


Document Breaking Change to Annotations Field

Changing Annotations from an inline struct to a *Annotations pointer is a breaking change. Any code that previously did:

r := Resource{}
// r.Annotations.Priority == 0

will now panic on r.Annotations.Priority because r.Annotations can be nil.

Please update your documentation and migration guide:

• Add a note under Breaking Changes in CHANGELOG.md (or RELEASE_NOTES) that the Annotations field is now a pointer.
• In README or docs, advise users to initialize with WithAnnotations(...) or check for nil before accessing fields.
• (Optional) Consider adding a custom UnmarshalJSON on Annotated to default the pointer.

Affected locations:

  • mcp/types.go at type Annotated struct { Annotations *Annotations ... }
  • mcp/resources.go builder funcs already guard against nil, but any unmarshaled or literal Annotated must be initialized.


type Content interface {
Expand Down