@aws/nx-plugin 0.35.0 → 0.37.0
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/LICENSE-THIRD-PARTY +39484 -0
- package/README.md +3 -62
- package/generators.json +6 -0
- package/package.json +2 -1
- package/sdk/ts.d.ts +4 -0
- package/sdk/ts.js +15 -9
- package/sdk/ts.js.map +1 -1
- package/src/mcp-server/tools/generator-guide.js +1 -1
- package/src/mcp-server/tools/generator-guide.js.map +1 -1
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -0
- package/src/preset/generator.d.ts +23 -0
- package/src/preset/generator.js +69 -0
- package/src/preset/generator.js.map +1 -1
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/trpc/backend/files/src/schema/echo.ts.template +1 -1
- package/src/trpc/backend/generator.js +0 -3
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/ts/mcp-server/files/server.ts.template +1 -1
- package/src/ts/nx-generator/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/ts/nx-generator/files/common/schema.json.template +1 -1
- package/src/ts/nx-generator/files/local/README.md.template +5 -0
- package/src/ts/nx-generator/generator.js +5 -41
- package/src/ts/nx-generator/generator.js.map +1 -1
- package/src/ts/nx-generator/schema.d.ts +1 -1
- package/src/ts/nx-generator/schema.json +3 -3
- package/src/ts/nx-plugin/__snapshots__/generator.spec.ts.snap +375 -0
- package/src/ts/nx-plugin/files/mcp-server/resources/GENERAL_GUIDANCE.md.template +49 -0
- package/src/ts/nx-plugin/files/mcp-server/schema.ts.template +4 -0
- package/src/ts/nx-plugin/files/mcp-server/server.ts.template +41 -0
- package/src/ts/nx-plugin/files/mcp-server/tools/create-workspace-command.ts.template +36 -0
- package/src/ts/nx-plugin/files/mcp-server/tools/general-guidance.ts.template +24 -0
- package/src/ts/nx-plugin/files/mcp-server/tools/generator-guide.ts.template +45 -0
- package/src/ts/nx-plugin/files/mcp-server/tools/list-generators.ts.template +27 -0
- package/src/ts/nx-plugin/files/mcp-server/utils.ts.template +97 -0
- package/src/ts/nx-plugin/generator.d.ts +10 -0
- package/src/ts/nx-plugin/generator.js +88 -0
- package/src/ts/nx-plugin/generator.js.map +1 -0
- package/src/ts/nx-plugin/schema.d.ts +11 -0
- package/src/ts/nx-plugin/schema.json +32 -0
- package/src/ts/nx-plugin/utils.d.ts +9 -0
- package/src/ts/nx-plugin/utils.js +65 -0
- package/src/ts/nx-plugin/utils.js.map +1 -0
- package/src/utils/ast.js +3 -1
- package/src/utils/ast.js.map +1 -1
- package/src/utils/config/index.d.ts +4 -0
- package/src/utils/files/common/constructs/src/core/app.ts.template +1 -1
- package/src/utils/shared-constructs.js +3 -0
- package/src/utils/shared-constructs.js.map +1 -1
- package/src/utils/zod.d.ts +0 -9
- package/src/utils/zod.js +0 -19
- package/src/utils/zod.js.map +0 -1
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`ts#nx-plugin generator > should generate MCP server files > test-plugin/src/mcp-server/index.ts 1`] = `
|
|
4
|
+
"#!/usr/bin/env node
|
|
5
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
6
|
+
import { createServer } from './server';
|
|
7
|
+
|
|
8
|
+
export const startMcpServer = async () => {
|
|
9
|
+
const transport = new StdioServerTransport();
|
|
10
|
+
await createServer().connect(transport);
|
|
11
|
+
console.error('MCP Server listening on STDIO');
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
void (async () => {
|
|
15
|
+
try {
|
|
16
|
+
await startMcpServer();
|
|
17
|
+
} catch (e) {
|
|
18
|
+
console.error(e);
|
|
19
|
+
}
|
|
20
|
+
})();
|
|
21
|
+
"
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
exports[`ts#nx-plugin generator > should generate MCP server files > test-plugin/src/mcp-server/resources/GENERAL_GUIDANCE.md 1`] = `
|
|
25
|
+
"# General Guidance
|
|
26
|
+
|
|
27
|
+
## Tool Selection Guide
|
|
28
|
+
|
|
29
|
+
- Use the \`general-guidance\` tool for guidance and best practices for working with Nx and @proj/test-plugin.
|
|
30
|
+
- Use the \`create-workspace-command\` tool to discover how to create a workspace to start a new project.
|
|
31
|
+
- Use the \`list-generators\` tool to discover the available generators and how to run them.
|
|
32
|
+
- Use the \`generator-guide\` tool to retrieve detailed information about a specific generator.
|
|
33
|
+
|
|
34
|
+
## Getting Started
|
|
35
|
+
|
|
36
|
+
- Choose a package manager first. You can choose between pnpm, bun, yarn or npm. Check if one is already in use if working in an existing project. It's recommended to use "pnpm" if the user has no preference
|
|
37
|
+
- If starting from scratch, you must create an Nx workspace. Use the \`create-workspace-command\` tool for more details, and provide it with your chosen package manager
|
|
38
|
+
- After this, you can start scaffolding the main components of your application using generators. Use the \`list-generators\` tool to discover available generators, and the \`generator-guide\` tool for more detailed information about a specific generator
|
|
39
|
+
|
|
40
|
+
## Nx Primer
|
|
41
|
+
|
|
42
|
+
- Prefix nx commands with the appropriate prefix for your package manager, for example:
|
|
43
|
+
- pnpm nx <options>
|
|
44
|
+
- bunx nx <options>
|
|
45
|
+
- npx nx <options>
|
|
46
|
+
- yarn nx <options>
|
|
47
|
+
- Each project in your workspace has a file named \`project.json\` which contains important project information such as its name, and defines the "targets" which can be run for that project, for example building or testing the project
|
|
48
|
+
- Use the command \`nx reset\` to reset the Nx daemon when unexpected issues arise
|
|
49
|
+
- After adding dependencies between TypeScript projects, use \`nx sync\` to ensure project references are set up correctly
|
|
50
|
+
|
|
51
|
+
## General Instructions
|
|
52
|
+
|
|
53
|
+
- Workspaces contain a single \`package.json\` file at the root which defines the dependencies for all projects. Therefore when installing dependencies, you must add these to the root workspace using the appropriate command for your package manager:
|
|
54
|
+
- pnpm add -w -D <package>
|
|
55
|
+
- yarn add -D <package>
|
|
56
|
+
- npm install --legacy-peer-deps -D <package>
|
|
57
|
+
- bun install -D <package>
|
|
58
|
+
- (Omit -D for production dependencies)
|
|
59
|
+
- When specifying project names as arguments to generators, prefer the _fully qualified_ project name, for example \`@workspace-name/project-name\`. Check the \`project.json\` file for the specific package to find its fully qualified name
|
|
60
|
+
- When no generator exists for a specific framework required, look for more generic project generators if availalbe and build on top of these.
|
|
61
|
+
|
|
62
|
+
## Useful Commands
|
|
63
|
+
|
|
64
|
+
- Fix lint issues with \`nx run-many --target lint --configuration=fix --all --output-style=stream\`
|
|
65
|
+
- Build all projects with \`nx run-many --target build --all --output-style=stream\`
|
|
66
|
+
- Prefer importing the CDK constructs vended by generators in \`packages/common/constructs\` over writing your own
|
|
67
|
+
|
|
68
|
+
## Best Practices
|
|
69
|
+
|
|
70
|
+
- After running a generator, use the \`nx show projects\` command to check which projects have been added (if any)
|
|
71
|
+
- Carefully examine the files that have been generated and always refer back to the generator guide when working in a generated project
|
|
72
|
+
- Generate all projects into the \`packages/\` directory
|
|
73
|
+
- After making changes to your projects, fix linting issues, then run a full build
|
|
74
|
+
"
|
|
75
|
+
`;
|
|
76
|
+
|
|
77
|
+
exports[`ts#nx-plugin generator > should generate MCP server files > test-plugin/src/mcp-server/schema.ts 1`] = `
|
|
78
|
+
"import { z } from 'zod';
|
|
79
|
+
|
|
80
|
+
export const PACKAGE_MANAGERS = ['pnpm', 'yarn', 'npm', 'bun'] as const;
|
|
81
|
+
export const PackageManagerSchema = z.enum(PACKAGE_MANAGERS);
|
|
82
|
+
"
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
exports[`ts#nx-plugin generator > should generate MCP server files > test-plugin/src/mcp-server/server.ts 1`] = `
|
|
86
|
+
"import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
87
|
+
import { registerCreateWorkspaceCommandTool } from './tools/create-workspace-command';
|
|
88
|
+
import { registerGeneralGuidanceTool } from './tools/general-guidance';
|
|
89
|
+
import { registerListGeneratorsTool } from './tools/list-generators';
|
|
90
|
+
import { registerGeneratorGuideTool } from './tools/generator-guide';
|
|
91
|
+
import { getPackageName } from './utils';
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Create the MCP Server
|
|
95
|
+
*/
|
|
96
|
+
export const createServer = () => {
|
|
97
|
+
const packageName = getPackageName();
|
|
98
|
+
|
|
99
|
+
const server = new McpServer(
|
|
100
|
+
{
|
|
101
|
+
name: packageName,
|
|
102
|
+
version: '1.0.0',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
instructions: \`# \${packageName} MCP Server
|
|
106
|
+
|
|
107
|
+
This server provides resources and tools for quickly scaffolding projects using \${packageName}.
|
|
108
|
+
|
|
109
|
+
\${packageName} provides "generators" to add projects or functionality to your workspace. Use this to build the foundations of any project you are building, if the generators apply to your use case.
|
|
110
|
+
|
|
111
|
+
## Tool Selection Guide
|
|
112
|
+
|
|
113
|
+
- Use the \\\`general-guidance\\\` tool for guidance and best practices for working with Nx and \${packageName}.
|
|
114
|
+
- Use the \\\`create-workspace-command\\\` tool to discover how to create a workspace to start a new project.
|
|
115
|
+
- Use the \\\`list-generators\\\` tool to discover the available generators and how to run them.
|
|
116
|
+
- Use the \\\`generator-guide\\\` tool to retrieve detailed information about a specific generator.\`,
|
|
117
|
+
},
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
registerCreateWorkspaceCommandTool(server);
|
|
121
|
+
registerGeneralGuidanceTool(server);
|
|
122
|
+
registerListGeneratorsTool(server);
|
|
123
|
+
registerGeneratorGuideTool(server);
|
|
124
|
+
|
|
125
|
+
return server;
|
|
126
|
+
};
|
|
127
|
+
"
|
|
128
|
+
`;
|
|
129
|
+
|
|
130
|
+
exports[`ts#nx-plugin generator > should generate MCP server files > test-plugin/src/mcp-server/tools/create-workspace-command.ts 1`] = `
|
|
131
|
+
"import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
132
|
+
import { z } from 'zod';
|
|
133
|
+
import { PackageManagerSchema } from '../schema';
|
|
134
|
+
import { buildInstallCommand, getPackageName } from '../utils';
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Registers a tool which tells a model how to create an Nx workspace
|
|
138
|
+
*/
|
|
139
|
+
export const registerCreateWorkspaceCommandTool = (server: McpServer) => {
|
|
140
|
+
server.tool(
|
|
141
|
+
'create-workspace-command',
|
|
142
|
+
'Tool to discover how to create a workspace to start a new project.',
|
|
143
|
+
{ workspaceName: z.string(), packageManager: PackageManagerSchema },
|
|
144
|
+
({ workspaceName, packageManager }) => ({
|
|
145
|
+
content: [
|
|
146
|
+
{
|
|
147
|
+
type: 'text',
|
|
148
|
+
text: \`Run the following command to create a workspace:
|
|
149
|
+
|
|
150
|
+
\\\`\\\`\\\`bash
|
|
151
|
+
npx create-nx-workspace@~21.0.3 \${workspaceName} --pm=\${packageManager} --preset=@aws/nx-plugin --ci=skip
|
|
152
|
+
\\\`\\\`\\\`
|
|
153
|
+
|
|
154
|
+
This will create a new workspace within the \${workspaceName} directory.
|
|
155
|
+
|
|
156
|
+
Then, install the plugin package to ensure generators are available:
|
|
157
|
+
|
|
158
|
+
\\\`\\\`\\\`bash
|
|
159
|
+
\${buildInstallCommand(packageManager, getPackageName())}
|
|
160
|
+
\\\`\\\`\\\`.
|
|
161
|
+
\`,
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
}),
|
|
165
|
+
);
|
|
166
|
+
};
|
|
167
|
+
"
|
|
168
|
+
`;
|
|
169
|
+
|
|
170
|
+
exports[`ts#nx-plugin generator > should generate MCP server files > test-plugin/src/mcp-server/tools/general-guidance.ts 1`] = `
|
|
171
|
+
"import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
172
|
+
import * as fs from 'fs';
|
|
173
|
+
import * as path from 'path';
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Registers a tool which provides general guidance for using Nx and this plugin
|
|
177
|
+
*/
|
|
178
|
+
export const registerGeneralGuidanceTool = (server: McpServer) => {
|
|
179
|
+
server.tool(
|
|
180
|
+
'general-guidance',
|
|
181
|
+
'Tool for guidance and best practices for working with Nx and this plugin',
|
|
182
|
+
async () => ({
|
|
183
|
+
content: [
|
|
184
|
+
{
|
|
185
|
+
type: 'text',
|
|
186
|
+
text: fs.readFileSync(
|
|
187
|
+
path.resolve(__dirname, '../resources/GENERAL_GUIDANCE.md'),
|
|
188
|
+
'utf-8',
|
|
189
|
+
),
|
|
190
|
+
},
|
|
191
|
+
],
|
|
192
|
+
}),
|
|
193
|
+
);
|
|
194
|
+
};
|
|
195
|
+
"
|
|
196
|
+
`;
|
|
197
|
+
|
|
198
|
+
exports[`ts#nx-plugin generator > should generate MCP server files > test-plugin/src/mcp-server/tools/generator-guide.ts 1`] = `
|
|
199
|
+
"import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
200
|
+
import { z } from 'zod';
|
|
201
|
+
import { renderGeneratorInfo, listGenerators } from '../utils';
|
|
202
|
+
import { PackageManagerSchema } from '../schema';
|
|
203
|
+
import * as fs from 'fs';
|
|
204
|
+
import * as path from 'path';
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Registers a tool which provides a detailed guide for an individual generator
|
|
208
|
+
*/
|
|
209
|
+
export const registerGeneratorGuideTool = (server: McpServer) => {
|
|
210
|
+
server.tool(
|
|
211
|
+
'generator-guide',
|
|
212
|
+
'Tool to retrieve detailed information about a specific generator.',
|
|
213
|
+
{
|
|
214
|
+
packageManager: PackageManagerSchema,
|
|
215
|
+
generator: z.string(),
|
|
216
|
+
},
|
|
217
|
+
async ({ packageManager, generator: generatorId }) => {
|
|
218
|
+
const generators = listGenerators();
|
|
219
|
+
const generator = generators.find((g) => g.id === generatorId);
|
|
220
|
+
if (!generator) {
|
|
221
|
+
throw new Error(
|
|
222
|
+
\`No generator found with id \${generatorId}. Available generators: \${generators.map((g) => g.id).join(' ,')}\`,
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
content: [
|
|
228
|
+
{
|
|
229
|
+
type: 'text',
|
|
230
|
+
text: \`## \${renderGeneratorInfo(packageManager, generator)}
|
|
231
|
+
|
|
232
|
+
# Guide
|
|
233
|
+
|
|
234
|
+
\${fs.readFileSync(path.join(generator.resolvedPath, 'README.md'))}
|
|
235
|
+
\`,
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
};
|
|
239
|
+
},
|
|
240
|
+
);
|
|
241
|
+
};
|
|
242
|
+
"
|
|
243
|
+
`;
|
|
244
|
+
|
|
245
|
+
exports[`ts#nx-plugin generator > should generate MCP server files > test-plugin/src/mcp-server/tools/list-generators.ts 1`] = `
|
|
246
|
+
"import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
247
|
+
import { PackageManagerSchema } from '../schema';
|
|
248
|
+
import { renderGeneratorInfo, listGenerators } from '../utils';
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Registers a tool which lists details about the available generators
|
|
252
|
+
*/
|
|
253
|
+
export const registerListGeneratorsTool = (server: McpServer) => {
|
|
254
|
+
server.tool(
|
|
255
|
+
'list-generators',
|
|
256
|
+
'Tool to discover the available generators and how to run them.',
|
|
257
|
+
{ packageManager: PackageManagerSchema },
|
|
258
|
+
({ packageManager }) => ({
|
|
259
|
+
content: [
|
|
260
|
+
{
|
|
261
|
+
type: 'text',
|
|
262
|
+
text: \`## Available Generators
|
|
263
|
+
|
|
264
|
+
\${listGenerators()
|
|
265
|
+
.map((g) => \`### \${renderGeneratorInfo(packageManager, g)}\`)
|
|
266
|
+
.join('\\n\\n')}
|
|
267
|
+
\`,
|
|
268
|
+
},
|
|
269
|
+
],
|
|
270
|
+
}),
|
|
271
|
+
);
|
|
272
|
+
};
|
|
273
|
+
"
|
|
274
|
+
`;
|
|
275
|
+
|
|
276
|
+
exports[`ts#nx-plugin generator > should generate MCP server files > test-plugin/src/mcp-server/utils.ts 1`] = `
|
|
277
|
+
"import * as fs from 'fs';
|
|
278
|
+
import * as path from 'path';
|
|
279
|
+
|
|
280
|
+
export interface NxGeneratorInfo {
|
|
281
|
+
readonly id: string;
|
|
282
|
+
readonly resolvedPath: string;
|
|
283
|
+
readonly description?: string;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export const getPackageName = (): string =>
|
|
287
|
+
JSON.parse(
|
|
288
|
+
fs.readFileSync(path.resolve(__dirname, '../../package.json'), 'utf-8'),
|
|
289
|
+
).name;
|
|
290
|
+
|
|
291
|
+
export const listGenerators = (): NxGeneratorInfo[] =>
|
|
292
|
+
Object.entries(
|
|
293
|
+
JSON.parse(
|
|
294
|
+
fs.readFileSync(
|
|
295
|
+
path.resolve(__dirname, '../../generators.json'),
|
|
296
|
+
'utf-8',
|
|
297
|
+
),
|
|
298
|
+
).generators,
|
|
299
|
+
).map(([id, info]: any) => ({
|
|
300
|
+
id,
|
|
301
|
+
resolvedPath: path.resolve(__dirname, '..', '..', info.factory, '..'),
|
|
302
|
+
description: info.description,
|
|
303
|
+
}));
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Build a command to run nx
|
|
307
|
+
*/
|
|
308
|
+
export const buildNxCommand = (command: string, pm?: string) =>
|
|
309
|
+
\`\${
|
|
310
|
+
pm
|
|
311
|
+
? \`\${
|
|
312
|
+
{
|
|
313
|
+
npm: 'npx',
|
|
314
|
+
bun: 'bunx',
|
|
315
|
+
}[pm] ?? pm
|
|
316
|
+
} \`
|
|
317
|
+
: ''
|
|
318
|
+
}nx \${command}\`;
|
|
319
|
+
|
|
320
|
+
export const buildInstallCommand = (pm: string, pkg: string) =>
|
|
321
|
+
({
|
|
322
|
+
pnpm: \`pnpm add -Dw \${pkg}\`,
|
|
323
|
+
yarn: \`yarn add -D \${pkg}\`,
|
|
324
|
+
npm: \`npm install --legacy-peer-deps -D \${pkg}\`,
|
|
325
|
+
bun: \`bun install -D \${pkg}\`,
|
|
326
|
+
})[pm];
|
|
327
|
+
|
|
328
|
+
const renderSchema = (schema: any) =>
|
|
329
|
+
Object.entries(schema.properties)
|
|
330
|
+
.map(
|
|
331
|
+
([parameter, parameterSchema]: [string, any]) =>
|
|
332
|
+
\`- \${parameter} [type: \${parameterSchema.type}]\${(schema.required ?? []).includes(parameter) ? \` (required)\` : ''} \${parameterSchema.description}\`,
|
|
333
|
+
)
|
|
334
|
+
.join('\\n');
|
|
335
|
+
|
|
336
|
+
const renderGeneratorCommand = (
|
|
337
|
+
generatorId: string,
|
|
338
|
+
schema: any,
|
|
339
|
+
packageManager?: string,
|
|
340
|
+
) => \`\\\`\\\`\\\`bash
|
|
341
|
+
\${buildNxCommand(
|
|
342
|
+
\`g \${getPackageName()}:\${generatorId} --no-interactive \${Object.entries(
|
|
343
|
+
schema.properties,
|
|
344
|
+
)
|
|
345
|
+
.filter(([parameter]) => (schema.required ?? []).includes(parameter))
|
|
346
|
+
.map(([parameter]: [string, any]) => \`--\${parameter}=<\${parameter}>\`)
|
|
347
|
+
.join(' ')}\`,
|
|
348
|
+
packageManager,
|
|
349
|
+
)}
|
|
350
|
+
\\\`\\\`\\\`\`;
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Render summary information about a generator
|
|
354
|
+
*/
|
|
355
|
+
export const renderGeneratorInfo = (
|
|
356
|
+
packageManager: string,
|
|
357
|
+
info: NxGeneratorInfo,
|
|
358
|
+
): string => {
|
|
359
|
+
const schema = JSON.parse(
|
|
360
|
+
fs.readFileSync(path.join(info.resolvedPath, 'schema.json'), 'utf-8'),
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
return \`\${info.id}
|
|
364
|
+
|
|
365
|
+
Description: \${info.description}
|
|
366
|
+
|
|
367
|
+
Available Parameters:
|
|
368
|
+
\${renderSchema(schema)}
|
|
369
|
+
|
|
370
|
+
Command:
|
|
371
|
+
\${renderGeneratorCommand(info.id, schema, packageManager)}
|
|
372
|
+
\`;
|
|
373
|
+
};
|
|
374
|
+
"
|
|
375
|
+
`;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# General Guidance
|
|
2
|
+
|
|
3
|
+
## Tool Selection Guide
|
|
4
|
+
|
|
5
|
+
- Use the `general-guidance` tool for guidance and best practices for working with Nx and <%- name %>.
|
|
6
|
+
- Use the `create-workspace-command` tool to discover how to create a workspace to start a new project.
|
|
7
|
+
- Use the `list-generators` tool to discover the available generators and how to run them.
|
|
8
|
+
- Use the `generator-guide` tool to retrieve detailed information about a specific generator.
|
|
9
|
+
|
|
10
|
+
## Getting Started
|
|
11
|
+
|
|
12
|
+
- Choose a package manager first. You can choose between pnpm, bun, yarn or npm. Check if one is already in use if working in an existing project. It's recommended to use "pnpm" if the user has no preference
|
|
13
|
+
- If starting from scratch, you must create an Nx workspace. Use the `create-workspace-command` tool for more details, and provide it with your chosen package manager
|
|
14
|
+
- After this, you can start scaffolding the main components of your application using generators. Use the `list-generators` tool to discover available generators, and the `generator-guide` tool for more detailed information about a specific generator
|
|
15
|
+
|
|
16
|
+
## Nx Primer
|
|
17
|
+
|
|
18
|
+
- Prefix nx commands with the appropriate prefix for your package manager, for example:
|
|
19
|
+
- pnpm nx <options>
|
|
20
|
+
- bunx nx <options>
|
|
21
|
+
- npx nx <options>
|
|
22
|
+
- yarn nx <options>
|
|
23
|
+
- Each project in your workspace has a file named `project.json` which contains important project information such as its name, and defines the "targets" which can be run for that project, for example building or testing the project
|
|
24
|
+
- Use the command `nx reset` to reset the Nx daemon when unexpected issues arise
|
|
25
|
+
- After adding dependencies between TypeScript projects, use `nx sync` to ensure project references are set up correctly
|
|
26
|
+
|
|
27
|
+
## General Instructions
|
|
28
|
+
|
|
29
|
+
- Workspaces contain a single `package.json` file at the root which defines the dependencies for all projects. Therefore when installing dependencies, you must add these to the root workspace using the appropriate command for your package manager:
|
|
30
|
+
- pnpm add -w -D <package>
|
|
31
|
+
- yarn add -D <package>
|
|
32
|
+
- npm install --legacy-peer-deps -D <package>
|
|
33
|
+
- bun install -D <package>
|
|
34
|
+
- (Omit -D for production dependencies)
|
|
35
|
+
- When specifying project names as arguments to generators, prefer the _fully qualified_ project name, for example `@workspace-name/project-name`. Check the `project.json` file for the specific package to find its fully qualified name
|
|
36
|
+
- When no generator exists for a specific framework required, look for more generic project generators if availalbe and build on top of these.
|
|
37
|
+
|
|
38
|
+
## Useful Commands
|
|
39
|
+
|
|
40
|
+
- Fix lint issues with `nx run-many --target lint --configuration=fix --all --output-style=stream`
|
|
41
|
+
- Build all projects with `nx run-many --target build --all --output-style=stream`
|
|
42
|
+
- Prefer importing the CDK constructs vended by generators in `packages/common/constructs` over writing your own
|
|
43
|
+
|
|
44
|
+
## Best Practices
|
|
45
|
+
|
|
46
|
+
- After running a generator, use the `nx show projects` command to check which projects have been added (if any)
|
|
47
|
+
- Carefully examine the files that have been generated and always refer back to the generator guide when working in a generated project
|
|
48
|
+
- Generate all projects into the `packages/` directory
|
|
49
|
+
- After making changes to your projects, fix linting issues, then run a full build
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { registerCreateWorkspaceCommandTool } from './tools/create-workspace-command';
|
|
3
|
+
import { registerGeneralGuidanceTool } from './tools/general-guidance';
|
|
4
|
+
import { registerListGeneratorsTool } from './tools/list-generators';
|
|
5
|
+
import { registerGeneratorGuideTool } from './tools/generator-guide';
|
|
6
|
+
import { getPackageName } from './utils';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Create the MCP Server
|
|
10
|
+
*/
|
|
11
|
+
export const createServer = () => {
|
|
12
|
+
const packageName = getPackageName();
|
|
13
|
+
|
|
14
|
+
const server = new McpServer(
|
|
15
|
+
{
|
|
16
|
+
name: packageName,
|
|
17
|
+
version: '1.0.0',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
instructions: `# ${packageName} MCP Server
|
|
21
|
+
|
|
22
|
+
This server provides resources and tools for quickly scaffolding projects using ${packageName}.
|
|
23
|
+
|
|
24
|
+
${packageName} provides "generators" to add projects or functionality to your workspace. Use this to build the foundations of any project you are building, if the generators apply to your use case.
|
|
25
|
+
|
|
26
|
+
## Tool Selection Guide
|
|
27
|
+
|
|
28
|
+
- Use the \`general-guidance\` tool for guidance and best practices for working with Nx and ${packageName}.
|
|
29
|
+
- Use the \`create-workspace-command\` tool to discover how to create a workspace to start a new project.
|
|
30
|
+
- Use the \`list-generators\` tool to discover the available generators and how to run them.
|
|
31
|
+
- Use the \`generator-guide\` tool to retrieve detailed information about a specific generator.`,
|
|
32
|
+
},
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
registerCreateWorkspaceCommandTool(server);
|
|
36
|
+
registerGeneralGuidanceTool(server);
|
|
37
|
+
registerListGeneratorsTool(server);
|
|
38
|
+
registerGeneratorGuideTool(server);
|
|
39
|
+
|
|
40
|
+
return server;
|
|
41
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { PackageManagerSchema } from '../schema';
|
|
4
|
+
import { buildInstallCommand, getPackageName } from '../utils';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Registers a tool which tells a model how to create an Nx workspace
|
|
8
|
+
*/
|
|
9
|
+
export const registerCreateWorkspaceCommandTool = (server: McpServer) => {
|
|
10
|
+
server.tool(
|
|
11
|
+
'create-workspace-command',
|
|
12
|
+
'Tool to discover how to create a workspace to start a new project.',
|
|
13
|
+
{ workspaceName: z.string(), packageManager: PackageManagerSchema },
|
|
14
|
+
({ workspaceName, packageManager }) => ({
|
|
15
|
+
content: [
|
|
16
|
+
{
|
|
17
|
+
type: 'text',
|
|
18
|
+
text: `Run the following command to create a workspace:
|
|
19
|
+
|
|
20
|
+
\`\`\`bash
|
|
21
|
+
npx create-nx-workspace@~21.0.3 ${workspaceName} --pm=${packageManager} --preset=@aws/nx-plugin --ci=skip
|
|
22
|
+
\`\`\`
|
|
23
|
+
|
|
24
|
+
This will create a new workspace within the ${workspaceName} directory.
|
|
25
|
+
|
|
26
|
+
Then, install the plugin package to ensure generators are available:
|
|
27
|
+
|
|
28
|
+
\`\`\`bash
|
|
29
|
+
${buildInstallCommand(packageManager, getPackageName())}
|
|
30
|
+
\`\`\`.
|
|
31
|
+
`,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
}),
|
|
35
|
+
);
|
|
36
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Registers a tool which provides general guidance for using Nx and this plugin
|
|
7
|
+
*/
|
|
8
|
+
export const registerGeneralGuidanceTool = (server: McpServer) => {
|
|
9
|
+
server.tool(
|
|
10
|
+
'general-guidance',
|
|
11
|
+
'Tool for guidance and best practices for working with Nx and this plugin',
|
|
12
|
+
async () => ({
|
|
13
|
+
content: [
|
|
14
|
+
{
|
|
15
|
+
type: 'text',
|
|
16
|
+
text: fs.readFileSync(
|
|
17
|
+
path.resolve(__dirname, '../resources/GENERAL_GUIDANCE.md'),
|
|
18
|
+
'utf-8',
|
|
19
|
+
),
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
24
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { renderGeneratorInfo, listGenerators } from '../utils';
|
|
4
|
+
import { PackageManagerSchema } from '../schema';
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Registers a tool which provides a detailed guide for an individual generator
|
|
10
|
+
*/
|
|
11
|
+
export const registerGeneratorGuideTool = (
|
|
12
|
+
server: McpServer,
|
|
13
|
+
) => {
|
|
14
|
+
server.tool(
|
|
15
|
+
'generator-guide',
|
|
16
|
+
'Tool to retrieve detailed information about a specific generator.',
|
|
17
|
+
{
|
|
18
|
+
packageManager: PackageManagerSchema,
|
|
19
|
+
generator: z.string(),
|
|
20
|
+
},
|
|
21
|
+
async ({ packageManager, generator: generatorId }) => {
|
|
22
|
+
const generators = listGenerators();
|
|
23
|
+
const generator = generators.find((g) => g.id === generatorId);
|
|
24
|
+
if (!generator) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`No generator found with id ${generatorId}. Available generators: ${generators.map((g) => g.id).join(' ,')}`,
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
content: [
|
|
32
|
+
{
|
|
33
|
+
type: 'text',
|
|
34
|
+
text: `## ${renderGeneratorInfo(packageManager, generator)}
|
|
35
|
+
|
|
36
|
+
# Guide
|
|
37
|
+
|
|
38
|
+
${fs.readFileSync(path.join(generator.resolvedPath, 'README.md'))}
|
|
39
|
+
`,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
);
|
|
45
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { PackageManagerSchema } from '../schema';
|
|
3
|
+
import { renderGeneratorInfo, listGenerators } from '../utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Registers a tool which lists details about the available generators
|
|
7
|
+
*/
|
|
8
|
+
export const registerListGeneratorsTool = (
|
|
9
|
+
server: McpServer,
|
|
10
|
+
) => {
|
|
11
|
+
server.tool(
|
|
12
|
+
'list-generators',
|
|
13
|
+
'Tool to discover the available generators and how to run them.',
|
|
14
|
+
{ packageManager: PackageManagerSchema },
|
|
15
|
+
({ packageManager }) => ({
|
|
16
|
+
content: [
|
|
17
|
+
{
|
|
18
|
+
type: 'text',
|
|
19
|
+
text: `## Available Generators
|
|
20
|
+
|
|
21
|
+
${listGenerators().map((g) => `### ${renderGeneratorInfo(packageManager, g)}`).join('\n\n')}
|
|
22
|
+
`,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
}),
|
|
26
|
+
);
|
|
27
|
+
};
|