Skip to content

Commit 6ec285a

Browse files
authored
Move MCP config from .mcp.json to .github/mcp.json (#26665)
1 parent cc2e417 commit 6ec285a

File tree

13 files changed

+53
-50
lines changed

13 files changed

+53
-50
lines changed

.mcp.json

Lines changed: 0 additions & 8 deletions
This file was deleted.

create.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ You do not need to run `gh aw init` as part of your workflow creation. However i
132132

133133
- `.github/agents/agentic-workflows.agent.md`
134134
- `.vscode/settings.json`
135-
- `.mcp.json`
135+
- `.github/mcp.json`
136136
- And several other configuration files
137137

138138
Don't remove these but don't add them if not already present in the repo. Unless instructed otherwise do NOT commit the changes to ANY files except the gitattributes file and workflow files.

docs/src/content/docs/reference/gh-aw-as-mcp-server.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ Configure VS Code Copilot Chat to use gh-aw MCP server:
6666
gh aw init
6767
```
6868

69-
This creates `.mcp.json` and `.github/workflows/copilot-setup-steps.yml`. MCP server integration is enabled by default. Use `gh aw init --no-mcp` to skip MCP configuration.
69+
This creates `.github/mcp.json` and `.github/workflows/copilot-setup-steps.yml`. MCP server integration is enabled by default. Use `gh aw init --no-mcp` to skip MCP configuration.
7070

71-
Alternatively, create `.mcp.json` manually:
71+
Alternatively, create `.github/mcp.json` manually:
7272

7373
```json wrap
7474
{

docs/src/content/docs/troubleshooting/errors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ Use `gh aw init my-workflow --force` to overwrite.
204204

205205
`failed to parse existing mcp.json: [details]`
206206

207-
Fix the JSON syntax (validate with `cat .mcp.json | jq .`) or delete the file to regenerate.
207+
Fix the JSON syntax (validate with `cat .github/mcp.json | jq .`) or delete the file to regenerate.
208208

209209
### Failed to Marshal MCP Config
210210

install.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ gh aw init
4545
- Configures `.gitattributes` to mark `.lock.yml` files as generated
4646
- Creates `.github/agents/agentic-workflows.agent.md` as the dispatcher agent for AI workflows
4747
- Configures VSCode settings in `.vscode/settings.json`
48-
- Creates GH-AW MCP server configuration in `.mcp.json`
48+
- Creates GH-AW MCP server configuration in `.github/mcp.json`
4949
- Creates `.github/workflows/copilot-setup-steps.yml` with setup instructions
5050

5151
**Note**: The command may prompt for additional configuration or secrets. If secrets are needed, `gh aw init` will provide instructions for setting them up. You don't need to configure secrets as part of this initial setup.
@@ -63,7 +63,7 @@ You should see new/modified files including:
6363
- `.gitattributes`
6464
- `.github/agents/agentic-workflows.agent.md`
6565
- `.vscode/settings.json`
66-
- `.mcp.json`
66+
- `.github/mcp.json`
6767

6868
Commit the initialization changes:
6969

pkg/cli/init.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,13 @@ func InitRepository(opts InitOptions) error {
9292
fmt.Fprintln(os.Stderr, console.FormatSuccessMessage("Created .github/workflows/copilot-setup-steps.yml"))
9393
}
9494

95-
// Create .mcp.json
95+
// Create .github/mcp.json
9696
if err := ensureMCPConfig(opts.Verbose); err != nil {
9797
initLog.Printf("Failed to create MCP config: %v", err)
9898
return fmt.Errorf("failed to create MCP config: %w", err)
9999
}
100100
if opts.Verbose {
101-
fmt.Fprintln(os.Stderr, console.FormatSuccessMessage("Created .mcp.json"))
101+
fmt.Fprintln(os.Stderr, console.FormatSuccessMessage("Created .github/mcp.json"))
102102
}
103103
}
104104

pkg/cli/init_command.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ This command:
3535
3636
By default (without --no-mcp):
3737
- Creates .github/workflows/copilot-setup-steps.yml with gh-aw installation steps
38-
- Creates .mcp.json with gh-aw MCP server configuration
38+
- Creates .github/mcp.json with gh-aw MCP server configuration
3939
4040
With --no-mcp flag:
4141
- Skips creating GitHub Copilot Agent MCP server configuration files

pkg/cli/init_command_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ func TestInitRepositoryBasic(t *testing.T) {
188188
// Verify MCP files were created by default
189189
mcpConfigPath := mcpConfigFilePath
190190
if _, err := os.Stat(mcpConfigPath); os.IsNotExist(err) {
191-
t.Error("Expected .mcp.json to be created by default")
191+
t.Error("Expected .github/mcp.json to be created by default")
192192
}
193193

194194
setupStepsPath := filepath.Join(".github", "workflows", "copilot-setup-steps.yml")
@@ -227,10 +227,10 @@ func TestInitRepositoryWithMCP(t *testing.T) {
227227
t.Fatalf("InitRepository(, false, false, false, nil) with MCP failed: %v", err)
228228
}
229229

230-
// Verify .mcp.json was created
230+
// Verify .github/mcp.json was created
231231
mcpConfigPath := mcpConfigFilePath
232232
if _, err := os.Stat(mcpConfigPath); os.IsNotExist(err) {
233-
t.Error("Expected .mcp.json to be created")
233+
t.Error("Expected .github/mcp.json to be created")
234234
}
235235

236236
// Verify copilot-setup-steps.yml was created
@@ -270,10 +270,10 @@ func TestInitRepositoryWithNoMCP(t *testing.T) {
270270
t.Fatalf("InitRepository(, false, false, false, nil) with --no-mcp failed: %v", err)
271271
}
272272

273-
// Verify .mcp.json was NOT created
273+
// Verify .github/mcp.json was NOT created
274274
mcpConfigPath := mcpConfigFilePath
275275
if _, err := os.Stat(mcpConfigPath); err == nil {
276-
t.Error("Expected .mcp.json to NOT be created with --no-mcp flag")
276+
t.Error("Expected .github/mcp.json to NOT be created with --no-mcp flag")
277277
}
278278

279279
// Verify copilot-setup-steps.yml was NOT created
@@ -318,10 +318,10 @@ func TestInitRepositoryWithMCPBackwardCompatibility(t *testing.T) {
318318
t.Fatalf("InitRepository(, false, false, false, nil) with deprecated --mcp flag failed: %v", err)
319319
}
320320

321-
// Verify .mcp.json was created
321+
// Verify .github/mcp.json was created
322322
mcpConfigPath := mcpConfigFilePath
323323
if _, err := os.Stat(mcpConfigPath); os.IsNotExist(err) {
324-
t.Error("Expected .mcp.json to be created with --mcp flag (backward compatibility)")
324+
t.Error("Expected .github/mcp.json to be created with --mcp flag (backward compatibility)")
325325
}
326326

327327
// Verify copilot-setup-steps.yml was created
@@ -481,7 +481,7 @@ func TestInitRepositoryWithMCPIdempotent(t *testing.T) {
481481
// Verify files still exist and are correct
482482
mcpConfigPath := mcpConfigFilePath
483483
if _, err := os.Stat(mcpConfigPath); os.IsNotExist(err) {
484-
t.Error("Expected .mcp.json to still exist after second run")
484+
t.Error("Expected .github/mcp.json to still exist after second run")
485485
}
486486

487487
setupStepsPath := filepath.Join(".github", "workflows", "copilot-setup-steps.yml")

pkg/cli/init_mcp_test.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,24 +77,24 @@ func TestInitRepository_WithMCP(t *testing.T) {
7777
}
7878
}
7979

80-
// Verify .mcp.json was created
80+
// Verify .github/mcp.json was created
8181
mcpConfigPath := filepath.Join(tempDir, mcpConfigFilePath)
8282
if _, err := os.Stat(mcpConfigPath); os.IsNotExist(err) {
83-
t.Errorf("Expected .mcp.json to exist")
83+
t.Errorf("Expected .github/mcp.json to exist")
8484
} else {
8585
// Verify content is valid JSON with gh-aw server
8686
content, err := os.ReadFile(mcpConfigPath)
8787
if err != nil {
88-
t.Fatalf("Failed to read .mcp.json: %v", err)
88+
t.Fatalf("Failed to read .github/mcp.json: %v", err)
8989
}
9090

9191
var config MCPConfig
9292
if err := json.Unmarshal(content, &config); err != nil {
93-
t.Fatalf("Failed to parse .mcp.json: %v", err)
93+
t.Fatalf("Failed to parse .github/mcp.json: %v", err)
9494
}
9595

9696
if _, exists := config.MCPServers["github-agentic-workflows"]; !exists {
97-
t.Errorf("Expected .mcp.json to contain github-agentic-workflows server")
97+
t.Errorf("Expected .github/mcp.json to contain github-agentic-workflows server")
9898
}
9999

100100
server := config.MCPServers["github-agentic-workflows"]
@@ -155,7 +155,7 @@ func TestInitRepository_MCP_Idempotent(t *testing.T) {
155155

156156
mcpConfigPath := filepath.Join(tempDir, mcpConfigFilePath)
157157
if _, err := os.Stat(mcpConfigPath); os.IsNotExist(err) {
158-
t.Errorf("Expected .mcp.json to exist after second call")
158+
t.Errorf("Expected .github/mcp.json to exist after second call")
159159
}
160160
}
161161

@@ -176,7 +176,7 @@ func TestEnsureMCPConfig_RendersInstructions(t *testing.T) {
176176
t.Fatalf("Failed to change directory: %v", err)
177177
}
178178

179-
// Create initial .mcp.json with a different server
179+
// Create initial .github/mcp.json with a different server
180180
initialConfig := MCPConfig{
181181
MCPServers: map[string]VSCodeMCPServer{
182182
"other-server": {
@@ -187,8 +187,11 @@ func TestEnsureMCPConfig_RendersInstructions(t *testing.T) {
187187
}
188188
initialData, _ := json.MarshalIndent(initialConfig, "", " ")
189189
mcpConfigPath := filepath.Join(tempDir, mcpConfigFilePath)
190+
if err := os.MkdirAll(filepath.Dir(mcpConfigPath), 0755); err != nil {
191+
t.Fatalf("Failed to create MCP config directory: %v", err)
192+
}
190193
if err := os.WriteFile(mcpConfigPath, initialData, 0644); err != nil {
191-
t.Fatalf("Failed to write initial .mcp.json: %v", err)
194+
t.Fatalf("Failed to write initial .github/mcp.json: %v", err)
192195
}
193196

194197
// Call ensureMCPConfig
@@ -199,12 +202,12 @@ func TestEnsureMCPConfig_RendersInstructions(t *testing.T) {
199202
// Verify the config was NOT modified (file should remain unchanged)
200203
content, err := os.ReadFile(mcpConfigPath)
201204
if err != nil {
202-
t.Fatalf("Failed to read .mcp.json: %v", err)
205+
t.Fatalf("Failed to read .github/mcp.json: %v", err)
203206
}
204207

205208
var config MCPConfig
206209
if err := json.Unmarshal(content, &config); err != nil {
207-
t.Fatalf("Failed to parse .mcp.json: %v", err)
210+
t.Fatalf("Failed to parse .github/mcp.json: %v", err)
208211
}
209212

210213
// Check that other-server still exists

pkg/cli/mcp_config_file.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ import (
44
"encoding/json"
55
"fmt"
66
"os"
7+
"path/filepath"
78

89
"github.com/github/gh-aw/pkg/logger"
910
)
1011

1112
var mcpConfigLog = logger.New("cli:mcp_config_file")
1213

1314
// mcpConfigFilePath is the path to the MCP configuration file used by GitHub Copilot CLI.
14-
// GitHub Copilot CLI reads .mcp.json from the repository root.
15-
const mcpConfigFilePath = ".mcp.json"
15+
const mcpConfigFilePath = ".github/mcp.json"
1616

1717
// VSCodeMCPServer represents a single MCP server configuration for VSCode mcp.json
1818
type VSCodeMCPServer struct {
@@ -21,17 +21,17 @@ type VSCodeMCPServer struct {
2121
CWD string `json:"cwd,omitempty"`
2222
}
2323

24-
// MCPConfig represents the structure of .mcp.json for Claude Code.
24+
// MCPConfig represents the structure of .github/mcp.json for Claude Code.
2525
type MCPConfig struct {
2626
MCPServers map[string]VSCodeMCPServer `json:"mcpServers,omitempty"`
27-
// Servers is a legacy key kept for backward-compatible reads of existing .mcp.json files.
27+
// Servers is a legacy key kept for backward-compatible reads of existing mcp config files.
2828
Servers map[string]VSCodeMCPServer `json:"servers,omitempty"`
2929
}
3030

31-
// ensureMCPConfig creates .mcp.json with gh-aw MCP server configuration
31+
// ensureMCPConfig creates .github/mcp.json with gh-aw MCP server configuration
3232
// If the file already exists, it renders console instructions instead of editing
3333
func ensureMCPConfig(verbose bool) error {
34-
mcpConfigLog.Print("Creating .mcp.json")
34+
mcpConfigLog.Print("Creating .github/mcp.json")
3535

3636
mcpConfigPath := mcpConfigFilePath
3737

@@ -78,6 +78,10 @@ func ensureMCPConfig(verbose bool) error {
7878
}
7979
config.MCPServers[ghAwServerName] = ghAwConfig
8080

81+
if err := os.MkdirAll(filepath.Dir(mcpConfigPath), 0755); err != nil {
82+
return fmt.Errorf("failed to create mcp config directory: %w", err)
83+
}
84+
8185
// Write config file with proper indentation
8286
data, err := json.MarshalIndent(config, "", " ")
8387
if err != nil {
@@ -92,15 +96,15 @@ func ensureMCPConfig(verbose bool) error {
9296
return nil
9397
}
9498

95-
// renderMCPConfigUpdateInstructions renders console instructions for updating .mcp.json
99+
// renderMCPConfigUpdateInstructions renders console instructions for updating .github/mcp.json
96100
func renderMCPConfigUpdateInstructions(filePath, serverName string, serverConfig VSCodeMCPServer) {
97101
fmt.Fprintln(os.Stderr)
98102
fmt.Fprintf(os.Stderr, "%s %s\n",
99103
"ℹ",
100104
"Existing file detected: "+filePath)
101105
fmt.Fprintln(os.Stderr)
102106
fmt.Fprintln(os.Stderr, "To enable GitHub Copilot Agent MCP server integration, please add the following")
103-
fmt.Fprintln(os.Stderr, "to the \"mcpServers\" section of your .mcp.json file:")
107+
fmt.Fprintf(os.Stderr, "to the \"mcpServers\" section of your %s file:\n", filePath)
104108
fmt.Fprintln(os.Stderr)
105109

106110
// Generate the JSON to add

0 commit comments

Comments
 (0)