create-mcp-kit 0.0.5 → 0.0.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mcp-kit",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "create mcp tool kit",
5
5
  "type": "module",
6
6
  "author": "zhensherlock",
@@ -43,7 +43,7 @@
43
43
  "gradient-string": "^3.0.0",
44
44
  "handlebars": "^4.7.8",
45
45
  "picocolors": "^1.1.1",
46
- "@mcp-tool-kit/shared": "^0.0.6"
46
+ "@mcp-tool-kit/shared": "^0.0.7"
47
47
  },
48
48
  "devDependencies": {},
49
49
  "scripts": {
@@ -31,7 +31,8 @@
31
31
  {{/if}}
32
32
  {{#if (includes plugins 'vitest')}}
33
33
  "test": "vitest run",
34
- "coverage": "rimraf coverage && npm run test && c8 report --reporter=lcov --reporter=html",
34
+ "report": "c8 report --reporter=lcov --reporter=html",
35
+ "coverage": "rimraf coverage && npm run test && npm run report",
35
36
  {{/if}}
36
37
  {{#if (includes plugins 'changelog')}}
37
38
  "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 -n changelog-option.js",
@@ -54,7 +55,7 @@
54
55
  "@commitlint/config-conventional": "^19.8.1",
55
56
  {{/if}}
56
57
  {{#if (includes plugins 'inspector')}}
57
- "@modelcontextprotocol/inspector": "^0.16.2",
58
+ "@modelcontextprotocol/inspector": "^0.16.3",
58
59
  {{/if}}
59
60
  {{#if (includes plugins 'vitest')}}
60
61
  "@vitest/coverage-v8": "^3.2.4",
@@ -1,6 +1,6 @@
1
1
  {{#if (or (includes transports 'streamable') (includes transports 'sse'))}}
2
2
  {{#if (includes transports 'streamable')}}
3
- import { nanoid } from 'nanoid'
3
+ import { nanoid } from 'nanoid'
4
4
  {{/if}}
5
5
  import express from 'express'
6
6
  {{#if (includes transports 'streamable')}}
@@ -0,0 +1,16 @@
1
+ export function waitForValue(getterFn, checkInterval = 100, timeout = 10000) {
2
+ return new Promise((resolve, reject) => {
3
+ const start = Date.now()
4
+
5
+ const intervalId = setInterval(() => {
6
+ const value = getterFn()
7
+ if (value) {
8
+ clearInterval(intervalId)
9
+ resolve(value)
10
+ } else if (Date.now() - start > timeout) {
11
+ clearInterval(intervalId)
12
+ reject(new Error('Timeout waiting for value'))
13
+ }
14
+ }, checkInterval)
15
+ })
16
+ }
@@ -3,10 +3,22 @@ import { defineConfig } from 'vitest/config'
3
3
 
4
4
  export default defineConfig({
5
5
  test: {
6
+ {{#if (or (includes transports 'streamable') (includes transports 'sse'))}}
7
+ globalSetup: ['./vitest.global.js'],
8
+ {{/if}}
6
9
  setupFiles: ['./vitest.setup.js'],
7
10
  coverage: {
8
11
  include: ['src/**/*.js'],
9
12
  },
13
+ {{#if (or (includes transports 'streamable') (includes transports 'sse'))}}
14
+ pool: 'threads',
15
+ poolOptions: {
16
+ threads: {
17
+ maxThreads: 1,
18
+ minThreads: 1,
19
+ },
20
+ },
21
+ {{/if}}
10
22
  },
11
23
  })
12
24
  {{/if}}
@@ -0,0 +1,25 @@
1
+ {{#if (and (includes plugins 'vitest') (or (includes transports 'streamable') (includes transports 'sse')))}}
2
+ import { spawn } from 'child_process'
3
+ import { waitForValue } from './tests/utils.js'
4
+
5
+ export default async function setup() {
6
+ const webProcess = spawn('c8', ['--reporter=lcov', '--reporter=text', 'node', './src/index.js', 'web'], {
7
+ stdio: 'pipe',
8
+ env: {
9
+ ...process.env,
10
+ NODE_V8_COVERAGE: './coverage/tmp',
11
+ },
12
+ })
13
+ let webStarted = false
14
+ webProcess.stdout?.on('data', async data => {
15
+ const output = data.toString()
16
+ if (output.includes('MCP server started')) {
17
+ webStarted = true
18
+ }
19
+ })
20
+ await waitForValue(() => webStarted)
21
+ return () => {
22
+ webProcess.kill('SIGINT')
23
+ }
24
+ }
25
+ {{/if}}
@@ -1,21 +1,44 @@
1
1
  {{#if (includes plugins 'vitest')}}
2
2
  import 'dotenv/config'
3
3
  import { Client } from '@modelcontextprotocol/sdk/client/index.js'
4
+ {{#if (includes transports 'stdio')}}
4
5
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
6
+ {{/if}}
7
+ {{#if (includes transports 'streamable')}}
8
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
9
+ {{/if}}
10
+ {{#if (includes transports 'sse')}}
11
+ import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'
12
+ {{/if}}
5
13
 
6
- const serverParams = new StdioClientTransport({
7
- command: 'nyc',
8
- args: ['--merge-async', '--reporter=lcov', '--reporter=text', 'node', './src/index.js'],
14
+ const client = new Client({
15
+ name: 'test-mcp-client',
16
+ version: '1.0.0',
17
+ })
18
+
19
+ {{#if (includes transports 'stdio')}}
20
+ const stdioClientTransport = new StdioClientTransport({
21
+ command: 'c8',
22
+ args: ['--reporter=lcov', '--reporter=text', 'node', './src/index.js'],
9
23
  env: {
10
24
  ...process.env,
11
25
  NODE_V8_COVERAGE: './coverage/tmp',
12
26
  },
13
27
  })
14
- const client = new Client({
15
- name: 'test-mcp-client',
16
- version: '1.0.0',
17
- })
18
- await client.connect(serverParams)
28
+ await client.connect(stdioClientTransport)
29
+
30
+ {{/if}}
31
+ {{#if (includes transports 'streamable')}}
32
+ const streamableBaseUrl = new URL('http://localhost:8401/mcp')
33
+ const streamableClientTransport = new StreamableHTTPClientTransport(new URL(streamableBaseUrl))
34
+ await client.connect(streamableClientTransport)
35
+
36
+ {{/if}}
37
+ {{#if (includes transports 'sse')}}
38
+ const sseBaseUrl = new URL('http://localhost:8401/sse')
39
+ const sseClientTransport = new SSEClientTransport(new URL(sseBaseUrl))
40
+ await client.connect(sseClientTransport)
19
41
 
42
+ {{/if}}
20
43
  global.client = client
21
44
  {{/if}}
@@ -31,7 +31,8 @@
31
31
  {{/if}}
32
32
  {{#if (includes plugins 'vitest')}}
33
33
  "test": "vitest run",
34
- "coverage": "rimraf coverage && npm run test && c8 report --reporter=lcov --reporter=html",
34
+ "report": "c8 report --reporter=lcov --reporter=html",
35
+ "coverage": "rimraf coverage && npm run test && npm run report",
35
36
  {{/if}}
36
37
  {{#if (includes plugins 'changelog')}}
37
38
  "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0 -n changelog-option.js",
@@ -54,15 +55,15 @@
54
55
  "@commitlint/config-conventional": "^19.8.1",
55
56
  {{/if}}
56
57
  {{#if (includes plugins 'inspector')}}
57
- "@modelcontextprotocol/inspector": "^0.16.2",
58
+ "@modelcontextprotocol/inspector": "^0.16.3",
58
59
  {{/if}}
59
60
  {{#if (or (includes transports 'streamable') (includes transports 'sse'))}}
60
61
  "@types/express": "^5.0.3",
61
62
  {{/if}}
62
63
  "@types/yargs": "^17.0.33",
63
64
  {{#if (includes plugins 'style')}}
64
- "@typescript-eslint/eslint-plugin": "^8.38.0",
65
- "@typescript-eslint/parser": "^8.38.0",
65
+ "@typescript-eslint/eslint-plugin": "^8.39.1",
66
+ "@typescript-eslint/parser": "^8.39.1",
66
67
  {{/if}}
67
68
  {{#if (includes plugins 'vitest')}}
68
69
  "@vitest/coverage-v8": "^3.2.4",
@@ -1,6 +1,6 @@
1
1
  {{#if (or (includes transports 'streamable') (includes transports 'sse'))}}
2
2
  {{#if (includes transports 'streamable')}}
3
- import { nanoid } from 'nanoid'
3
+ import { nanoid } from 'nanoid'
4
4
  {{/if}}
5
5
  import express from 'express'
6
6
  {{#if (includes transports 'streamable')}}
@@ -0,0 +1,20 @@
1
+ export function waitForValue<T>(
2
+ getterFn: () => T | undefined | null,
3
+ checkInterval = 100,
4
+ timeout = 10000,
5
+ ): Promise<T> {
6
+ return new Promise((resolve, reject) => {
7
+ const start = Date.now()
8
+
9
+ const intervalId = setInterval(() => {
10
+ const value = getterFn()
11
+ if (value) {
12
+ clearInterval(intervalId)
13
+ resolve(value)
14
+ } else if (Date.now() - start > timeout) {
15
+ clearInterval(intervalId)
16
+ reject(new Error('Timeout waiting for value'))
17
+ }
18
+ }, checkInterval)
19
+ })
20
+ }
@@ -3,10 +3,22 @@ import { defineConfig } from 'vitest/config'
3
3
 
4
4
  export default defineConfig({
5
5
  test: {
6
+ {{#if (or (includes transports 'streamable') (includes transports 'sse'))}}
7
+ globalSetup: ['./vitest.global.ts'],
8
+ {{/if}}
6
9
  setupFiles: ['./vitest.setup.ts'],
7
10
  coverage: {
8
11
  include: ['src/**/*.ts'],
9
12
  },
13
+ {{#if (or (includes transports 'streamable') (includes transports 'sse'))}}
14
+ pool: 'threads',
15
+ poolOptions: {
16
+ threads: {
17
+ maxThreads: 1,
18
+ minThreads: 1,
19
+ },
20
+ },
21
+ {{/if}}
10
22
  },
11
23
  })
12
24
  {{/if}}
@@ -0,0 +1,25 @@
1
+ {{#if (and (includes plugins 'vitest') (or (includes transports 'streamable') (includes transports 'sse')))}}
2
+ import { spawn } from 'child_process'
3
+ import { waitForValue } from './tests/utils'
4
+
5
+ export default async function setup() {
6
+ const webProcess = spawn('c8', ['--reporter=lcov', '--reporter=text', 'tsx', './src/index.ts', 'web'], {
7
+ stdio: 'pipe',
8
+ env: {
9
+ ...(process.env as Record<string, string>),
10
+ NODE_V8_COVERAGE: './coverage/tmp',
11
+ },
12
+ })
13
+ let webStarted = false
14
+ webProcess.stdout?.on('data', async data => {
15
+ const output = data.toString()
16
+ if (output.includes('MCP server started')) {
17
+ webStarted = true
18
+ }
19
+ })
20
+ await waitForValue(() => webStarted)
21
+ return () => {
22
+ webProcess.kill('SIGINT')
23
+ }
24
+ }
25
+ {{/if}}
@@ -1,27 +1,44 @@
1
1
  {{#if (includes plugins 'vitest')}}
2
2
  import 'dotenv/config'
3
3
  import { Client } from '@modelcontextprotocol/sdk/client/index.js'
4
+ {{#if (includes transports 'stdio')}}
4
5
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'
6
+ {{/if}}
7
+ {{#if (includes transports 'streamable')}}
8
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
9
+ {{/if}}
10
+ {{#if (includes transports 'sse')}}
11
+ import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'
12
+ {{/if}}
5
13
 
6
- const serverParams = new StdioClientTransport({
7
- command: 'nyc',
8
- args: [
9
- '--merge-async',
10
- '--reporter=lcov',
11
- '--reporter=text',
12
- 'tsx',
13
- './src/index.ts',
14
- ],
14
+ const client = new Client({
15
+ name: 'test-mcp-client',
16
+ version: '1.0.0',
17
+ })
18
+
19
+ {{#if (includes transports 'stdio')}}
20
+ const stdioClientTransport = new StdioClientTransport({
21
+ command: 'c8',
22
+ args: ['--reporter=lcov', '--reporter=text', 'tsx', './src/index.ts'],
15
23
  env: {
16
24
  ...process.env as Record<string, string>,
17
25
  NODE_V8_COVERAGE: './coverage/tmp',
18
26
  },
19
27
  })
20
- const client = new Client({
21
- name: 'test-mcp-client',
22
- version: '1.0.0',
23
- })
24
- await client.connect(serverParams)
28
+ await client.connect(stdioClientTransport)
29
+
30
+ {{/if}}
31
+ {{#if (includes transports 'streamable')}}
32
+ const streamableBaseUrl = new URL('http://localhost:8401/mcp')
33
+ const streamableClientTransport = new StreamableHTTPClientTransport(new URL(streamableBaseUrl))
34
+ await client.connect(streamableClientTransport)
35
+
36
+ {{/if}}
37
+ {{#if (includes transports 'sse')}}
38
+ const sseBaseUrl = new URL('http://localhost:8401/sse')
39
+ const sseClientTransport = new SSEClientTransport(new URL(sseBaseUrl))
40
+ await client.connect(sseClientTransport)
25
41
 
42
+ {{/if}}
26
43
  global.client = client
27
44
  {{/if}}