@fyow/copilot-everything 1.0.10 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -91,6 +91,8 @@ copilot-everything <command> [options]
91
91
  |--------|-------------|
92
92
  | --ai type | Target AI platform: copilot (default), claude, or all |
93
93
  | --force | Overwrite existing files |
94
+ | --force-mcp | Overwrite ~/.copilot/mcp-config.json (contains API keys) |
95
+ | -y, --yes | Skip confirmation prompts for --force flags |
94
96
  | --skip-agents | Skip agent installation |
95
97
  | --skip-skills | Skip skills installation |
96
98
  | --skip-hooks | Skip hooks installation |
@@ -106,6 +108,12 @@ copilot-everything init
106
108
  # Initialize with force overwrite
107
109
  copilot-everything init --force
108
110
 
111
+ # Overwrite MCP config (API keys will be auto-filled from environment)
112
+ copilot-everything init --force-mcp
113
+
114
+ # Skip confirmation prompts (for CI/scripts)
115
+ copilot-everything init --force-mcp -y
116
+
109
117
  # Skip certain components
110
118
  copilot-everything init --skip-hooks --skip-skills
111
119
 
@@ -166,6 +174,47 @@ VS Code uses its own built-in tools (`read_file`, `run_in_terminal`, etc.) which
166
174
 
167
175
  ---
168
176
 
177
+ ## MCP Server Configuration
178
+
179
+ The init command installs a comprehensive MCP config template to `~/.copilot/mcp-config.json` with 20+ servers:
180
+
181
+ - **AI/Docs**: context7, next-devtools, cloudflare-docs
182
+ - **Browser**: playwright, chrome-devtools, puppeteer
183
+ - **DevOps**: github, vercel, railway, docker, sentry
184
+ - **Database**: postgres, sqlite, redis, supabase
185
+ - **Utilities**: memory, firecrawl, fetch, filesystem, git, sequential-thinking
186
+
187
+ ### Auto-fill Environment Variables
188
+
189
+ When installing MCP config, the CLI automatically detects and substitutes environment variables:
190
+
191
+ ```bash
192
+ # Set your API keys in environment
193
+ export GITHUB_TOKEN=ghp_xxx
194
+ export FIRECRAWL_API_KEY=fc_xxx
195
+ export CONTEXT7_API_KEY=xxx
196
+
197
+ # Install with auto-fill
198
+ copilot-everything init --force-mcp
199
+
200
+ # Output:
201
+ # ✅ MCP config: installed to ~/.copilot/mcp-config.json
202
+ # 🔑 Auto-filled from environment: GITHUB_TOKEN, FIRECRAWL_API_KEY, CONTEXT7_API_KEY
203
+ # 📝 Need to configure: SUPABASE_PROJECT_REF, POSTGRES_CONNECTION_STRING, ...
204
+ ```
205
+
206
+ Supported environment variables:
207
+ - `GITHUB_TOKEN` - GitHub Personal Access Token
208
+ - `CONTEXT7_API_KEY` - Context7 API key
209
+ - `FIRECRAWL_API_KEY` - Firecrawl API key
210
+ - `SUPABASE_PROJECT_REF` - Supabase project reference
211
+ - `POSTGRES_CONNECTION_STRING` - PostgreSQL connection string
212
+ - `SQLITE_DB_PATH` - SQLite database path
213
+ - `REDIS_URL` - Redis connection URL
214
+ - `WORKSPACE_PATH` - Filesystem workspace path
215
+
216
+ ---
217
+
169
218
  ## Customization
170
219
 
171
220
  After installation, customize the configs for your project:
@@ -1,103 +1,144 @@
1
1
  {
2
2
  "mcpServers": {
3
3
  "context7": {
4
- "command": "npx",
5
- "args": ["-y", "@upstash/context7-mcp@latest"],
6
- "env": {
4
+ "type": "http",
5
+ "url": "https://mcp.context7.com/mcp",
6
+ "headers": {
7
7
  "CONTEXT7_API_KEY": "${CONTEXT7_API_KEY}"
8
- }
8
+ },
9
+ "tools": ["*"]
9
10
  },
10
11
  "playwright": {
12
+ "type": "stdio",
11
13
  "command": "npx",
12
- "args": ["-y", "@playwright/mcp@latest"]
14
+ "args": ["-y", "@playwright/mcp@latest"],
15
+ "tools": ["*"]
13
16
  },
14
17
  "sequential-thinking": {
18
+ "type": "stdio",
15
19
  "command": "npx",
16
- "args": ["-y", "@modelcontextprotocol/server-sequential-thinking"]
20
+ "args": ["-y", "@modelcontextprotocol/server-sequential-thinking"],
21
+ "tools": ["*"]
17
22
  },
18
23
  "chrome-devtools": {
24
+ "type": "stdio",
19
25
  "command": "npx",
20
- "args": ["-y", "chrome-devtools-mcp"]
26
+ "args": ["-y", "chrome-devtools-mcp@latest"],
27
+ "tools": ["*"]
21
28
  },
22
29
  "next-devtools": {
30
+ "type": "stdio",
23
31
  "command": "npx",
24
- "args": ["-y", "next-devtools-mcp@latest"]
32
+ "args": ["-y", "next-devtools-mcp@latest"],
33
+ "tools": ["*"]
25
34
  },
26
35
  "github": {
36
+ "type": "stdio",
27
37
  "command": "npx",
28
38
  "args": ["-y", "@modelcontextprotocol/server-github"],
29
39
  "env": {
30
40
  "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
31
- }
41
+ },
42
+ "tools": ["*"]
32
43
  },
33
44
  "memory": {
45
+ "type": "stdio",
34
46
  "command": "npx",
35
- "args": ["-y", "@modelcontextprotocol/server-memory"]
47
+ "args": ["-y", "@modelcontextprotocol/server-memory"],
48
+ "tools": ["*"]
36
49
  },
37
50
  "firecrawl": {
51
+ "type": "stdio",
38
52
  "command": "npx",
39
53
  "args": ["-y", "firecrawl-mcp"],
40
54
  "env": {
41
55
  "FIRECRAWL_API_KEY": "${FIRECRAWL_API_KEY}"
42
- }
56
+ },
57
+ "tools": ["*"]
43
58
  },
44
59
  "supabase": {
60
+ "type": "stdio",
45
61
  "command": "npx",
46
- "args": ["-y", "@supabase/mcp-server-supabase@latest", "--project-ref=${SUPABASE_PROJECT_REF}"]
62
+ "args": ["-y", "@supabase/mcp-server-supabase@latest", "--project-ref=${SUPABASE_PROJECT_REF}"],
63
+ "tools": ["*"]
47
64
  },
48
65
  "vercel": {
49
66
  "type": "http",
50
- "url": "https://mcp.vercel.com"
67
+ "url": "https://mcp.vercel.com",
68
+ "headers": {},
69
+ "tools": ["*"]
51
70
  },
52
71
  "railway": {
72
+ "type": "stdio",
53
73
  "command": "npx",
54
- "args": ["-y", "@railway/mcp-server"]
74
+ "args": ["-y", "@railway/mcp-server"],
75
+ "tools": ["*"]
55
76
  },
56
77
  "cloudflare-docs": {
57
78
  "type": "http",
58
- "url": "https://docs.mcp.cloudflare.com/mcp"
79
+ "url": "https://docs.mcp.cloudflare.com/mcp",
80
+ "headers": {},
81
+ "tools": ["*"]
59
82
  },
60
83
  "filesystem": {
84
+ "type": "stdio",
61
85
  "command": "npx",
62
- "args": ["-y", "@modelcontextprotocol/server-filesystem", "${WORKSPACE_PATH}"]
86
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "${WORKSPACE_PATH}"],
87
+ "tools": ["*"]
63
88
  },
64
89
  "git": {
90
+ "type": "stdio",
65
91
  "command": "uvx",
66
- "args": ["mcp-server-git"]
92
+ "args": ["mcp-server-git"],
93
+ "tools": ["*"]
67
94
  },
68
95
  "postgres": {
96
+ "type": "stdio",
69
97
  "command": "npx",
70
- "args": ["-y", "@modelcontextprotocol/server-postgres", "${POSTGRES_CONNECTION_STRING}"]
98
+ "args": ["-y", "@modelcontextprotocol/server-postgres", "${POSTGRES_CONNECTION_STRING}"],
99
+ "tools": ["*"]
71
100
  },
72
101
  "sqlite": {
102
+ "type": "stdio",
73
103
  "command": "npx",
74
- "args": ["-y", "@modelcontextprotocol/server-sqlite", "--db-path", "${SQLITE_DB_PATH}"]
104
+ "args": ["-y", "@modelcontextprotocol/server-sqlite", "--db-path", "${SQLITE_DB_PATH}"],
105
+ "tools": ["*"]
75
106
  },
76
107
  "redis": {
108
+ "type": "stdio",
77
109
  "command": "npx",
78
110
  "args": ["-y", "@modelcontextprotocol/server-redis"],
79
111
  "env": {
80
112
  "REDIS_URL": "${REDIS_URL}"
81
- }
113
+ },
114
+ "tools": ["*"]
82
115
  },
83
116
  "puppeteer": {
117
+ "type": "stdio",
84
118
  "command": "npx",
85
- "args": ["-y", "@modelcontextprotocol/server-puppeteer"]
119
+ "args": ["-y", "@modelcontextprotocol/server-puppeteer"],
120
+ "tools": ["*"]
86
121
  },
87
122
  "fetch": {
123
+ "type": "stdio",
88
124
  "command": "npx",
89
- "args": ["-y", "@modelcontextprotocol/server-fetch"]
125
+ "args": ["-y", "@modelcontextprotocol/server-fetch"],
126
+ "tools": ["*"]
90
127
  },
91
128
  "docker": {
129
+ "type": "stdio",
92
130
  "command": "npx",
93
- "args": ["-y", "mcp-server-docker"]
131
+ "args": ["-y", "mcp-server-docker"],
132
+ "tools": ["*"]
94
133
  },
95
134
  "sentry": {
135
+ "type": "stdio",
96
136
  "command": "npx",
97
137
  "args": ["-y", "@modelcontextprotocol/server-sentry"],
98
138
  "env": {
99
139
  "SENTRY_AUTH_TOKEN": "${SENTRY_AUTH_TOKEN}"
100
- }
140
+ },
141
+ "tools": ["*"]
101
142
  }
102
143
  }
103
144
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fyow/copilot-everything",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Everything you need for GitHub Copilot CLI - agents, skills, instructions, and hooks configurations",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -82,6 +82,77 @@ function copyFile(src, dest, options = {}) {
82
82
  }
83
83
  }
84
84
 
85
+ /**
86
+ * Process MCP config and substitute environment variables
87
+ * Returns { content, substituted, missing } where:
88
+ * - content: the processed JSON string
89
+ * - substituted: array of env var names that were found and substituted
90
+ * - missing: array of env var names that are still placeholders
91
+ */
92
+ function processMcpConfig(src) {
93
+ const content = fs.readFileSync(src, 'utf-8');
94
+ const substituted = [];
95
+ const missing = [];
96
+
97
+ // Find all ${VAR_NAME} patterns
98
+ const envVarPattern = /\$\{([A-Z_][A-Z0-9_]*)\}/g;
99
+ const matches = content.matchAll(envVarPattern);
100
+
101
+ // Collect unique env var names
102
+ const envVars = new Set();
103
+ for (const match of matches) {
104
+ envVars.add(match[1]);
105
+ }
106
+
107
+ // Check which ones exist in environment and substitute
108
+ let processedContent = content;
109
+ for (const varName of envVars) {
110
+ const envValue = process.env[varName];
111
+ if (envValue) {
112
+ // Replace all occurrences of ${VAR_NAME} with actual value
113
+ processedContent = processedContent.replace(
114
+ new RegExp(`\\$\\{${varName}\\}`, 'g'),
115
+ envValue
116
+ );
117
+ substituted.push(varName);
118
+ } else {
119
+ missing.push(varName);
120
+ }
121
+ }
122
+
123
+ return { content: processedContent, substituted, missing };
124
+ }
125
+
126
+ /**
127
+ * Copy MCP config file with environment variable substitution
128
+ */
129
+ function copyMcpConfig(src, dest, options = {}) {
130
+ const { force = false, dryRun = false } = options;
131
+
132
+ if (!fs.existsSync(src)) {
133
+ return { copied: 0, skipped: 0, errors: [{ path: dest, error: 'Source not found' }], substituted: [], missing: [] };
134
+ }
135
+
136
+ if (fs.existsSync(dest) && !force) {
137
+ return { copied: 0, skipped: 1, errors: [], substituted: [], missing: [] };
138
+ }
139
+
140
+ try {
141
+ const { content, substituted, missing } = processMcpConfig(src);
142
+
143
+ if (!dryRun) {
144
+ const destDir = path.dirname(dest);
145
+ if (!fs.existsSync(destDir)) {
146
+ fs.mkdirSync(destDir, { recursive: true });
147
+ }
148
+ fs.writeFileSync(dest, content, 'utf-8');
149
+ }
150
+ return { copied: 1, skipped: 0, errors: [], substituted, missing };
151
+ } catch (error) {
152
+ return { copied: 0, skipped: 0, errors: [{ path: dest, error: error.message }], substituted: [], missing: [] };
153
+ }
154
+ }
155
+
85
156
  const readline = require('readline');
86
157
 
87
158
  /**
@@ -257,9 +328,17 @@ async function init(flags = {}) {
257
328
  console.log(` 💡 Template available at: ${mcpConfigSrc}`);
258
329
  totalSkipped += 1;
259
330
  } else {
260
- const mcpResult = copyFile(mcpConfigSrc, mcpConfigDest, { force: forceMcp });
331
+ const mcpResult = copyMcpConfig(mcpConfigSrc, mcpConfigDest, { force: forceMcp });
261
332
  if (mcpResult.copied > 0) {
262
333
  console.log(` ✅ MCP config: ${forceMcp ? 'overwritten' : 'installed'} to ${mcpConfigDest}`);
334
+
335
+ // Report env var substitution results
336
+ if (mcpResult.substituted.length > 0) {
337
+ console.log(` 🔑 Auto-filled from environment: ${mcpResult.substituted.join(', ')}`);
338
+ }
339
+ if (mcpResult.missing.length > 0) {
340
+ console.log(` 📝 Need to configure: ${mcpResult.missing.join(', ')}`);
341
+ }
263
342
  }
264
343
  totalCopied += mcpResult.copied;
265
344
  totalSkipped += mcpResult.skipped;