@agentailor/create-mcp-server 0.2.0 → 0.2.1
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/dist/index.js +1 -1
- package/dist/templates/common/env.example.d.ts +1 -0
- package/dist/templates/common/package.json.d.ts +1 -0
- package/dist/templates/stateful-streamable-http/index.d.ts +1 -0
- package/dist/templates/stateful-streamable-http/index.js +38 -10
- package/dist/templates/stateful-streamable-http/readme.js +10 -4
- package/dist/templates/stateful-streamable-http/templates.test.js +28 -1
- package/dist/templates/streamable-http/index.d.ts +1 -0
- package/dist/templates/streamable-http/index.js +19 -7
- package/dist/templates/streamable-http/readme.js +10 -6
- package/dist/templates/streamable-http/templates.test.js +28 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -98,7 +98,7 @@ async function main() {
|
|
|
98
98
|
initial: true,
|
|
99
99
|
}, { onCancel });
|
|
100
100
|
const withGitInit = gitInitResponse.withGitInit ?? false;
|
|
101
|
-
const templateOptions = { withOAuth };
|
|
101
|
+
const templateOptions = { withOAuth, packageManager };
|
|
102
102
|
const templates = templateFunctions[templateType];
|
|
103
103
|
const projectPath = join(process.cwd(), projectName);
|
|
104
104
|
const srcPath = join(projectPath, 'src');
|
|
@@ -29,10 +29,6 @@ import { getServer } from './server.js';`;
|
|
|
29
29
|
const deleteRoute = withOAuth
|
|
30
30
|
? `app.delete('/mcp', authMiddleware, async (req: Request, res: Response) => {`
|
|
31
31
|
: `app.delete('/mcp', async (req: Request, res: Response) => {`;
|
|
32
|
-
const startupLog = withOAuth
|
|
33
|
-
? `console.log(\`MCP Stateful HTTP Server listening on port \${PORT}\`);
|
|
34
|
-
console.log(\`OAuth metadata available at \${getOAuthMetadataUrl()}\`);`
|
|
35
|
-
: `console.log(\`MCP Stateful HTTP Server listening on port \${PORT}\`);`;
|
|
36
32
|
return `${imports}
|
|
37
33
|
|
|
38
34
|
${appSetup}
|
|
@@ -144,6 +140,24 @@ ${withOAuth
|
|
|
144
140
|
? `// Start the server
|
|
145
141
|
const PORT = process.env.PORT || 3000;
|
|
146
142
|
|
|
143
|
+
function startServer(port: number | string): void {
|
|
144
|
+
const server = app.listen(port, () => {
|
|
145
|
+
console.log(\`MCP Stateful HTTP Server listening on port \${port}\`);
|
|
146
|
+
console.log(\`OAuth metadata available at \${getOAuthMetadataUrl()}\`);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
server.on('error', (error: NodeJS.ErrnoException) => {
|
|
150
|
+
if (error.code === 'EADDRINUSE') {
|
|
151
|
+
const randomPort = Math.floor(Math.random() * (65535 - 49152) + 49152);
|
|
152
|
+
console.log(\`Port \${port} is in use, trying port \${randomPort}...\`);
|
|
153
|
+
startServer(randomPort);
|
|
154
|
+
} else {
|
|
155
|
+
console.error('Failed to start server:', error);
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
147
161
|
async function main() {
|
|
148
162
|
// Validate OAuth configuration and fetch OIDC discovery document
|
|
149
163
|
await validateOAuthConfig();
|
|
@@ -151,9 +165,7 @@ async function main() {
|
|
|
151
165
|
// Setup OAuth metadata routes (must be after validateOAuthConfig)
|
|
152
166
|
setupAuthMetadataRouter(app);
|
|
153
167
|
|
|
154
|
-
|
|
155
|
-
${startupLog}
|
|
156
|
-
});
|
|
168
|
+
startServer(PORT);
|
|
157
169
|
}
|
|
158
170
|
|
|
159
171
|
main().catch((error) => {
|
|
@@ -162,9 +174,25 @@ main().catch((error) => {
|
|
|
162
174
|
});`
|
|
163
175
|
: `// Start the server
|
|
164
176
|
const PORT = process.env.PORT || 3000;
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
177
|
+
|
|
178
|
+
function startServer(port: number | string): void {
|
|
179
|
+
const server = app.listen(port, () => {
|
|
180
|
+
console.log(\`MCP Stateful HTTP Server listening on port \${port}\`);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
server.on('error', (error: NodeJS.ErrnoException) => {
|
|
184
|
+
if (error.code === 'EADDRINUSE') {
|
|
185
|
+
const randomPort = Math.floor(Math.random() * (65535 - 49152) + 49152);
|
|
186
|
+
console.log(\`Port \${port} is in use, trying port \${randomPort}...\`);
|
|
187
|
+
startServer(randomPort);
|
|
188
|
+
} else {
|
|
189
|
+
console.error('Failed to start server:', error);
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
startServer(PORT);`}
|
|
168
196
|
|
|
169
197
|
// Handle server shutdown
|
|
170
198
|
process.on('SIGINT', async () => {
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
export function getReadmeTemplate(projectName, options) {
|
|
2
2
|
const withOAuth = options?.withOAuth ?? false;
|
|
3
|
+
const packageManager = options?.packageManager ?? 'npm';
|
|
4
|
+
const commands = {
|
|
5
|
+
npm: { install: 'npm install', dev: 'npm run dev', build: 'npm run build', start: 'npm start' },
|
|
6
|
+
pnpm: { install: 'pnpm install', dev: 'pnpm dev', build: 'pnpm build', start: 'pnpm start' },
|
|
7
|
+
yarn: { install: 'yarn', dev: 'yarn dev', build: 'yarn build', start: 'yarn start' },
|
|
8
|
+
}[packageManager];
|
|
3
9
|
const description = withOAuth
|
|
4
10
|
? 'A stateful streamable HTTP MCP (Model Context Protocol) server with session management and OAuth authentication.'
|
|
5
11
|
: 'A stateful streamable HTTP MCP (Model Context Protocol) server with session management.';
|
|
@@ -85,14 +91,14 @@ This project was created with [@agentailor/create-mcp-server](https://www.npmjs.
|
|
|
85
91
|
|
|
86
92
|
\`\`\`bash
|
|
87
93
|
# Install dependencies
|
|
88
|
-
|
|
94
|
+
${commands.install}
|
|
89
95
|
|
|
90
96
|
# Build and run in development
|
|
91
|
-
|
|
97
|
+
${commands.dev}
|
|
92
98
|
|
|
93
99
|
# Or build and start separately
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
${commands.build}
|
|
101
|
+
${commands.start}
|
|
96
102
|
\`\`\`
|
|
97
103
|
|
|
98
104
|
The server will start on port 3000 by default. You can change this by setting the \`PORT\` environment variable.
|
|
@@ -83,10 +83,12 @@ describe('stateful-streamable-http templates', () => {
|
|
|
83
83
|
const template = getReadmeTemplate(projectName);
|
|
84
84
|
expect(template).toContain(`# ${projectName}`);
|
|
85
85
|
});
|
|
86
|
-
it('should include getting started instructions', () => {
|
|
86
|
+
it('should include getting started instructions with npm by default', () => {
|
|
87
87
|
const template = getReadmeTemplate(projectName);
|
|
88
88
|
expect(template).toContain('npm install');
|
|
89
89
|
expect(template).toContain('npm run dev');
|
|
90
|
+
expect(template).toContain('npm run build');
|
|
91
|
+
expect(template).toContain('npm start');
|
|
90
92
|
});
|
|
91
93
|
it('should document the /mcp endpoint', () => {
|
|
92
94
|
const template = getReadmeTemplate(projectName);
|
|
@@ -108,6 +110,31 @@ describe('stateful-streamable-http templates', () => {
|
|
|
108
110
|
expect(template).toContain('DELETE /mcp');
|
|
109
111
|
});
|
|
110
112
|
});
|
|
113
|
+
describe('getReadmeTemplate with package manager', () => {
|
|
114
|
+
it('should use npm commands when packageManager is npm', () => {
|
|
115
|
+
const template = getReadmeTemplate(projectName, { packageManager: 'npm' });
|
|
116
|
+
expect(template).toContain('npm install');
|
|
117
|
+
expect(template).toContain('npm run dev');
|
|
118
|
+
expect(template).toContain('npm run build');
|
|
119
|
+
expect(template).toContain('npm start');
|
|
120
|
+
});
|
|
121
|
+
it('should use pnpm commands when packageManager is pnpm', () => {
|
|
122
|
+
const template = getReadmeTemplate(projectName, { packageManager: 'pnpm' });
|
|
123
|
+
expect(template).toContain('pnpm install');
|
|
124
|
+
expect(template).toContain('pnpm dev');
|
|
125
|
+
expect(template).toContain('pnpm build');
|
|
126
|
+
expect(template).toContain('pnpm start');
|
|
127
|
+
expect(template).not.toContain('npm run');
|
|
128
|
+
});
|
|
129
|
+
it('should use yarn commands when packageManager is yarn', () => {
|
|
130
|
+
const template = getReadmeTemplate(projectName, { packageManager: 'yarn' });
|
|
131
|
+
expect(template).toContain('yarn\n');
|
|
132
|
+
expect(template).toContain('yarn dev');
|
|
133
|
+
expect(template).toContain('yarn build');
|
|
134
|
+
expect(template).toContain('yarn start');
|
|
135
|
+
expect(template).not.toContain('npm run');
|
|
136
|
+
});
|
|
137
|
+
});
|
|
111
138
|
describe('getIndexTemplate with OAuth', () => {
|
|
112
139
|
it('should include auth imports when OAuth enabled', () => {
|
|
113
140
|
const template = getIndexTemplate({ withOAuth: true });
|
|
@@ -66,13 +66,25 @@ app.delete('/mcp', async (req: Request, res: Response) => {
|
|
|
66
66
|
|
|
67
67
|
// Start the server
|
|
68
68
|
const PORT = process.env.PORT || 3000;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
69
|
+
|
|
70
|
+
function startServer(port: number | string): void {
|
|
71
|
+
const server = app.listen(port, () => {
|
|
72
|
+
console.log(\`MCP Streamable HTTP Server listening on port \${port}\`);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
server.on('error', (error: NodeJS.ErrnoException) => {
|
|
76
|
+
if (error.code === 'EADDRINUSE') {
|
|
77
|
+
const randomPort = Math.floor(Math.random() * (65535 - 49152) + 49152);
|
|
78
|
+
console.log(\`Port \${port} is in use, trying port \${randomPort}...\`);
|
|
79
|
+
startServer(randomPort);
|
|
80
|
+
} else {
|
|
81
|
+
console.error('Failed to start server:', error);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
startServer(PORT);
|
|
76
88
|
|
|
77
89
|
// Handle server shutdown
|
|
78
90
|
process.on('SIGINT', async () => {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
// Options parameter added for type consistency with stateful template (OAuth not supported in stateless)
|
|
2
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3
1
|
export function getReadmeTemplate(projectName, options) {
|
|
2
|
+
const packageManager = options?.packageManager ?? 'npm';
|
|
3
|
+
const commands = {
|
|
4
|
+
npm: { install: 'npm install', dev: 'npm run dev', build: 'npm run build', start: 'npm start' },
|
|
5
|
+
pnpm: { install: 'pnpm install', dev: 'pnpm dev', build: 'pnpm build', start: 'pnpm start' },
|
|
6
|
+
yarn: { install: 'yarn', dev: 'yarn dev', build: 'yarn build', start: 'yarn start' },
|
|
7
|
+
}[packageManager];
|
|
4
8
|
return `# ${projectName}
|
|
5
9
|
|
|
6
10
|
A stateless streamable HTTP MCP (Model Context Protocol) server.
|
|
@@ -13,14 +17,14 @@ This project was created with [@agentailor/create-mcp-server](https://www.npmjs.
|
|
|
13
17
|
|
|
14
18
|
\`\`\`bash
|
|
15
19
|
# Install dependencies
|
|
16
|
-
|
|
20
|
+
${commands.install}
|
|
17
21
|
|
|
18
22
|
# Build and run in development
|
|
19
|
-
|
|
23
|
+
${commands.dev}
|
|
20
24
|
|
|
21
25
|
# Or build and start separately
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
${commands.build}
|
|
27
|
+
${commands.start}
|
|
24
28
|
\`\`\`
|
|
25
29
|
|
|
26
30
|
The server will start on port 3000 by default. You can change this by setting the \`PORT\` environment variable.
|
|
@@ -63,10 +63,12 @@ describe('streamable-http templates', () => {
|
|
|
63
63
|
const template = getReadmeTemplate(projectName);
|
|
64
64
|
expect(template).toContain(`# ${projectName}`);
|
|
65
65
|
});
|
|
66
|
-
it('should include getting started instructions', () => {
|
|
66
|
+
it('should include getting started instructions with npm by default', () => {
|
|
67
67
|
const template = getReadmeTemplate(projectName);
|
|
68
68
|
expect(template).toContain('npm install');
|
|
69
69
|
expect(template).toContain('npm run dev');
|
|
70
|
+
expect(template).toContain('npm run build');
|
|
71
|
+
expect(template).toContain('npm start');
|
|
70
72
|
});
|
|
71
73
|
it('should document the /mcp endpoint', () => {
|
|
72
74
|
const template = getReadmeTemplate(projectName);
|
|
@@ -77,4 +79,29 @@ describe('streamable-http templates', () => {
|
|
|
77
79
|
expect(template).toContain('stateless');
|
|
78
80
|
});
|
|
79
81
|
});
|
|
82
|
+
describe('getReadmeTemplate with package manager', () => {
|
|
83
|
+
it('should use npm commands when packageManager is npm', () => {
|
|
84
|
+
const template = getReadmeTemplate(projectName, { packageManager: 'npm' });
|
|
85
|
+
expect(template).toContain('npm install');
|
|
86
|
+
expect(template).toContain('npm run dev');
|
|
87
|
+
expect(template).toContain('npm run build');
|
|
88
|
+
expect(template).toContain('npm start');
|
|
89
|
+
});
|
|
90
|
+
it('should use pnpm commands when packageManager is pnpm', () => {
|
|
91
|
+
const template = getReadmeTemplate(projectName, { packageManager: 'pnpm' });
|
|
92
|
+
expect(template).toContain('pnpm install');
|
|
93
|
+
expect(template).toContain('pnpm dev');
|
|
94
|
+
expect(template).toContain('pnpm build');
|
|
95
|
+
expect(template).toContain('pnpm start');
|
|
96
|
+
expect(template).not.toContain('npm run');
|
|
97
|
+
});
|
|
98
|
+
it('should use yarn commands when packageManager is yarn', () => {
|
|
99
|
+
const template = getReadmeTemplate(projectName, { packageManager: 'yarn' });
|
|
100
|
+
expect(template).toContain('yarn\n');
|
|
101
|
+
expect(template).toContain('yarn dev');
|
|
102
|
+
expect(template).toContain('yarn build');
|
|
103
|
+
expect(template).toContain('yarn start');
|
|
104
|
+
expect(template).not.toContain('npm run');
|
|
105
|
+
});
|
|
106
|
+
});
|
|
80
107
|
});
|