Skip to content

Commit d97f6f7

Browse files
authored
Merge branch 'main' into fix-get-me-empty-arguments
2 parents d6c154f + 3778a41 commit d97f6f7

11 files changed

Lines changed: 118 additions & 18 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,7 @@ The following sets of tools are available:
12781278
- **create_or_update_file** - Create or update file
12791279
- **Required OAuth Scopes**: `repo`
12801280
- `branch`: Branch to create/update the file in (string, required)
1281-
- `content`: Content of the file (string, required)
1281+
- `content`: Content of the file, exactly as it should appear once written. Do not base64-encode it; this server does that before calling the REST API. (string, required)
12821282
- `message`: Commit message (string, required)
12831283
- `owner`: Repository owner (username or organization) (string, required)
12841284
- `path`: Path where to create/update the file (string, required)

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ require (
1010
github.com/josephburnett/jd/v2 v2.5.0
1111
github.com/lithammer/fuzzysearch v1.1.8
1212
github.com/microcosm-cc/bluemonday v1.0.27
13-
github.com/modelcontextprotocol/go-sdk v1.7.0-pre.3
13+
github.com/modelcontextprotocol/go-sdk v1.7.0
1414
github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021
1515
github.com/shurcooL/githubv4 v0.0.0-20240727222349-48295856cce7
1616
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8
3939
github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
4040
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
4141
github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
42-
github.com/modelcontextprotocol/go-sdk v1.7.0-pre.3 h1:SEAY9IduDif4iApnZgpFkjFIdo3askSGZVbZIYyTy6I=
43-
github.com/modelcontextprotocol/go-sdk v1.7.0-pre.3/go.mod h1:dL7u98E/zjJTGzEq+j30jQ8K2k1mb6LeAH4inEcSGts=
42+
github.com/modelcontextprotocol/go-sdk v1.7.0 h1:yqjY2dsbKAC0LSuWZVBMrHgiG8ukXv6NRo0JiALay44=
43+
github.com/modelcontextprotocol/go-sdk v1.7.0/go.mod h1:dL7u98E/zjJTGzEq+j30jQ8K2k1mb6LeAH4inEcSGts=
4444
github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021 h1:31Y+Yu373ymebRdJN1cWLLooHH8xAr0MhKTEJGV/87g=
4545
github.com/muesli/cache2go v0.0.0-20221011235721-518229cd8021/go.mod h1:WERUkUryfUWlrHnFSO/BEUZ+7Ns8aZy7iVOGewxKzcc=
4646
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=

pkg/github/__toolsnaps__/create_or_update_file.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"type": "string"
1313
},
1414
"content": {
15-
"description": "Content of the file",
15+
"description": "Content of the file, exactly as it should appear once written. Do not base64-encode it; this server does that before calling the REST API.",
1616
"type": "string"
1717
},
1818
"message": {

pkg/github/repositories.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ SHA MUST be provided for existing file updates.
436436
},
437437
"content": {
438438
Type: "string",
439-
Description: "Content of the file",
439+
Description: "Content of the file, exactly as it should appear once written. Do not base64-encode it; this server does that before calling the REST API.",
440440
},
441441
"message": {
442442
Type: "string",

pkg/github/server.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,18 @@ func NewMCPServer(ctx context.Context, cfg *MCPServerConfig, deps ToolDependenci
8989
Instructions: inv.Instructions(),
9090
Logger: cfg.Logger,
9191
CompletionHandler: CompletionsHandler(deps.GetClient),
92+
// Advertise tools, prompts, and resources without list-changed
93+
// notifications. The server has a static set of tools/prompts/resources
94+
// and never mutates them at runtime, so it never emits list_changed
95+
// notifications. Left unset, the SDK would infer listChanged:true from
96+
// the presence of items and advertise a capability we don't support -
97+
// which the 2026-07-28 spec (subscriptions/listen) makes stricter still.
98+
// Explicitly declaring these keeps the advertised capabilities honest.
99+
Capabilities: &mcp.ServerCapabilities{
100+
Tools: &mcp.ToolCapabilities{},
101+
Prompts: &mcp.PromptCapabilities{},
102+
Resources: &mcp.ResourceCapabilities{},
103+
},
92104
}
93105

94106
// Apply any additional server options

pkg/github/server_test.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"testing"
1212
"time"
1313

14+
"github.com/github/github-mcp-server/pkg/inventory"
1415
"github.com/github/github-mcp-server/pkg/lockdown"
1516
"github.com/github/github-mcp-server/pkg/observability"
1617
"github.com/github/github-mcp-server/pkg/observability/metrics"
@@ -191,6 +192,97 @@ func TestNewMCPServer_CreatesSuccessfully(t *testing.T) {
191192
// is already tested in pkg/github/*_test.go.
192193
}
193194

195+
// advertisedServerCapabilities connects an in-memory client to the given server
196+
// and returns the capabilities the server advertised during initialization.
197+
func advertisedServerCapabilities(t *testing.T, server *mcp.Server) *mcp.ServerCapabilities {
198+
t.Helper()
199+
200+
ctx := context.Background()
201+
clientTransport, serverTransport := mcp.NewInMemoryTransports()
202+
203+
serverSession, err := server.Connect(ctx, serverTransport, nil)
204+
require.NoError(t, err, "expected server to connect")
205+
t.Cleanup(func() { _ = serverSession.Close() })
206+
207+
client := mcp.NewClient(&mcp.Implementation{Name: "test-client", Version: "1.0.0"}, nil)
208+
clientSession, err := client.Connect(ctx, clientTransport, nil)
209+
require.NoError(t, err, "expected client to connect")
210+
t.Cleanup(func() { _ = clientSession.Close() })
211+
212+
result := clientSession.InitializeResult()
213+
require.NotNil(t, result, "expected an initialize result")
214+
return result.Capabilities
215+
}
216+
217+
// TestNewMCPServer_AdvertisedCapabilities locks in the capability contract set by
218+
// NewMCPServer: tools, prompts, and resources are advertised without list-changed
219+
// notifications (the server has a static item set and never emits list_changed),
220+
// the deprecated logging capability is not advertised, and the inferred
221+
// completions capability is preserved. This is asserted for both the stdio path
222+
// (full inventory, items present) and the HTTP path (inventory emptied for the
223+
// discovery/initialize request), which share the same NewMCPServer entry point.
224+
func TestNewMCPServer_AdvertisedCapabilities(t *testing.T) {
225+
t.Parallel()
226+
227+
cfg := MCPServerConfig{
228+
Version: "test",
229+
Token: "test-token",
230+
EnabledToolsets: []string{"context"},
231+
Translator: translations.NullTranslationHelper,
232+
ContentWindowSize: 5000,
233+
}
234+
235+
deps := stubDeps{obsv: stubExporters()}
236+
237+
fullInventory, err := NewInventory(cfg.Translator).
238+
WithDeprecatedAliases(DeprecatedToolAliases).
239+
WithToolsets(cfg.EnabledToolsets).
240+
Build()
241+
require.NoError(t, err, "expected inventory build to succeed")
242+
243+
tests := []struct {
244+
name string
245+
inv *inventory.Inventory
246+
}{
247+
{
248+
name: "stdio path with registered items",
249+
inv: fullInventory,
250+
},
251+
{
252+
// The HTTP handler registers only the items relevant to a request;
253+
// for initialize/discover that is nothing, so capabilities must come
254+
// from the explicit declaration rather than being inferred from items.
255+
name: "http path with no registered items for discovery",
256+
inv: fullInventory.ForMCPRequest(inventory.MCPMethodDiscover, ""),
257+
},
258+
}
259+
260+
for _, tt := range tests {
261+
t.Run(tt.name, func(t *testing.T) {
262+
t.Parallel()
263+
264+
server, err := NewMCPServer(context.Background(), &cfg, deps, tt.inv)
265+
require.NoError(t, err, "expected server creation to succeed")
266+
267+
caps := advertisedServerCapabilities(t, server)
268+
269+
require.NotNil(t, caps.Tools, "tools capability should be advertised")
270+
assert.False(t, caps.Tools.ListChanged, "tools list-changed must not be advertised")
271+
272+
require.NotNil(t, caps.Prompts, "prompts capability should be advertised")
273+
assert.False(t, caps.Prompts.ListChanged, "prompts list-changed must not be advertised")
274+
275+
require.NotNil(t, caps.Resources, "resources capability should be advertised")
276+
assert.False(t, caps.Resources.ListChanged, "resources list-changed must not be advertised")
277+
assert.False(t, caps.Resources.Subscribe, "resources subscribe must not be advertised")
278+
279+
assert.NotNil(t, caps.Completions, "completions capability should be preserved")
280+
// Intentionally asserting the deprecated logging capability is absent.
281+
assert.Nil(t, caps.Logging, "deprecated logging capability should not be advertised") //nolint:staticcheck // SA1019: verifying the deprecated capability is not advertised
282+
})
283+
}
284+
}
285+
194286
// TestNewServer_NameAndTitleViaTranslation verifies that server name and title
195287
// can be overridden via the translation helper (GITHUB_MCP_SERVER_NAME /
196288
// GITHUB_MCP_SERVER_TITLE env vars or github-mcp-server-config.json) and

pkg/http/handler.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,10 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
205205
ContentWindowSize: h.config.ContentWindowSize,
206206
Logger: h.logger,
207207
RepoAccessTTL: h.config.RepoAccessCacheTTL,
208-
// Explicitly set empty capabilities. inv.ForMCPRequest currently returns nothing for Initialize.
208+
// Capabilities (no list-changed advertising) are set by NewMCPServer;
209+
// here we only supply the remote-specific schema cache.
209210
ServerOptions: []github.MCPServerOption{
210211
func(so *mcp.ServerOptions) {
211-
so.Capabilities = &mcp.ServerCapabilities{
212-
Tools: &mcp.ToolCapabilities{},
213-
Resources: &mcp.ResourceCapabilities{},
214-
Prompts: &mcp.PromptCapabilities{},
215-
}
216212
so.SchemaCache = h.schemaCache
217213
},
218214
},

third-party-licenses.darwin.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ The following packages are included for the amd64, arm64 architectures.
2424
- [github.com/josephburnett/jd/v2](https://pkg.go.dev/github.com/josephburnett/jd/v2) ([MIT](https://github.com/josephburnett/jd/blob/v2.5.0/v2/LICENSE))
2525
- [github.com/lithammer/fuzzysearch/fuzzy](https://pkg.go.dev/github.com/lithammer/fuzzysearch/fuzzy) ([MIT](https://github.com/lithammer/fuzzysearch/blob/v1.1.8/LICENSE))
2626
- [github.com/microcosm-cc/bluemonday](https://pkg.go.dev/github.com/microcosm-cc/bluemonday) ([BSD-3-Clause](https://github.com/microcosm-cc/bluemonday/blob/v1.0.27/LICENSE.md))
27-
- [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0-pre.3/LICENSE))
28-
- [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0-pre.3/LICENSE))
27+
- [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0/LICENSE))
28+
- [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0/LICENSE))
2929
- [github.com/muesli/cache2go](https://pkg.go.dev/github.com/muesli/cache2go) ([BSD-3-Clause](https://github.com/muesli/cache2go/blob/518229cd8021/LICENSE.txt))
3030
- [github.com/pelletier/go-toml/v2](https://pkg.go.dev/github.com/pelletier/go-toml/v2) ([MIT](https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE))
3131
- [github.com/sagikazarmark/locafero](https://pkg.go.dev/github.com/sagikazarmark/locafero) ([MIT](https://github.com/sagikazarmark/locafero/blob/v0.11.0/LICENSE))

third-party-licenses.linux.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ The following packages are included for the 386, amd64, arm64 architectures.
2424
- [github.com/josephburnett/jd/v2](https://pkg.go.dev/github.com/josephburnett/jd/v2) ([MIT](https://github.com/josephburnett/jd/blob/v2.5.0/v2/LICENSE))
2525
- [github.com/lithammer/fuzzysearch/fuzzy](https://pkg.go.dev/github.com/lithammer/fuzzysearch/fuzzy) ([MIT](https://github.com/lithammer/fuzzysearch/blob/v1.1.8/LICENSE))
2626
- [github.com/microcosm-cc/bluemonday](https://pkg.go.dev/github.com/microcosm-cc/bluemonday) ([BSD-3-Clause](https://github.com/microcosm-cc/bluemonday/blob/v1.0.27/LICENSE.md))
27-
- [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0-pre.3/LICENSE))
28-
- [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0-pre.3/LICENSE))
27+
- [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([Apache-2.0](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0/LICENSE))
28+
- [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) ([MIT](https://github.com/modelcontextprotocol/go-sdk/blob/v1.7.0/LICENSE))
2929
- [github.com/muesli/cache2go](https://pkg.go.dev/github.com/muesli/cache2go) ([BSD-3-Clause](https://github.com/muesli/cache2go/blob/518229cd8021/LICENSE.txt))
3030
- [github.com/pelletier/go-toml/v2](https://pkg.go.dev/github.com/pelletier/go-toml/v2) ([MIT](https://github.com/pelletier/go-toml/blob/v2.2.4/LICENSE))
3131
- [github.com/sagikazarmark/locafero](https://pkg.go.dev/github.com/sagikazarmark/locafero) ([MIT](https://github.com/sagikazarmark/locafero/blob/v0.11.0/LICENSE))

0 commit comments

Comments
 (0)