@nerviq/cli 0.0.1 → 0.9.0-beta.2
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/CHANGELOG.md +181 -0
- package/LICENSE +21 -0
- package/README.md +447 -0
- package/bin/cli.js +749 -0
- package/content/case-study-template.md +91 -0
- package/content/claims-governance.md +37 -0
- package/content/claude-code/audit-repo/SKILL.md +20 -0
- package/content/claude-native-integration.md +60 -0
- package/content/devto-article.json +9 -0
- package/content/launch-posts.md +226 -0
- package/content/pilot-rollout-kit.md +30 -0
- package/content/release-checklist.md +31 -0
- package/package.json +53 -4
- package/src/activity.js +529 -0
- package/src/aider/activity.js +226 -0
- package/src/aider/config-parser.js +166 -0
- package/src/aider/context.js +158 -0
- package/src/aider/deep-review.js +316 -0
- package/src/aider/domain-packs.js +278 -0
- package/src/aider/freshness.js +168 -0
- package/src/aider/governance.js +253 -0
- package/src/aider/interactive.js +334 -0
- package/src/aider/mcp-packs.js +98 -0
- package/src/aider/patch.js +214 -0
- package/src/aider/plans.js +186 -0
- package/src/aider/premium.js +360 -0
- package/src/aider/setup.js +404 -0
- package/src/aider/techniques.js +1323 -0
- package/src/analyze.js +821 -0
- package/src/audit.js +1003 -0
- package/src/badge.js +13 -0
- package/src/benchmark.js +339 -0
- package/src/claudex-sync.json +7 -0
- package/src/codex/activity.js +324 -0
- package/src/codex/config-parser.js +183 -0
- package/src/codex/context.js +221 -0
- package/src/codex/deep-review.js +493 -0
- package/src/codex/domain-packs.js +372 -0
- package/src/codex/freshness.js +167 -0
- package/src/codex/governance.js +192 -0
- package/src/codex/interactive.js +618 -0
- package/src/codex/mcp-packs.js +660 -0
- package/src/codex/patch.js +209 -0
- package/src/codex/plans.js +251 -0
- package/src/codex/premium.js +614 -0
- package/src/codex/setup.js +603 -0
- package/src/codex/techniques.js +2649 -0
- package/src/context.js +272 -0
- package/src/copilot/activity.js +309 -0
- package/src/copilot/config-parser.js +226 -0
- package/src/copilot/context.js +197 -0
- package/src/copilot/deep-review.js +346 -0
- package/src/copilot/domain-packs.js +350 -0
- package/src/copilot/freshness.js +197 -0
- package/src/copilot/governance.js +222 -0
- package/src/copilot/interactive.js +406 -0
- package/src/copilot/mcp-packs.js +572 -0
- package/src/copilot/patch.js +238 -0
- package/src/copilot/plans.js +253 -0
- package/src/copilot/premium.js +450 -0
- package/src/copilot/setup.js +488 -0
- package/src/copilot/techniques.js +1822 -0
- package/src/cursor/activity.js +301 -0
- package/src/cursor/config-parser.js +265 -0
- package/src/cursor/context.js +236 -0
- package/src/cursor/deep-review.js +334 -0
- package/src/cursor/domain-packs.js +346 -0
- package/src/cursor/freshness.js +214 -0
- package/src/cursor/governance.js +229 -0
- package/src/cursor/interactive.js +391 -0
- package/src/cursor/mcp-packs.js +571 -0
- package/src/cursor/patch.js +243 -0
- package/src/cursor/plans.js +254 -0
- package/src/cursor/premium.js +468 -0
- package/src/cursor/setup.js +488 -0
- package/src/cursor/techniques.js +1786 -0
- package/src/deep-review.js +345 -0
- package/src/domain-packs.js +364 -0
- package/src/formatters/sarif.js +115 -0
- package/src/gemini/activity.js +402 -0
- package/src/gemini/config-parser.js +275 -0
- package/src/gemini/context.js +221 -0
- package/src/gemini/deep-review.js +559 -0
- package/src/gemini/domain-packs.js +371 -0
- package/src/gemini/freshness.js +204 -0
- package/src/gemini/governance.js +201 -0
- package/src/gemini/interactive.js +860 -0
- package/src/gemini/mcp-packs.js +658 -0
- package/src/gemini/patch.js +229 -0
- package/src/gemini/plans.js +269 -0
- package/src/gemini/premium.js +759 -0
- package/src/gemini/setup.js +692 -0
- package/src/gemini/techniques.js +2084 -0
- package/src/governance.js +523 -0
- package/src/harmony/advisor.js +383 -0
- package/src/harmony/audit.js +303 -0
- package/src/harmony/canon.js +444 -0
- package/src/harmony/cli.js +331 -0
- package/src/harmony/drift.js +401 -0
- package/src/harmony/governance.js +313 -0
- package/src/harmony/memory.js +238 -0
- package/src/harmony/sync.js +458 -0
- package/src/harmony/watch.js +336 -0
- package/src/index.js +256 -0
- package/src/insights.js +119 -0
- package/src/interactive.js +118 -0
- package/src/mcp-packs.js +597 -0
- package/src/opencode/activity.js +286 -0
- package/src/opencode/config-parser.js +109 -0
- package/src/opencode/context.js +247 -0
- package/src/opencode/deep-review.js +313 -0
- package/src/opencode/domain-packs.js +240 -0
- package/src/opencode/freshness.js +158 -0
- package/src/opencode/governance.js +159 -0
- package/src/opencode/interactive.js +392 -0
- package/src/opencode/mcp-packs.js +474 -0
- package/src/opencode/patch.js +184 -0
- package/src/opencode/plans.js +231 -0
- package/src/opencode/premium.js +413 -0
- package/src/opencode/setup.js +449 -0
- package/src/opencode/techniques.js +1713 -0
- package/src/plans.js +655 -0
- package/src/secret-patterns.js +30 -0
- package/src/setup.js +1274 -0
- package/src/synergy/adaptive.js +261 -0
- package/src/synergy/compensation.js +156 -0
- package/src/synergy/evidence.js +193 -0
- package/src/synergy/learning.js +184 -0
- package/src/synergy/patterns.js +227 -0
- package/src/synergy/ranking.js +83 -0
- package/src/synergy/report.js +163 -0
- package/src/synergy/routing.js +152 -0
- package/src/techniques.js +1354 -0
- package/src/watch.js +229 -0
- package/src/windsurf/activity.js +302 -0
- package/src/windsurf/config-parser.js +267 -0
- package/src/windsurf/context.js +249 -0
- package/src/windsurf/deep-review.js +337 -0
- package/src/windsurf/domain-packs.js +348 -0
- package/src/windsurf/freshness.js +215 -0
- package/src/windsurf/governance.js +231 -0
- package/src/windsurf/interactive.js +388 -0
- package/src/windsurf/mcp-packs.js +535 -0
- package/src/windsurf/patch.js +231 -0
- package/src/windsurf/plans.js +247 -0
- package/src/windsurf/premium.js +467 -0
- package/src/windsurf/setup.js +471 -0
- package/src/windsurf/techniques.js +1758 -0
package/src/mcp-packs.js
ADDED
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
const MCP_PACKS = [
|
|
2
|
+
{
|
|
3
|
+
key: 'context7-docs',
|
|
4
|
+
label: 'Context7 Docs',
|
|
5
|
+
useWhen: 'Repos that benefit from live, current framework and library documentation during Claude sessions.',
|
|
6
|
+
adoption: 'Safe default docs pack for most application repos.',
|
|
7
|
+
servers: {
|
|
8
|
+
context7: {
|
|
9
|
+
command: 'npx',
|
|
10
|
+
args: ['-y', '@upstash/context7-mcp@latest'],
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
key: 'next-devtools',
|
|
16
|
+
label: 'Next.js Devtools',
|
|
17
|
+
useWhen: 'Next.js repos that need runtime-aware debugging and framework-specific tooling.',
|
|
18
|
+
adoption: 'Useful companion pack for frontend-ui repos running Next.js.',
|
|
19
|
+
servers: {
|
|
20
|
+
'next-devtools': {
|
|
21
|
+
command: 'npx',
|
|
22
|
+
args: ['-y', 'next-devtools-mcp@latest'],
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
key: 'github-mcp',
|
|
28
|
+
label: 'GitHub',
|
|
29
|
+
useWhen: 'Repos hosted on GitHub that benefit from issue, PR, and repository context during Claude sessions.',
|
|
30
|
+
adoption: 'Recommended for any GitHub-hosted project. Requires GITHUB_PERSONAL_ACCESS_TOKEN env var.',
|
|
31
|
+
servers: {
|
|
32
|
+
github: {
|
|
33
|
+
command: 'npx',
|
|
34
|
+
args: ['-y', '@modelcontextprotocol/server-github'],
|
|
35
|
+
env: { GITHUB_PERSONAL_ACCESS_TOKEN: '${GITHUB_PERSONAL_ACCESS_TOKEN}' },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
key: 'postgres-mcp',
|
|
41
|
+
label: 'PostgreSQL',
|
|
42
|
+
useWhen: 'Repos with PostgreSQL databases that benefit from schema inspection and query assistance.',
|
|
43
|
+
adoption: 'Useful for backend-api and data-pipeline repos. Pass connection string as CLI argument.',
|
|
44
|
+
servers: {
|
|
45
|
+
postgres: {
|
|
46
|
+
command: 'npx',
|
|
47
|
+
args: ['-y', '@modelcontextprotocol/server-postgres', '${DATABASE_URL}'],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: 'memory-mcp',
|
|
53
|
+
label: 'Memory / Knowledge Graph',
|
|
54
|
+
useWhen: 'Long-running projects that benefit from persistent entity and relationship tracking across sessions.',
|
|
55
|
+
adoption: 'Useful for complex projects with many interconnected concepts. Stores data locally.',
|
|
56
|
+
servers: {
|
|
57
|
+
memory: {
|
|
58
|
+
command: 'npx',
|
|
59
|
+
args: ['-y', '@modelcontextprotocol/server-memory'],
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
key: 'playwright-mcp',
|
|
65
|
+
label: 'Playwright Browser',
|
|
66
|
+
useWhen: 'Frontend repos that need browser automation, E2E testing, or visual QA during Claude sessions.',
|
|
67
|
+
adoption: 'Recommended for frontend-ui repos with E2E tests. No auth required.',
|
|
68
|
+
servers: {
|
|
69
|
+
playwright: {
|
|
70
|
+
command: 'npx',
|
|
71
|
+
args: ['-y', '@playwright/mcp@latest'],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
key: 'docker-mcp',
|
|
77
|
+
label: 'Docker',
|
|
78
|
+
useWhen: 'Repos with containerized workflows that benefit from container management during Claude sessions.',
|
|
79
|
+
adoption: 'Community Docker MCP server. Requires Docker running locally. Note: community-maintained package.',
|
|
80
|
+
servers: {
|
|
81
|
+
docker: {
|
|
82
|
+
command: 'npx',
|
|
83
|
+
args: ['-y', '@hypnosis/docker-mcp-server'],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
key: 'notion-mcp',
|
|
89
|
+
label: 'Notion',
|
|
90
|
+
useWhen: 'Teams using Notion for documentation, wikis, or knowledge bases that Claude should reference.',
|
|
91
|
+
adoption: 'Useful for teams with Notion-based docs. Requires NOTION_API_KEY env var.',
|
|
92
|
+
servers: {
|
|
93
|
+
notion: {
|
|
94
|
+
command: 'npx',
|
|
95
|
+
args: ['-y', '@notionhq/notion-mcp-server'],
|
|
96
|
+
env: { NOTION_API_KEY: '${NOTION_API_KEY}' },
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
key: 'linear-mcp',
|
|
102
|
+
label: 'Linear',
|
|
103
|
+
useWhen: 'Teams using Linear for issue tracking that want Claude to read and create issues.',
|
|
104
|
+
adoption: 'Useful for teams managing sprints in Linear. Requires LINEAR_API_KEY env var.',
|
|
105
|
+
servers: {
|
|
106
|
+
linear: {
|
|
107
|
+
command: 'npx',
|
|
108
|
+
args: ['-y', '@mseep/linear-mcp'],
|
|
109
|
+
env: { LINEAR_API_KEY: '${LINEAR_API_KEY}' },
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
key: 'sentry-mcp',
|
|
115
|
+
label: 'Sentry',
|
|
116
|
+
useWhen: 'Repos with Sentry error tracking that benefit from error context during debugging sessions.',
|
|
117
|
+
adoption: 'Useful for production repos. Requires SENTRY_AUTH_TOKEN env var.',
|
|
118
|
+
servers: {
|
|
119
|
+
sentry: {
|
|
120
|
+
command: 'npx',
|
|
121
|
+
args: ['-y', '@sentry/mcp-server'],
|
|
122
|
+
env: { SENTRY_AUTH_TOKEN: '${SENTRY_AUTH_TOKEN}' },
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
key: 'slack-mcp',
|
|
128
|
+
label: 'Slack',
|
|
129
|
+
useWhen: 'Teams using Slack that want Claude to draft, preview, or post messages.',
|
|
130
|
+
adoption: 'Community Slack MCP server (supports OAuth and stealth mode). Requires SLACK_BOT_TOKEN or SLACK_COOKIES env var.',
|
|
131
|
+
servers: {
|
|
132
|
+
slack: {
|
|
133
|
+
command: 'npx',
|
|
134
|
+
args: ['-y', 'slack-mcp-server'],
|
|
135
|
+
env: { SLACK_BOT_TOKEN: '${SLACK_BOT_TOKEN}' },
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
key: 'stripe-mcp',
|
|
141
|
+
label: 'Stripe',
|
|
142
|
+
useWhen: 'Repos with Stripe integration for payments, subscriptions, or billing workflows.',
|
|
143
|
+
adoption: 'Useful for e-commerce and SaaS repos. Requires STRIPE_API_KEY env var.',
|
|
144
|
+
servers: {
|
|
145
|
+
stripe: {
|
|
146
|
+
command: 'npx',
|
|
147
|
+
args: ['-y', '@stripe/mcp'],
|
|
148
|
+
env: { STRIPE_API_KEY: '${STRIPE_API_KEY}' },
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
key: 'figma-mcp',
|
|
154
|
+
label: 'Figma',
|
|
155
|
+
useWhen: 'Design-heavy repos where Claude needs access to Figma designs and components.',
|
|
156
|
+
adoption: 'Community Figma MCP server. Requires FIGMA_ACCESS_TOKEN env var. Note: community-maintained package.',
|
|
157
|
+
servers: {
|
|
158
|
+
figma: {
|
|
159
|
+
command: 'npx',
|
|
160
|
+
args: ['-y', 'claude-talk-to-figma-mcp'],
|
|
161
|
+
env: { FIGMA_ACCESS_TOKEN: '${FIGMA_ACCESS_TOKEN}' },
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
key: 'mcp-security',
|
|
167
|
+
label: 'MCP Security Scanner',
|
|
168
|
+
useWhen: 'Any repo using MCP servers that should be scanned for tool poisoning and prompt injection.',
|
|
169
|
+
adoption: 'Recommended as a safety companion for any repo with 2+ MCP servers.',
|
|
170
|
+
servers: {
|
|
171
|
+
'mcp-scan': {
|
|
172
|
+
command: 'npx',
|
|
173
|
+
args: ['-y', 'mcp-scan@latest'],
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
key: 'composio-mcp',
|
|
179
|
+
label: 'Composio Universal',
|
|
180
|
+
useWhen: 'Teams needing 500+ integrations through a single MCP gateway with centralized OAuth.',
|
|
181
|
+
adoption: 'Useful for enterprise or integration-heavy repos. Requires COMPOSIO_API_KEY env var.',
|
|
182
|
+
servers: {
|
|
183
|
+
composio: {
|
|
184
|
+
command: 'npx',
|
|
185
|
+
args: ['-y', '@composio/mcp'],
|
|
186
|
+
env: { COMPOSIO_API_KEY: '${COMPOSIO_API_KEY}' },
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
key: 'sequential-thinking',
|
|
192
|
+
label: 'Sequential Thinking',
|
|
193
|
+
useWhen: 'Complex problem-solving sessions that benefit from structured step-by-step reasoning.',
|
|
194
|
+
adoption: 'Safe default for any repo. No auth required.',
|
|
195
|
+
servers: {
|
|
196
|
+
'sequential-thinking': {
|
|
197
|
+
command: 'npx',
|
|
198
|
+
args: ['-y', '@modelcontextprotocol/server-sequential-thinking'],
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
key: 'jira-confluence',
|
|
204
|
+
label: 'Jira',
|
|
205
|
+
useWhen: 'Teams using Atlassian Jira for issue tracking and project management.',
|
|
206
|
+
adoption: 'Requires ATLASSIAN_API_TOKEN and ATLASSIAN_EMAIL env vars.',
|
|
207
|
+
servers: {
|
|
208
|
+
jira: {
|
|
209
|
+
command: 'npx',
|
|
210
|
+
args: ['-y', 'jira-mcp'],
|
|
211
|
+
env: { ATLASSIAN_API_TOKEN: '${ATLASSIAN_API_TOKEN}', ATLASSIAN_EMAIL: '${ATLASSIAN_EMAIL}' },
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
key: 'ga4-analytics',
|
|
217
|
+
label: 'Google Analytics 4',
|
|
218
|
+
useWhen: 'Repos with web analytics needs — live GA4 data, attribution, and audience insights.',
|
|
219
|
+
adoption: 'Requires GA4_PROPERTY_ID and either GOOGLE_APPLICATION_CREDENTIALS or ADC for auth.',
|
|
220
|
+
servers: {
|
|
221
|
+
ga4: {
|
|
222
|
+
command: 'npx',
|
|
223
|
+
args: ['-y', 'mcp-server-ga4'],
|
|
224
|
+
env: { GA4_PROPERTY_ID: '${GA4_PROPERTY_ID}', GOOGLE_APPLICATION_CREDENTIALS: '${GOOGLE_APPLICATION_CREDENTIALS}' },
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
key: 'search-console',
|
|
230
|
+
label: 'Google Search Console',
|
|
231
|
+
useWhen: 'SEO-focused repos that need search performance data, indexing status, and sitemap insights.',
|
|
232
|
+
adoption: 'Requires Google OAuth client credentials (client ID + secret). Uses OAuth consent flow.',
|
|
233
|
+
servers: {
|
|
234
|
+
gsc: {
|
|
235
|
+
command: 'npx',
|
|
236
|
+
args: ['-y', 'mcp-gsc@latest'],
|
|
237
|
+
env: { GOOGLE_CLIENT_ID: '${GOOGLE_CLIENT_ID}', GOOGLE_CLIENT_SECRET: '${GOOGLE_CLIENT_SECRET}' },
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
key: 'n8n-workflows',
|
|
243
|
+
label: 'n8n Workflow Automation',
|
|
244
|
+
useWhen: 'Teams using n8n for workflow automation with 1,396 integration nodes.',
|
|
245
|
+
adoption: 'Requires n8n instance URL and API key.',
|
|
246
|
+
servers: {
|
|
247
|
+
n8n: {
|
|
248
|
+
command: 'npx',
|
|
249
|
+
args: ['-y', 'n8n-mcp-server@latest'],
|
|
250
|
+
env: { N8N_URL: '${N8N_URL}', N8N_API_KEY: '${N8N_API_KEY}' },
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
key: 'zendesk-mcp',
|
|
256
|
+
label: 'Zendesk',
|
|
257
|
+
useWhen: 'Support teams using Zendesk for ticket management and help center content.',
|
|
258
|
+
adoption: 'Requires ZENDESK_API_TOKEN and ZENDESK_SUBDOMAIN env vars.',
|
|
259
|
+
servers: {
|
|
260
|
+
zendesk: {
|
|
261
|
+
command: 'npx',
|
|
262
|
+
args: ['-y', 'zendesk-mcp'],
|
|
263
|
+
env: { ZENDESK_API_TOKEN: '${ZENDESK_API_TOKEN}', ZENDESK_SUBDOMAIN: '${ZENDESK_SUBDOMAIN}' },
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
key: 'infisical-secrets',
|
|
269
|
+
label: 'Infisical Secrets',
|
|
270
|
+
useWhen: 'Repos using Infisical for secrets management with auto-rotation.',
|
|
271
|
+
adoption: 'Requires INFISICAL_TOKEN env var.',
|
|
272
|
+
servers: {
|
|
273
|
+
infisical: {
|
|
274
|
+
command: 'npx',
|
|
275
|
+
args: ['-y', '@infisical/mcp'],
|
|
276
|
+
env: { INFISICAL_TOKEN: '${INFISICAL_TOKEN}' },
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
key: 'shopify-mcp',
|
|
282
|
+
label: 'Shopify',
|
|
283
|
+
useWhen: 'Shopify stores and apps that need API schema access and deployment tooling.',
|
|
284
|
+
adoption: 'Community Shopify MCP server for GraphQL API access. Requires SHOPIFY_ACCESS_TOKEN env var.',
|
|
285
|
+
servers: {
|
|
286
|
+
shopify: {
|
|
287
|
+
command: 'npx',
|
|
288
|
+
args: ['-y', 'shopify-mcp'],
|
|
289
|
+
env: { SHOPIFY_ACCESS_TOKEN: '${SHOPIFY_ACCESS_TOKEN}' },
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
key: 'huggingface-mcp',
|
|
295
|
+
label: 'Hugging Face',
|
|
296
|
+
useWhen: 'AI/ML repos that need model search, dataset discovery, and Spaces integration.',
|
|
297
|
+
adoption: 'Useful for ai-ml domain repos. Requires HF_TOKEN env var.',
|
|
298
|
+
servers: {
|
|
299
|
+
huggingface: {
|
|
300
|
+
command: 'npx',
|
|
301
|
+
args: ['-y', 'huggingface-mcp-server'],
|
|
302
|
+
env: { HF_TOKEN: '${HF_TOKEN}' },
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
key: 'blender-mcp',
|
|
308
|
+
label: 'Blender 3D',
|
|
309
|
+
useWhen: '3D modeling, animation, or rendering repos that use Blender.',
|
|
310
|
+
adoption: 'Requires Blender installed locally. Python bridge.',
|
|
311
|
+
servers: {
|
|
312
|
+
blender: {
|
|
313
|
+
command: 'npx',
|
|
314
|
+
args: ['-y', '@glutamateapp/blender-mcp-ts'],
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
key: 'wordpress-mcp',
|
|
320
|
+
label: 'WordPress',
|
|
321
|
+
useWhen: 'WordPress sites needing content management, site ops, and plugin workflows.',
|
|
322
|
+
adoption: 'Requires WP_URL and WP_AUTH_TOKEN env vars.',
|
|
323
|
+
servers: {
|
|
324
|
+
wordpress: {
|
|
325
|
+
command: 'npx',
|
|
326
|
+
args: ['-y', 'wordpress-mcp-server@latest'],
|
|
327
|
+
env: { WP_URL: '${WP_URL}', WP_AUTH_TOKEN: '${WP_AUTH_TOKEN}' },
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
];
|
|
332
|
+
|
|
333
|
+
function clone(value) {
|
|
334
|
+
return JSON.parse(JSON.stringify(value));
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function hasDependency(deps, name) {
|
|
338
|
+
return Object.prototype.hasOwnProperty.call(deps || {}, name);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function hasFileContentMatch(ctx, filePath, pattern) {
|
|
342
|
+
if (!ctx) return false;
|
|
343
|
+
const content = ctx.fileContent(filePath);
|
|
344
|
+
return !!(content && pattern.test(content));
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function getProjectDependencies(ctx) {
|
|
348
|
+
if (!ctx) return {};
|
|
349
|
+
if (typeof ctx.projectDependencies === 'function') {
|
|
350
|
+
return ctx.projectDependencies();
|
|
351
|
+
}
|
|
352
|
+
const pkg = ctx.jsonFile('package.json') || {};
|
|
353
|
+
return {
|
|
354
|
+
...(pkg.dependencies || {}),
|
|
355
|
+
...(pkg.devDependencies || {}),
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function hasPostgresSignals(ctx, deps = {}) {
|
|
360
|
+
if (
|
|
361
|
+
hasDependency(deps, 'pg') ||
|
|
362
|
+
hasDependency(deps, 'postgres') ||
|
|
363
|
+
hasDependency(deps, 'pg-promise') ||
|
|
364
|
+
hasDependency(deps, 'postgres.js') ||
|
|
365
|
+
hasDependency(deps, 'slonik') ||
|
|
366
|
+
hasDependency(deps, '@neondatabase/serverless') ||
|
|
367
|
+
hasDependency(deps, '@vercel/postgres')
|
|
368
|
+
) {
|
|
369
|
+
return true;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return (
|
|
373
|
+
hasFileContentMatch(ctx, 'prisma/schema.prisma', /provider\s*=\s*["']postgresql["']/i) ||
|
|
374
|
+
hasFileContentMatch(ctx, 'docker-compose.yml', /\bpostgres\b/i) ||
|
|
375
|
+
hasFileContentMatch(ctx, 'docker-compose.yaml', /\bpostgres\b/i) ||
|
|
376
|
+
hasFileContentMatch(ctx, 'compose.yml', /\bpostgres\b/i) ||
|
|
377
|
+
hasFileContentMatch(ctx, 'compose.yaml', /\bpostgres\b/i) ||
|
|
378
|
+
hasFileContentMatch(ctx, '.env', /postgres(?:ql)?:\/\//i) ||
|
|
379
|
+
hasFileContentMatch(ctx, '.env.local', /postgres(?:ql)?:\/\//i) ||
|
|
380
|
+
hasFileContentMatch(ctx, '.env.example', /postgres(?:ql)?:\/\//i)
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function hasObservabilitySignals(ctx, deps = {}) {
|
|
385
|
+
if (
|
|
386
|
+
hasDependency(deps, '@sentry/nextjs') ||
|
|
387
|
+
hasDependency(deps, '@sentry/node') ||
|
|
388
|
+
hasDependency(deps, '@sentry/react') ||
|
|
389
|
+
hasDependency(deps, '@sentry/vue') ||
|
|
390
|
+
hasDependency(deps, '@sentry/browser')
|
|
391
|
+
) {
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return (
|
|
396
|
+
hasFileContentMatch(ctx, 'sentry.client.config.js', /\S/) ||
|
|
397
|
+
hasFileContentMatch(ctx, 'sentry.client.config.ts', /\S/) ||
|
|
398
|
+
hasFileContentMatch(ctx, 'sentry.server.config.js', /\S/) ||
|
|
399
|
+
hasFileContentMatch(ctx, 'sentry.server.config.ts', /\S/) ||
|
|
400
|
+
hasFileContentMatch(ctx, 'instrumentation.ts', /sentry/i) ||
|
|
401
|
+
hasFileContentMatch(ctx, 'instrumentation.js', /sentry/i)
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function getMcpPack(key) {
|
|
406
|
+
return MCP_PACKS.find(pack => pack.key === key) || null;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function normalizeMcpPackKeys(keys = []) {
|
|
410
|
+
return [...new Set((Array.isArray(keys) ? keys : [])
|
|
411
|
+
.map(key => `${key}`.trim())
|
|
412
|
+
.filter(Boolean))]
|
|
413
|
+
.filter(key => !!getMcpPack(key));
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function mergeMcpServers(existing = {}, packKeys = []) {
|
|
417
|
+
const merged = clone(existing || {});
|
|
418
|
+
for (const key of normalizeMcpPackKeys(packKeys)) {
|
|
419
|
+
const pack = getMcpPack(key);
|
|
420
|
+
if (!pack) continue;
|
|
421
|
+
for (const [serverName, serverConfig] of Object.entries(pack.servers || {})) {
|
|
422
|
+
if (!merged[serverName]) {
|
|
423
|
+
merged[serverName] = clone(serverConfig);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return merged;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
function getRequiredEnvVars(packKeys = []) {
|
|
431
|
+
const required = new Set();
|
|
432
|
+
for (const key of normalizeMcpPackKeys(packKeys)) {
|
|
433
|
+
const pack = getMcpPack(key);
|
|
434
|
+
if (!pack) continue;
|
|
435
|
+
for (const serverConfig of Object.values(pack.servers || {})) {
|
|
436
|
+
for (const envKey of Object.keys(serverConfig.env || {})) {
|
|
437
|
+
required.add(envKey);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
return [...required].sort();
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function getMcpPackPreflight(packKeys = [], env = process.env) {
|
|
445
|
+
return normalizeMcpPackKeys(packKeys)
|
|
446
|
+
.map((key) => {
|
|
447
|
+
const pack = getMcpPack(key);
|
|
448
|
+
if (!pack) return null;
|
|
449
|
+
const requiredEnvVars = getRequiredEnvVars([key]);
|
|
450
|
+
if (requiredEnvVars.length === 0) return null;
|
|
451
|
+
const missingEnvVars = requiredEnvVars.filter((envKey) => {
|
|
452
|
+
const value = env && Object.prototype.hasOwnProperty.call(env, envKey) ? env[envKey] : '';
|
|
453
|
+
return !`${value || ''}`.trim();
|
|
454
|
+
});
|
|
455
|
+
return {
|
|
456
|
+
key,
|
|
457
|
+
label: pack.label,
|
|
458
|
+
requiredEnvVars,
|
|
459
|
+
missingEnvVars,
|
|
460
|
+
};
|
|
461
|
+
})
|
|
462
|
+
.filter(Boolean);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
function recommendMcpPacks(stacks = [], domainPacks = [], options = {}) {
|
|
466
|
+
const recommended = new Set();
|
|
467
|
+
const stackKeys = new Set(stacks.map(stack => stack.key));
|
|
468
|
+
const ctx = options.ctx || null;
|
|
469
|
+
const deps = getProjectDependencies(ctx);
|
|
470
|
+
|
|
471
|
+
for (const pack of domainPacks) {
|
|
472
|
+
for (const key of pack.recommendedMcpPacks || []) {
|
|
473
|
+
recommended.add(key);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (stackKeys.has('nextjs')) {
|
|
478
|
+
recommended.add('next-devtools');
|
|
479
|
+
}
|
|
480
|
+
if (stackKeys.size > 0) {
|
|
481
|
+
recommended.add('context7-docs');
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
const domainKeys = new Set(domainPacks.map(p => p.key));
|
|
485
|
+
|
|
486
|
+
// GitHub MCP for collaborative repos
|
|
487
|
+
if (domainKeys.has('oss-library') || domainKeys.has('enterprise-governed') || domainKeys.has('monorepo')) {
|
|
488
|
+
recommended.add('github-mcp');
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Postgres MCP only when there are explicit Postgres signals
|
|
492
|
+
if ((domainKeys.has('data-pipeline') || domainKeys.has('backend-api')) && hasPostgresSignals(ctx, deps)) {
|
|
493
|
+
recommended.add('postgres-mcp');
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Memory MCP for complex projects
|
|
497
|
+
if (domainKeys.has('monorepo') || domainKeys.has('enterprise-governed')) {
|
|
498
|
+
recommended.add('memory-mcp');
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Playwright for frontend repos
|
|
502
|
+
if (domainKeys.has('frontend-ui') || stackKeys.has('react') || stackKeys.has('vue') || stackKeys.has('angular') || stackKeys.has('svelte')) {
|
|
503
|
+
recommended.add('playwright-mcp');
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
// Docker for infra repos
|
|
507
|
+
if (domainKeys.has('infra-platform') || stackKeys.has('docker')) {
|
|
508
|
+
recommended.add('docker-mcp');
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Sentry when the repo already shows observability signals or has stricter operational needs
|
|
512
|
+
if (
|
|
513
|
+
(domainKeys.has('backend-api') || domainKeys.has('frontend-ui')) &&
|
|
514
|
+
(
|
|
515
|
+
hasObservabilitySignals(ctx, deps) ||
|
|
516
|
+
domainKeys.has('enterprise-governed') ||
|
|
517
|
+
domainKeys.has('security-focused') ||
|
|
518
|
+
domainKeys.has('ecommerce')
|
|
519
|
+
)
|
|
520
|
+
) {
|
|
521
|
+
recommended.add('sentry-mcp');
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Figma only when design-system signals are present
|
|
525
|
+
if (domainKeys.has('design-system')) {
|
|
526
|
+
recommended.add('figma-mcp');
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
// Stripe for e-commerce
|
|
530
|
+
if (domainKeys.has('ecommerce')) {
|
|
531
|
+
recommended.add('stripe-mcp');
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// Jira for enterprise teams
|
|
535
|
+
if (domainKeys.has('enterprise-governed')) {
|
|
536
|
+
recommended.add('jira-confluence');
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Analytics for ecommerce (docs-content repos rarely need GA4/GSC)
|
|
540
|
+
if (domainKeys.has('ecommerce')) {
|
|
541
|
+
recommended.add('ga4-analytics');
|
|
542
|
+
recommended.add('search-console');
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// Shopify only when Shopify signals are present
|
|
546
|
+
if (domainKeys.has('ecommerce') && ctx && (
|
|
547
|
+
hasDependency(deps, 'shopify') || hasDependency(deps, '@shopify/shopify-api') ||
|
|
548
|
+
hasFileContentMatch(ctx, '.env', /shopify/i) || hasFileContentMatch(ctx, '.env.example', /shopify/i)
|
|
549
|
+
)) {
|
|
550
|
+
recommended.add('shopify-mcp');
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// HuggingFace for AI/ML
|
|
554
|
+
if (domainKeys.has('ai-ml')) {
|
|
555
|
+
recommended.add('huggingface-mcp');
|
|
556
|
+
recommended.add('sequential-thinking');
|
|
557
|
+
if (
|
|
558
|
+
hasDependency(deps, 'langgraph') ||
|
|
559
|
+
hasDependency(deps, 'langchain') ||
|
|
560
|
+
hasDependency(deps, '@langchain/core') ||
|
|
561
|
+
hasDependency(deps, 'chromadb') ||
|
|
562
|
+
hasDependency(deps, 'qdrant-client') ||
|
|
563
|
+
hasFileContentMatch(ctx, 'langgraph.json', /\S/) ||
|
|
564
|
+
ctx?.hasDir('rag') ||
|
|
565
|
+
ctx?.hasDir('retrievers')
|
|
566
|
+
) {
|
|
567
|
+
recommended.add('memory-mcp');
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Zendesk only when Zendesk signals are present
|
|
572
|
+
if (domainKeys.has('enterprise-governed') && ctx && (
|
|
573
|
+
hasDependency(deps, 'zendesk') || hasDependency(deps, 'node-zendesk') ||
|
|
574
|
+
hasFileContentMatch(ctx, '.env', /zendesk/i) || hasFileContentMatch(ctx, '.env.example', /zendesk/i)
|
|
575
|
+
)) {
|
|
576
|
+
recommended.add('zendesk-mcp');
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// Infisical for security-focused
|
|
580
|
+
if (domainKeys.has('security-focused') || domainKeys.has('regulated-lite')) {
|
|
581
|
+
recommended.add('infisical-secrets');
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
return MCP_PACKS
|
|
585
|
+
.filter(pack => recommended.has(pack.key))
|
|
586
|
+
.map(pack => clone(pack));
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
module.exports = {
|
|
590
|
+
MCP_PACKS,
|
|
591
|
+
getMcpPack,
|
|
592
|
+
normalizeMcpPackKeys,
|
|
593
|
+
mergeMcpServers,
|
|
594
|
+
getRequiredEnvVars,
|
|
595
|
+
getMcpPackPreflight,
|
|
596
|
+
recommendMcpPacks,
|
|
597
|
+
};
|