Skip to content

Commit 6935039

Browse files
authored
Merge pull request #166 from olaservo/structured-output-2026-07-28/go
Add structured content to the Go weather server and client and update to latest SDK and protocol version
2 parents 7fbffb1 + 1e6af87 commit 6935039

8 files changed

Lines changed: 256 additions & 115 deletions

File tree

mcp-client-go/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
# An LLM-Powered Chatbot MCP Client written in Go
22

33
See the [Build an MCP client](https://modelcontextprotocol.io/docs/develop/build-client) tutorial for more information.
4+
5+
## Structured content
6+
7+
The SDK does not validate tool output, so this client compiles each declared `outputSchema` at connect time and checks results against it — the spec's client-side SHOULD. It uses [`jsonschema-go`](https://pkg.go.dev/github.com/google/jsonschema-go/jsonschema), already an SDK dependency.
8+
9+
The two channels go to different readers: `Content` is forwarded to the model, while `StructuredContent` is used as data — the client counts the items it returns. See [Structured Content](https://modelcontextprotocol.io/specification/2026-07-28/server/tools#structured-content).

mcp-client-go/go.mod

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@ go 1.25.1
44

55
require (
66
github.com/anthropics/anthropic-sdk-go v1.14.0
7+
github.com/google/jsonschema-go v0.4.3
78
github.com/joho/godotenv v1.5.1
8-
github.com/modelcontextprotocol/go-sdk v1.4.1
9+
github.com/modelcontextprotocol/go-sdk v1.7.0
910
)
1011

1112
require (
12-
github.com/google/jsonschema-go v0.4.2 // indirect
1313
github.com/segmentio/asm v1.1.3 // indirect
1414
github.com/segmentio/encoding v0.5.4 // indirect
1515
github.com/tidwall/gjson v1.18.0 // indirect
1616
github.com/tidwall/match v1.1.1 // indirect
1717
github.com/tidwall/pretty v1.2.1 // indirect
1818
github.com/tidwall/sjson v1.2.5 // indirect
1919
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
20-
golang.org/x/oauth2 v0.34.0 // indirect
21-
golang.org/x/sys v0.40.0 // indirect
20+
golang.org/x/oauth2 v0.35.0 // indirect
21+
golang.org/x/sync v0.20.0 // indirect
22+
golang.org/x/sys v0.41.0 // indirect
23+
golang.org/x/time v0.15.0 // indirect
2224
)

mcp-client-go/go.sum

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ github.com/anthropics/anthropic-sdk-go v1.14.0 h1:EzNQvnZlaDHe2UPkoUySDz3ixRgNbw
22
github.com/anthropics/anthropic-sdk-go v1.14.0/go.mod h1:WTz31rIUHUHqai2UslPpw5CwXrQP3geYBioRV4WOLvE=
33
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
44
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5-
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
6-
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
5+
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
6+
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
77
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
88
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
9-
github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8=
10-
github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
9+
github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0=
10+
github.com/google/jsonschema-go v0.4.3/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
1111
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
1212
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
13-
github.com/modelcontextprotocol/go-sdk v1.4.1 h1:M4x9GyIPj+HoIlHNGpK2hq5o3BFhC+78PkEaldQRphc=
14-
github.com/modelcontextprotocol/go-sdk v1.4.1/go.mod h1:Bo/mS87hPQqHSRkMv4dQq1XCu6zv4INdXnFZabkNU6s=
13+
github.com/modelcontextprotocol/go-sdk v1.7.0 h1:yqjY2dsbKAC0LSuWZVBMrHgiG8ukXv6NRo0JiALay44=
14+
github.com/modelcontextprotocol/go-sdk v1.7.0/go.mod h1:dL7u98E/zjJTGzEq+j30jQ8K2k1mb6LeAH4inEcSGts=
1515
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1616
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1717
github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc=
@@ -32,11 +32,15 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
3232
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
3333
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
3434
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
35-
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
36-
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
37-
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
38-
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
39-
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
40-
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
35+
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
36+
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
37+
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
38+
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
39+
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
40+
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
41+
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
42+
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
43+
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
44+
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
4145
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
4246
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

mcp-client-go/main.go

Lines changed: 82 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,28 @@ import (
1212

1313
"github.com/anthropics/anthropic-sdk-go"
1414
"github.com/anthropics/anthropic-sdk-go/option"
15+
"github.com/google/jsonschema-go/jsonschema"
1516
"github.com/joho/godotenv"
1617
"github.com/modelcontextprotocol/go-sdk/mcp"
1718
)
1819

19-
var model anthropic.Model = anthropic.ModelClaudeSonnet4_5_20250929
20+
// A string literal rather than an anthropic.Model constant: the pinned SDK
21+
// version predates this model and has no constant for it.
22+
var model anthropic.Model = "claude-sonnet-5"
2023

2124
type MCPClient struct {
2225
anthropic *anthropic.Client
2326
session *mcp.ClientSession
2427
tools []anthropic.ToolUnionParam
28+
// Compiled outputSchema per tool name, for validating results.
29+
outputSchemas map[string]*jsonschema.Resolved
2530
}
2631

2732
func NewMCPClient() (*MCPClient, error) {
28-
// Load .env file
29-
if err := godotenv.Load(); err != nil {
30-
return nil, fmt.Errorf("failed to load .env file: %w", err)
31-
}
32-
33-
apiKey := os.Getenv("ANTHROPIC_API_KEY")
34-
if apiKey == "" {
35-
return nil, fmt.Errorf("ANTHROPIC_API_KEY environment variable not set")
36-
}
33+
// .env is optional; the key may come from the environment instead.
34+
_ = godotenv.Load()
3735

38-
client := anthropic.NewClient(option.WithAPIKey(apiKey))
36+
client := anthropic.NewClient(option.WithAPIKey(os.Getenv("ANTHROPIC_API_KEY")))
3937

4038
return &MCPClient{
4139
anthropic: &client,
@@ -80,13 +78,22 @@ func (c *MCPClient) ConnectToServer(ctx context.Context, serverArgs []string) er
8078
var toolNames []string
8179

8280
// Convert MCP tools to Anthropic tool format
81+
c.outputSchemas = make(map[string]*jsonschema.Resolved)
8382
for _, tool := range toolsResult.Tools {
8483
toolNames = append(toolNames, tool.Name)
8584
anthropicTool, err := mcpToolToAnthropicTool(tool)
8685
if err != nil {
8786
return fmt.Errorf("failed to convert mcp tool to anthropic tool: %w", err)
8887
}
8988
c.tools = append(c.tools, anthropicTool)
89+
90+
resolved, err := resolveOutputSchema(tool)
91+
if err != nil {
92+
return fmt.Errorf("failed to compile output schema of tool %s: %w", tool.Name, err)
93+
}
94+
if resolved != nil {
95+
c.outputSchemas[tool.Name] = resolved
96+
}
9097
}
9198

9299
fmt.Printf("Connected to server with tools: %v\n", toolNames)
@@ -116,6 +123,40 @@ func mcpToolToAnthropicTool(tool *mcp.Tool) (anthropic.ToolUnionParam, error) {
116123
}, nil
117124
}
118125

126+
// resolveOutputSchema compiles a tool's declared outputSchema, or returns
127+
// (nil, nil) when it declares none. OutputSchema is `any` because the root may
128+
// be any JSON Schema, so round-trip through JSON to accept every form.
129+
func resolveOutputSchema(tool *mcp.Tool) (*jsonschema.Resolved, error) {
130+
if tool.OutputSchema == nil {
131+
return nil, nil
132+
}
133+
raw, err := json.Marshal(tool.OutputSchema)
134+
if err != nil {
135+
return nil, fmt.Errorf("failed to marshal output schema: %w", err)
136+
}
137+
var schema jsonschema.Schema
138+
if err := json.Unmarshal(raw, &schema); err != nil {
139+
return nil, fmt.Errorf("failed to unmarshal output schema: %w", err)
140+
}
141+
return schema.Resolve(nil)
142+
}
143+
144+
// validateToolOutput checks a result against its tool's declared outputSchema.
145+
// Error results are exempt: they carry a message, not data.
146+
func (c *MCPClient) validateToolOutput(name string, result *mcp.CallToolResult) error {
147+
resolved, ok := c.outputSchemas[name]
148+
if !ok || result.IsError {
149+
return nil
150+
}
151+
if result.StructuredContent == nil {
152+
return fmt.Errorf("tool %s declares an output schema but returned no structured content", name)
153+
}
154+
if err := resolved.Validate(result.StructuredContent); err != nil {
155+
return fmt.Errorf("structured content from tool %s does not match its output schema: %w", name, err)
156+
}
157+
return nil
158+
}
159+
119160
func (c *MCPClient) ProcessQuery(ctx context.Context, query string) (string, error) {
120161
if c.session == nil {
121162
return "", fmt.Errorf("client is not connected to any server")
@@ -169,16 +210,27 @@ func (c *MCPClient) ProcessQuery(ctx context.Context, query string) (string, err
169210
return "", fmt.Errorf("tool call %s failed: %w", toolUseBlock.Name, err)
170211
}
171212

172-
// Serialize tool result
173-
resultJSON, err := json.Marshal(mcpToolResult)
174-
if err != nil {
175-
return "", fmt.Errorf("failed to serialize tool result: %w", err)
213+
if err := c.validateToolOutput(toolUseBlock.Name, mcpToolResult); err != nil {
214+
return "", err
215+
}
216+
217+
// StructuredContent is data the application can use directly.
218+
if items, ok := mcpToolResult.StructuredContent.([]any); ok {
219+
finalText = append(finalText, fmt.Sprintf("[%s returned %d items]", toolUseBlock.Name, len(items)))
220+
}
221+
222+
// Content is a list of block types; forward only the text ones.
223+
var texts []string
224+
for _, block := range mcpToolResult.Content {
225+
if text, ok := block.(*mcp.TextContent); ok {
226+
texts = append(texts, text.Text)
227+
}
176228
}
177229

178230
anthropicToolResults = append(anthropicToolResults, anthropic.NewToolResultBlock(
179231
toolUseBlock.ID,
180-
string(resultJSON),
181-
false,
232+
strings.Join(texts, "\n"),
233+
mcpToolResult.IsError,
182234
))
183235
}
184236

@@ -187,7 +239,7 @@ func (c *MCPClient) ProcessQuery(ctx context.Context, query string) (string, err
187239

188240
// Make another API call with tool results
189241
response, err = c.anthropic.Messages.New(ctx, anthropic.MessageNewParams{
190-
Model: anthropic.ModelClaude3_7SonnetLatest,
242+
Model: model,
191243
MaxTokens: 1024,
192244
Messages: messages,
193245
})
@@ -267,6 +319,18 @@ func main() {
267319
log.Fatalf("Failed to connect to MCP server: %v", err)
268320
}
269321

322+
// Connecting and listing tools needs no credentials; querying them does.
323+
// Matching the Python and TypeScript clients, report and exit rather than
324+
// failing, so the connection itself can be exercised without a key.
325+
if os.Getenv("ANTHROPIC_API_KEY") == "" {
326+
fmt.Println("\nNo ANTHROPIC_API_KEY found. To query these tools with Claude, set your API key:")
327+
fmt.Println(" export ANTHROPIC_API_KEY=your-api-key-here")
328+
if err := client.Cleanup(); err != nil {
329+
log.Printf("Cleanup error: %v", err)
330+
}
331+
return
332+
}
333+
270334
if err := client.ChatLoop(ctx); err != nil {
271335
log.Printf("ChatLoop error: %v", err)
272336
}

weather-server-go/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,11 @@ go build -o weather
1717
The server will communicate via stdio and expose two MCP tools:
1818
- `get_forecast` - Get weather forecast for a location (requires latitude and longitude)
1919
- `get_alerts` - Get weather alerts for a US state (requires two-letter state code)
20+
21+
## Structured content
22+
23+
Both tools advertise an `outputSchema` and return `StructuredContent`. `get_forecast` returns an object; `get_alerts` returns a top-level JSON array, which protocol revision `2026-07-28` is the first to allow — see [Structured Content](https://modelcontextprotocol.io/specification/2026-07-28/server/tools#structured-content) in the spec.
24+
25+
`get_forecast` sets no `OutputSchema` on the `Tool`: the SDK infers one from the handler's return type, which is the idiomatic Go spelling. `get_alerts` overrides it, because inference widens a slice to `["null", "array"]` — a nil slice marshals to `null` — and the tool never returns nil.
26+
27+
Note that an array-rooted schema requires a `2026-07-28` client: the SDK sends it as written on every connection rather than projecting it down, so an older client rejects the tool list.

weather-server-go/go.mod

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ module github.com/modelcontextprotocol/quickstart-resources/weather-server-go
22

33
go 1.25.1
44

5-
require github.com/modelcontextprotocol/go-sdk v1.4.1
5+
require (
6+
github.com/google/jsonschema-go v0.4.3
7+
github.com/modelcontextprotocol/go-sdk v1.7.0
8+
)
69

710
require (
8-
github.com/google/jsonschema-go v0.4.2 // indirect
911
github.com/segmentio/asm v1.1.3 // indirect
1012
github.com/segmentio/encoding v0.5.4 // indirect
1113
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
12-
golang.org/x/oauth2 v0.34.0 // indirect
13-
golang.org/x/sys v0.40.0 // indirect
14+
golang.org/x/oauth2 v0.35.0 // indirect
15+
golang.org/x/sync v0.20.0 // indirect
16+
golang.org/x/sys v0.41.0 // indirect
17+
golang.org/x/time v0.15.0 // indirect
1418
)

weather-server-go/go.sum

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,24 @@
1-
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
2-
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
1+
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
2+
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
33
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
44
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
5-
github.com/google/jsonschema-go v0.4.2 h1:tmrUohrwoLZZS/P3x7ex0WAVknEkBZM46iALbcqoRA8=
6-
github.com/google/jsonschema-go v0.4.2/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
7-
github.com/modelcontextprotocol/go-sdk v1.4.1 h1:M4x9GyIPj+HoIlHNGpK2hq5o3BFhC+78PkEaldQRphc=
8-
github.com/modelcontextprotocol/go-sdk v1.4.1/go.mod h1:Bo/mS87hPQqHSRkMv4dQq1XCu6zv4INdXnFZabkNU6s=
5+
github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0=
6+
github.com/google/jsonschema-go v0.4.3/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
7+
github.com/modelcontextprotocol/go-sdk v1.7.0 h1:yqjY2dsbKAC0LSuWZVBMrHgiG8ukXv6NRo0JiALay44=
8+
github.com/modelcontextprotocol/go-sdk v1.7.0/go.mod h1:dL7u98E/zjJTGzEq+j30jQ8K2k1mb6LeAH4inEcSGts=
99
github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc=
1010
github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg=
1111
github.com/segmentio/encoding v0.5.4 h1:OW1VRern8Nw6ITAtwSZ7Idrl3MXCFwXHPgqESYfvNt0=
1212
github.com/segmentio/encoding v0.5.4/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=
1313
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
1414
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
15-
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
16-
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
17-
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
18-
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
19-
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
20-
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
15+
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
16+
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
17+
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
18+
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
19+
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
20+
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
21+
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
22+
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
23+
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
24+
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=

0 commit comments

Comments
 (0)