Skip to content

Commit 945d0a5

Browse files
Merge branch 'main' into guglielmoc/SEP-2207_OIDC-flavored
2 parents 88d77d3 + 2b7c993 commit 945d0a5

11 files changed

Lines changed: 143 additions & 12 deletions

File tree

.github/workflows/codeql.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ jobs:
3838
- name: Checkout repository
3939
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
4040
- name: Initialize CodeQL
41-
uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
41+
uses: github/codeql-action/init@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
4242
with:
4343
languages: ${{ matrix.language }}
4444
build-mode: ${{ matrix.build-mode }}
4545
- name: Perform CodeQL Analysis
46-
uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
46+
uses: github/codeql-action/analyze@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
4747
with:
4848
category: "/language:${{matrix.language}}"

.github/workflows/nightly.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
with:
3030
go-version: "^1.26"
3131
- name: Set up Node.js
32-
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
32+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
3333
with:
3434
node-version: "22"
3535
- name: Run server conformance tests

.github/workflows/publish-docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
with:
2323
python-version: 3.x
2424
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
25-
- uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
25+
- uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
2626
with:
2727
key: mkdocs-material-${{ env.cache_id }}
2828
path: .cache

.github/workflows/scorecard.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ jobs:
6464
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
6565
# format to the repository Actions tab.
6666
- name: "Upload artifact"
67-
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
67+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
6868
with:
6969
name: SARIF file
7070
path: results.sarif
@@ -73,6 +73,6 @@ jobs:
7373
# Upload the results to GitHub's code scanning dashboard (optional).
7474
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
7575
- name: "Upload to code-scanning"
76-
uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
76+
uses: github/codeql-action/upload-sarif@95e58e9a2cdfd71adc6e0353d5c52f41a045d225 # v4.35.2
7777
with:
7878
sarif_file: results.sarif

docs/mcpgodebug.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@
1818

1919
## `MCPGODEBUG` history
2020

21+
### 1.7.0
22+
23+
Options listed below were added and will be removed in the 1.9.0 version of the SDK.
24+
25+
- `customresnotfounderrcode` added. If set to `1`, `ResourceNotFoundError` will
26+
use the custom error code `-32002` instead of the standard `-32602` (Invalid
27+
Params), restoring the previous behavior. The default behavior was changed to
28+
align with SEP-2164 and the JSON-RPC specification.
29+
2130
### 1.6.0
2231

2332
Options listed below were added and will be removed in the 1.8.0 version of the SDK.

internal/docs/mcpgodebug.src.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@
1717

1818
## `MCPGODEBUG` history
1919

20+
### 1.7.0
21+
22+
Options listed below were added and will be removed in the 1.9.0 version of the SDK.
23+
24+
- `customresnotfounderrcode` added. If set to `1`, `ResourceNotFoundError` will
25+
use the custom error code `-32002` instead of the standard `-32602` (Invalid
26+
Params), restoring the previous behavior. The default behavior was changed to
27+
align with SEP-2164 and the JSON-RPC specification.
28+
2029
### 1.6.0
2130

2231
Options listed below were added and will be removed in the 1.8.0 version of the SDK.

mcp/error_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,22 @@ func TestServerErrors(t *testing.T) {
111111
}
112112
}
113113

114+
// TestResourceNotFoundErrorCode verifies ResourceNotFoundError code and
115+
// CodeResourceNotFound are -32602 (InvalidParams) per SEP-2164.
116+
func TestResourceNotFoundErrorCode(t *testing.T) {
117+
err := ResourceNotFoundError("file:///test.txt")
118+
var rpcErr *jsonrpc.Error
119+
if !errors.As(err, &rpcErr) {
120+
t.Fatalf("got error type %T, want *jsonrpc.Error", err)
121+
}
122+
if rpcErr.Code != jsonrpc.CodeInvalidParams {
123+
t.Errorf("got error code %d, want %d (InvalidParams)", rpcErr.Code, jsonrpc.CodeInvalidParams)
124+
}
125+
if CodeResourceNotFound != jsonrpc.CodeInvalidParams {
126+
t.Errorf("CodeResourceNotFound = %d, want %d", CodeResourceNotFound, jsonrpc.CodeInvalidParams)
127+
}
128+
}
129+
114130
// TestInputValidationToolError validates that input validation errors (missing
115131
// required params, wrong types) are returned as tool results with IsError=true,
116132
// not as JSON-RPC errors. This allows LLMs to see the error and self-correct.

mcp/resource.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"path/filepath"
1616
"strings"
1717

18+
"github.com/modelcontextprotocol/go-sdk/internal/mcpgodebug"
1819
"github.com/modelcontextprotocol/go-sdk/internal/util"
1920
"github.com/modelcontextprotocol/go-sdk/jsonrpc"
2021
"github.com/yosida95/uritemplate/v3"
@@ -37,8 +38,25 @@ type serverResourceTemplate struct {
3738
// If it cannot find the resource, it should return the result of calling [ResourceNotFoundError].
3839
type ResourceHandler func(context.Context, *ReadResourceRequest) (*ReadResourceResult, error)
3940

41+
// customresnotfounderrcode is a compatibility parameter that restores the
42+
// pre-1.7.0 behavior of [ResourceNotFoundError] and [CodeResourceNotFound],
43+
// where the error code was a custom -32002. See the documentation for the mcpgodebug
44+
// package for instructions on how to enable it.
45+
// The option will be removed in the future version of the SDK.
46+
var customresnotfounderrcode = mcpgodebug.Value("customresnotfounderrcode")
47+
48+
func init() {
49+
if customresnotfounderrcode == "1" {
50+
CodeResourceNotFound = -32002
51+
}
52+
}
53+
4054
// ResourceNotFoundError returns an error indicating that a resource being read could
4155
// not be found.
56+
//
57+
// By default, the error code is -32602 (Invalid Params), as specified in the
58+
// MCP specification (SEP-2164). To restore the pre-1.7.0 release behavior where the
59+
// error code was -32002, set MCPGODEBUG=customresnotfounderrcode=1.
4260
func ResourceNotFoundError(uri string) error {
4361
return &jsonrpc.Error{
4462
Code: CodeResourceNotFound,

mcp/shared.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,14 +347,22 @@ const (
347347
// CodeHeaderMismatch indicates that HTTP headers do not match the corresponding values
348348
// in the request body, or that required headers are missing or malformed.
349349
CodeHeaderMismatch = -32001
350-
// CodeResourceNotFound indicates that a requested resource could not be found.
351-
CodeResourceNotFound = -32002
352350
// CodeURLElicitationRequired indicates that the server requires URL elicitation
353351
// before processing the request. The client should execute the elicitation handler
354352
// with the elicitations provided in the error data.
355353
CodeURLElicitationRequired = -32042
356354
)
357355

356+
// CodeResourceNotFound indicates that a requested resource could not be found.
357+
//
358+
// By default, the value is -32602 (Invalid Params), as specified in the
359+
// MCP specification (SEP-2164). To restore the pre-1.7.0 release behavior where the
360+
// error code was -32002, set MCPGODEBUG=customresnotfounderrcode=1.
361+
//
362+
// Deprecated: Use [jsonrpc.CodeInvalidParams] directly. This variable will be
363+
// removed in a future version.
364+
var CodeResourceNotFound int64 = jsonrpc.CodeInvalidParams
365+
358366
// URLElicitationRequiredError returns an error indicating that URL elicitation is required
359367
// before the request can be processed. The elicitations parameter should contain the
360368
// elicitation requests that must be completed.

mcp/streamable.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"github.com/modelcontextprotocol/go-sdk/internal/util"
3838
"github.com/modelcontextprotocol/go-sdk/internal/xcontext"
3939
"github.com/modelcontextprotocol/go-sdk/jsonrpc"
40+
"golang.org/x/oauth2"
4041
)
4142

4243
// A StreamableHTTPHandler is an http.Handler that serves streamable MCP
@@ -1803,6 +1804,7 @@ func (c *streamableClientConn) Write(ctx context.Context, msg jsonrpc.Message) e
18031804
}
18041805
req.Header.Set("Content-Type", "application/json")
18051806
req.Header.Set("Accept", "application/json, text/event-stream")
1807+
18061808
if err := c.setMCPHeaders(req); err != nil {
18071809
// Failure to set headers means that the request was not sent.
18081810
// Wrap with ErrRejected so the jsonrpc2 connection doesn't set writeErr
@@ -1934,9 +1936,20 @@ func (c *streamableClientConn) setMCPHeaders(req *http.Request) error {
19341936
if ts != nil {
19351937
token, err := ts.Token()
19361938
if err != nil {
1937-
return err
1938-
}
1939-
if token != nil {
1939+
// If the error is an invalid_grant oauth2.RetrieveError it indicates
1940+
// that the token source doesn't have valid authorization for the token
1941+
// endpoint, per RFC 6749 section 5.2. For example, the refresh token
1942+
// may be expired or invalid.
1943+
//
1944+
// In that case, ignore the error, skip setting the Authorization
1945+
// header, and proceed with the request. Callers that support
1946+
// authorization flows get a 401/403 response and trigger the
1947+
// Authorize() flow to refresh their token.
1948+
var retrieveErr *oauth2.RetrieveError
1949+
if !errors.As(err, &retrieveErr) || retrieveErr.ErrorCode != "invalid_grant" {
1950+
return err
1951+
}
1952+
} else if token != nil {
19401953
req.Header.Set("Authorization", "Bearer "+token.AccessToken)
19411954
}
19421955
}
@@ -2236,8 +2249,10 @@ func (c *streamableClientConn) Close() error {
22362249
} else {
22372250
if err := c.setMCPHeaders(req); err != nil {
22382251
c.closeErr = err
2239-
} else if _, err := c.client.Do(req); err != nil {
2252+
} else if resp, err := c.client.Do(req); err != nil {
22402253
c.closeErr = err
2254+
} else {
2255+
resp.Body.Close()
22412256
}
22422257
}
22432258
}

0 commit comments

Comments
 (0)