@mcpmake/core 0.3.7 → 0.4.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/analyzer/dom-parser.d.ts.map +1 -1
- package/dist/analyzer/dom-parser.js +34 -19
- package/dist/analyzer/dom-parser.js.map +1 -1
- package/dist/analyzer/semantic-analyzer.d.ts.map +1 -1
- package/dist/analyzer/semantic-analyzer.js +10 -3
- package/dist/analyzer/semantic-analyzer.js.map +1 -1
- package/dist/emitter/a2a.d.ts +101 -0
- package/dist/emitter/a2a.d.ts.map +1 -0
- package/dist/emitter/a2a.js +366 -0
- package/dist/emitter/a2a.js.map +1 -0
- package/dist/emitter/code-writer.js +10 -10
- package/dist/emitter/code-writer.js.map +1 -1
- package/dist/emitter/composite-tools.d.ts +99 -0
- package/dist/emitter/composite-tools.d.ts.map +1 -0
- package/dist/emitter/composite-tools.js +391 -0
- package/dist/emitter/composite-tools.js.map +1 -0
- package/dist/emitter/mcp-ui.d.ts +42 -0
- package/dist/emitter/mcp-ui.d.ts.map +1 -0
- package/dist/emitter/mcp-ui.js +146 -0
- package/dist/emitter/mcp-ui.js.map +1 -0
- package/dist/emitter/mcpb-bundler.d.ts +56 -7
- package/dist/emitter/mcpb-bundler.d.ts.map +1 -1
- package/dist/emitter/mcpb-bundler.js +60 -11
- package/dist/emitter/mcpb-bundler.js.map +1 -1
- package/dist/emitter/normalize-tree.d.ts +17 -0
- package/dist/emitter/normalize-tree.d.ts.map +1 -0
- package/dist/emitter/normalize-tree.js +99 -0
- package/dist/emitter/normalize-tree.js.map +1 -0
- package/dist/emitter/project-scaffolder.d.ts.map +1 -1
- package/dist/emitter/project-scaffolder.js +47 -1
- package/dist/emitter/project-scaffolder.js.map +1 -1
- package/dist/emitter/python-template-loader.d.ts.map +1 -1
- package/dist/emitter/python-template-loader.js +6 -1
- package/dist/emitter/python-template-loader.js.map +1 -1
- package/dist/emitter/templates/server-main-http.ts.hbs +48 -0
- package/dist/emitter/templates/server-main.ts.hbs +38 -0
- package/dist/emitter/templates/tsconfig.json.hbs +3 -2
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/parser/overlay-loader.js +5 -1
- package/dist/parser/overlay-loader.js.map +1 -1
- package/dist/parser/postman-loader.js +7 -0
- package/dist/parser/postman-loader.js.map +1 -1
- package/dist/pricing.js +2 -2
- package/dist/pricing.js.map +1 -1
- package/dist/rescan/rescan-scheduler.js +14 -5
- package/dist/rescan/rescan-scheduler.js.map +1 -1
- package/dist/site-transformer/selector-healer.d.ts.map +1 -1
- package/dist/site-transformer/selector-healer.js +8 -0
- package/dist/site-transformer/selector-healer.js.map +1 -1
- package/dist/transformer/har-to-operations.d.ts.map +1 -1
- package/dist/transformer/har-to-operations.js +17 -6
- package/dist/transformer/har-to-operations.js.map +1 -1
- package/dist/transformer/resource-builder.d.ts.map +1 -1
- package/dist/transformer/resource-builder.js +15 -2
- package/dist/transformer/resource-builder.js.map +1 -1
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -12,25 +12,74 @@ export type ZipChecker = () => Promise<boolean>;
|
|
|
12
12
|
* @param checker injectable presence check; defaults to running `zip -v`.
|
|
13
13
|
*/
|
|
14
14
|
export declare function assertZipAvailable(checker?: ZipChecker): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* The .mcpb manifest, conformant to the official MCPB manifest schema (`manifest_version`
|
|
17
|
+
* "0.3"; https://github.com/anthropics/mcpb). NOT a custom shape — Claude Desktop / the MCPB
|
|
18
|
+
* loader validate the bundle against this schema, so the field names + nesting must match
|
|
19
|
+
* exactly (e.g. `author` is an object, `entry_point`/`type`/`mcp_config` live under `server`,
|
|
20
|
+
* and configurable env vars become `user_config`, not a flat `env_vars`).
|
|
21
|
+
*/
|
|
22
|
+
export interface McpbAuthor {
|
|
23
|
+
name: string;
|
|
24
|
+
email?: string;
|
|
25
|
+
url?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface McpbUserConfigEntry {
|
|
28
|
+
type: 'string' | 'number' | 'boolean' | 'directory' | 'file';
|
|
29
|
+
title: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
required?: boolean;
|
|
32
|
+
sensitive?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface McpbServer {
|
|
35
|
+
type: 'node' | 'python' | 'binary';
|
|
36
|
+
entry_point: string;
|
|
37
|
+
mcp_config: {
|
|
38
|
+
command: string;
|
|
39
|
+
args: string[];
|
|
40
|
+
env?: Record<string, string>;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
15
43
|
export interface McpbManifest {
|
|
16
|
-
|
|
44
|
+
manifest_version: string;
|
|
17
45
|
name: string;
|
|
46
|
+
display_name?: string;
|
|
18
47
|
version: string;
|
|
19
48
|
description: string;
|
|
20
|
-
author:
|
|
21
|
-
license
|
|
22
|
-
|
|
23
|
-
|
|
49
|
+
author: McpbAuthor;
|
|
50
|
+
license?: string;
|
|
51
|
+
server: McpbServer;
|
|
52
|
+
tools?: {
|
|
53
|
+
name: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
}[];
|
|
56
|
+
user_config?: Record<string, McpbUserConfigEntry>;
|
|
57
|
+
}
|
|
58
|
+
/** The MCPB manifest schema version this bundler targets. Bump on an MCPB manifest-spec update. */
|
|
59
|
+
export declare const MCPB_MANIFEST_VERSION = "0.3";
|
|
60
|
+
/**
|
|
61
|
+
* Build a schema-conformant MCPB manifest from a project's metadata. PURE + exported so the
|
|
62
|
+
* shape is validated against the official schema in tests without building the whole zip.
|
|
63
|
+
* Configurable env vars become `user_config` entries AND are wired into `server.mcp_config.env`
|
|
64
|
+
* as `${user_config.<key>}` so the user-supplied values reach the server process.
|
|
65
|
+
*/
|
|
66
|
+
export declare function buildMcpbManifest(input: {
|
|
67
|
+
name: string;
|
|
68
|
+
version: string;
|
|
69
|
+
description: string;
|
|
70
|
+
author?: string | McpbAuthor;
|
|
71
|
+
license?: string;
|
|
72
|
+
entryPoint?: string;
|
|
24
73
|
tools: {
|
|
25
74
|
name: string;
|
|
26
75
|
description: string;
|
|
27
76
|
}[];
|
|
28
|
-
|
|
77
|
+
envVars: {
|
|
29
78
|
name: string;
|
|
30
79
|
description: string;
|
|
31
80
|
required: boolean;
|
|
32
81
|
}[];
|
|
33
|
-
}
|
|
82
|
+
}): McpbManifest;
|
|
34
83
|
/**
|
|
35
84
|
* Generate an .mcpb bundle from a built MCP server project.
|
|
36
85
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcpb-bundler.d.ts","sourceRoot":"","sources":["../../src/emitter/mcpb-bundler.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;AAgBhD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,UAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/F;AAED,MAAM,WAAW,YAAY;IAC3B,
|
|
1
|
+
{"version":3,"file":"mcpb-bundler.d.ts","sourceRoot":"","sources":["../../src/emitter/mcpb-bundler.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;AAgBhD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,UAA8B,GAAG,OAAO,CAAC,IAAI,CAAC,CAI/F;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE;QACV,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC9B,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CACnD;AAED,mGAAmG;AACnG,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAK3C;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/C,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;CACrE,GAAG,YAAY,CAyCf;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CAClC,GAAG,OAAO,CAAC,MAAM,CAAC,CAoGlB"}
|
|
@@ -40,6 +40,55 @@ export async function assertZipAvailable(checker = defaultZipChecker) {
|
|
|
40
40
|
throw new Error(ZIP_MISSING_MESSAGE);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
+
/** The MCPB manifest schema version this bundler targets. Bump on an MCPB manifest-spec update. */
|
|
44
|
+
export const MCPB_MANIFEST_VERSION = '0.3';
|
|
45
|
+
/** An env var name that names a secret → mark its user_config entry `sensitive`. */
|
|
46
|
+
const SENSITIVE_ENV_RE = /KEY|TOKEN|SECRET|PASSWORD|PASS|CREDENTIAL|PRIVATE/i;
|
|
47
|
+
/**
|
|
48
|
+
* Build a schema-conformant MCPB manifest from a project's metadata. PURE + exported so the
|
|
49
|
+
* shape is validated against the official schema in tests without building the whole zip.
|
|
50
|
+
* Configurable env vars become `user_config` entries AND are wired into `server.mcp_config.env`
|
|
51
|
+
* as `${user_config.<key>}` so the user-supplied values reach the server process.
|
|
52
|
+
*/
|
|
53
|
+
export function buildMcpbManifest(input) {
|
|
54
|
+
const entry = input.entryPoint ?? 'server/dist/index.js';
|
|
55
|
+
const author = typeof input.author === 'string'
|
|
56
|
+
? { name: input.author.trim() || input.name }
|
|
57
|
+
: (input.author ?? { name: input.name });
|
|
58
|
+
const user_config = {};
|
|
59
|
+
const env = {};
|
|
60
|
+
for (const v of input.envVars) {
|
|
61
|
+
const key = v.name.toLowerCase();
|
|
62
|
+
user_config[key] = {
|
|
63
|
+
type: 'string',
|
|
64
|
+
title: v.name,
|
|
65
|
+
...(v.description ? { description: v.description } : {}),
|
|
66
|
+
required: v.required,
|
|
67
|
+
sensitive: SENSITIVE_ENV_RE.test(v.name),
|
|
68
|
+
};
|
|
69
|
+
env[v.name] = `\${user_config.${key}}`;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
manifest_version: MCPB_MANIFEST_VERSION,
|
|
73
|
+
name: input.name,
|
|
74
|
+
version: input.version,
|
|
75
|
+
// `description` is required by the schema; never emit empty.
|
|
76
|
+
description: input.description.trim() || `MCP server for ${input.name}`,
|
|
77
|
+
author,
|
|
78
|
+
...(input.license ? { license: input.license } : {}),
|
|
79
|
+
server: {
|
|
80
|
+
type: 'node',
|
|
81
|
+
entry_point: entry,
|
|
82
|
+
mcp_config: {
|
|
83
|
+
command: 'node',
|
|
84
|
+
args: [`\${__dirname}/${entry}`],
|
|
85
|
+
...(Object.keys(env).length > 0 ? { env } : {}),
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
tools: input.tools,
|
|
89
|
+
...(Object.keys(user_config).length > 0 ? { user_config } : {}),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
43
92
|
/**
|
|
44
93
|
* Generate an .mcpb bundle from a built MCP server project.
|
|
45
94
|
*
|
|
@@ -67,18 +116,18 @@ export async function generateMcpb(opts) {
|
|
|
67
116
|
const tools = await extractToolList(projectDir);
|
|
68
117
|
// Extract env vars from .env.example
|
|
69
118
|
const envVars = await extractEnvVars(projectDir);
|
|
70
|
-
// Build
|
|
119
|
+
// Build a schema-conformant MCPB manifest, then apply any caller overrides on top.
|
|
71
120
|
const manifest = {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
121
|
+
...buildMcpbManifest({
|
|
122
|
+
name: projectName,
|
|
123
|
+
version: projectVersion,
|
|
124
|
+
description: projectDescription,
|
|
125
|
+
author: typeof pkgJson.author === 'string' ? pkgJson.author : undefined,
|
|
126
|
+
license: typeof pkgJson.license === 'string' ? pkgJson.license : undefined,
|
|
127
|
+
tools,
|
|
128
|
+
envVars,
|
|
129
|
+
}),
|
|
130
|
+
...opts.manifest,
|
|
82
131
|
};
|
|
83
132
|
// Create temp staging directory
|
|
84
133
|
const stagingDir = await mkdtemp(join(tmpdir(), 'mcpb-'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcpb-bundler.js","sourceRoot":"","sources":["../../src/emitter/mcpb-bundler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;AAEvC;;;;GAIG;AACH,MAAM,mBAAmB,GACvB,mFAAmF;IACnF,6FAA6F;IAC7F,+CAA+C,CAAC;AASlD;;;;GAIG;AACH,MAAM,iBAAiB,GAAe,KAAK,IAAI,EAAE;IAC/C,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAsB,iBAAiB;IAC9E,IAAI,CAAC,CAAC,MAAM,OAAO,EAAE,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;
|
|
1
|
+
{"version":3,"file":"mcpb-bundler.js","sourceRoot":"","sources":["../../src/emitter/mcpb-bundler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CodeUnit } from './code-writer.js';
|
|
2
|
+
/**
|
|
3
|
+
* Return the units in canonical form: POSIX-normalized paths, de-duplicated, sorted byte-wise by
|
|
4
|
+
* path. Two unit arrays that describe the same logical tree (any order, either separator style)
|
|
5
|
+
* normalize to deeply-equal arrays. Throws on an empty/`.`/`..`-bearing path or a path that
|
|
6
|
+
* appears twice with DIFFERENT content (a real collision a determinism gate must not hide). Does
|
|
7
|
+
* not mutate input.
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizeTree(units: CodeUnit[]): CodeUnit[];
|
|
10
|
+
/**
|
|
11
|
+
* Sha-256 digest of the canonical tree. Same logical tree → same digest; any path or content
|
|
12
|
+
* change → a different digest. The serialization is length-prefixed (byte length of each path
|
|
13
|
+
* and content, plus the unit count) so it is injective — no two distinct trees can collide by a
|
|
14
|
+
* delimiter appearing inside a path or file body.
|
|
15
|
+
*/
|
|
16
|
+
export declare function treeFingerprint(units: CodeUnit[]): string;
|
|
17
|
+
//# sourceMappingURL=normalize-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-tree.d.ts","sourceRoot":"","sources":["../../src/emitter/normalize-tree.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AA4DjD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE,CA0B3D;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CASzD"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Determinism gate for the emitted file tree.
|
|
4
|
+
*
|
|
5
|
+
* The managed-Sync / "regenerate → diff → maintenance PR" flow only works if regenerating a
|
|
6
|
+
* server from the SAME inputs yields byte-identical output — otherwise every regen shows
|
|
7
|
+
* spurious diffs and opens noise PRs. `normalizeTree` collapses the two avoidable sources of
|
|
8
|
+
* cross-run variance — file ORDER and path SPELLING (OS separators, redundant `./`) — into one
|
|
9
|
+
* canonical form, and surfaces a genuine collision (same path, different bytes) as an error
|
|
10
|
+
* rather than silently picking a winner. `treeFingerprint` reduces a canonical tree to a single
|
|
11
|
+
* digest so a caller can answer "did anything actually change?" without a full file-by-file diff.
|
|
12
|
+
*
|
|
13
|
+
* It deliberately does NOT rewrite file CONTENT (line endings, whitespace): the bytes are the
|
|
14
|
+
* artifact the user ships, so normalization must be path/order only. Residual content
|
|
15
|
+
* non-determinism (a baked timestamp, a random id) is a generator bug — the determinism test
|
|
16
|
+
* around the real emitter is what catches it; this gate just makes that test meaningful.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Locale-independent byte-wise string comparison. `localeCompare` is NOT used: its ordering
|
|
20
|
+
* depends on the host locale/ICU data, which would make the canonical order itself
|
|
21
|
+
* non-deterministic across machines — exactly what this module exists to prevent.
|
|
22
|
+
*/
|
|
23
|
+
function byteCompare(a, b) {
|
|
24
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Canonicalize a relative path by SEGMENTS: Windows separators → POSIX `/`, then drop every
|
|
28
|
+
* empty segment (from repeated, leading, or trailing slashes) and every `.` segment. This is
|
|
29
|
+
* provably idempotent — `normalizePath(normalizePath(p)) === normalizePath(p)` — because the
|
|
30
|
+
* result can contain no empty or `.` segment for a second pass to remove. A regex chain is NOT
|
|
31
|
+
* used: `/\/\.\//g` is non-overlapping, so `foo/././bar` → `foo/./bar` (a residual `/./`) and a
|
|
32
|
+
* trailing `/.` survives — both defeat the dedup contract by leaving disk-equivalent paths in
|
|
33
|
+
* distinct canonical forms. `foo/./bar`, `foo//bar`, `foo/bar/`, and `foo/././bar` all resolve
|
|
34
|
+
* to the SAME file on disk, so they must canonicalize identically here — otherwise two units
|
|
35
|
+
* differing only in path spelling slip past the collision check and `writeCodeUnits` silently
|
|
36
|
+
* last-write-wins. `..` segments are NOT resolved (that would need a real path stack); they are
|
|
37
|
+
* preserved so the caller can reject them.
|
|
38
|
+
*/
|
|
39
|
+
function normalizePath(filePath) {
|
|
40
|
+
return filePath
|
|
41
|
+
.replace(/\\/g, '/')
|
|
42
|
+
.split('/')
|
|
43
|
+
.filter((segment) => segment !== '' && segment !== '.')
|
|
44
|
+
.join('/');
|
|
45
|
+
}
|
|
46
|
+
/** True if the path is absolute (POSIX `/` or Windows `\` root). Absolute paths escape the
|
|
47
|
+
* output-dir contract, so the gate rejects them rather than silently stripping the root. */
|
|
48
|
+
function isAbsolutePath(filePath) {
|
|
49
|
+
return /^[/\\]/.test(filePath);
|
|
50
|
+
}
|
|
51
|
+
/** True if any path segment is exactly `..` (an unresolved traversal the gate must reject). */
|
|
52
|
+
function hasDotDotSegment(filePath) {
|
|
53
|
+
return filePath.split('/').some((segment) => segment === '..');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Return the units in canonical form: POSIX-normalized paths, de-duplicated, sorted byte-wise by
|
|
57
|
+
* path. Two unit arrays that describe the same logical tree (any order, either separator style)
|
|
58
|
+
* normalize to deeply-equal arrays. Throws on an empty/`.`/`..`-bearing path or a path that
|
|
59
|
+
* appears twice with DIFFERENT content (a real collision a determinism gate must not hide). Does
|
|
60
|
+
* not mutate input.
|
|
61
|
+
*/
|
|
62
|
+
export function normalizeTree(units) {
|
|
63
|
+
const byPath = new Map();
|
|
64
|
+
for (const unit of units) {
|
|
65
|
+
if (isAbsolutePath(unit.filePath)) {
|
|
66
|
+
throw new Error(`normalizeTree: absolute file path not allowed: ${JSON.stringify(unit.filePath)}`);
|
|
67
|
+
}
|
|
68
|
+
const filePath = normalizePath(unit.filePath);
|
|
69
|
+
if (filePath === '' || hasDotDotSegment(filePath)) {
|
|
70
|
+
throw new Error(`normalizeTree: empty or invalid file path: ${JSON.stringify(unit.filePath)}`);
|
|
71
|
+
}
|
|
72
|
+
const existing = byPath.get(filePath);
|
|
73
|
+
if (existing !== undefined && existing !== unit.content) {
|
|
74
|
+
throw new Error(`normalizeTree: conflicting duplicate path "${filePath}" — same path emitted with ` +
|
|
75
|
+
`different content (non-deterministic or colliding generator output).`);
|
|
76
|
+
}
|
|
77
|
+
byPath.set(filePath, unit.content);
|
|
78
|
+
}
|
|
79
|
+
return [...byPath.entries()]
|
|
80
|
+
.sort(([a], [b]) => byteCompare(a, b))
|
|
81
|
+
.map(([filePath, content]) => ({ filePath, content }));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Sha-256 digest of the canonical tree. Same logical tree → same digest; any path or content
|
|
85
|
+
* change → a different digest. The serialization is length-prefixed (byte length of each path
|
|
86
|
+
* and content, plus the unit count) so it is injective — no two distinct trees can collide by a
|
|
87
|
+
* delimiter appearing inside a path or file body.
|
|
88
|
+
*/
|
|
89
|
+
export function treeFingerprint(units) {
|
|
90
|
+
const canonical = normalizeTree(units);
|
|
91
|
+
const hash = createHash('sha256');
|
|
92
|
+
hash.update(`mcpmake-tree\n${canonical.length}\n`);
|
|
93
|
+
for (const { filePath, content } of canonical) {
|
|
94
|
+
hash.update(`${Buffer.byteLength(filePath, 'utf8')}\n${filePath}\n`);
|
|
95
|
+
hash.update(`${Buffer.byteLength(content, 'utf8')}\n${content}\n`);
|
|
96
|
+
}
|
|
97
|
+
return hash.digest('hex');
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=normalize-tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-tree.js","sourceRoot":"","sources":["../../src/emitter/normalize-tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-scaffolder.d.ts","sourceRoot":"","sources":["../../src/emitter/project-scaffolder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"project-scaffolder.d.ts","sourceRoot":"","sources":["../../src/emitter/project-scaffolder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAMjD;;;GAGG;AACH,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAEhD;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQrD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,eAAe,GAAG,QAAQ,EAAE,CAuD1E;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,eAAe,GAAG,QAAQ,EAAE,CAqG3E"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { renderTemplate } from './template-loader.js';
|
|
2
|
+
import { buildMcpUiModule } from './mcp-ui.js';
|
|
3
|
+
import { buildA2aModule } from './a2a.js';
|
|
4
|
+
import { buildCompositeToolsModule } from './composite-tools.js';
|
|
2
5
|
/**
|
|
3
6
|
* At/above this tool count, registering every tool upfront is a real token-cost
|
|
4
7
|
* problem; the README recommends `--dynamic-discovery` (the #1 buyer concern).
|
|
@@ -83,6 +86,9 @@ export function scaffoldSharedModules(manifest) {
|
|
|
83
86
|
const hasDynamicDiscovery = manifest.dynamicDiscovery ?? false;
|
|
84
87
|
const hasStaticTools = !hasDynamicDiscovery || (manifest.staticToolCount ?? 0) > 0;
|
|
85
88
|
const hasAsyncTools = manifest.tools.some((t) => t.isAsync);
|
|
89
|
+
const hasMcpUi = manifest.mcpUi ?? false;
|
|
90
|
+
const hasA2a = manifest.a2a ?? false;
|
|
91
|
+
const hasCompositeTools = (manifest.compositeTools?.length ?? 0) > 0;
|
|
86
92
|
const templateData = {
|
|
87
93
|
...manifest,
|
|
88
94
|
hasResources: (manifest.resources?.length ?? 0) > 0,
|
|
@@ -91,8 +97,11 @@ export function scaffoldSharedModules(manifest) {
|
|
|
91
97
|
hasDynamicDiscovery,
|
|
92
98
|
hasStaticTools,
|
|
93
99
|
hasAsyncTools,
|
|
100
|
+
hasMcpUi,
|
|
101
|
+
hasA2a,
|
|
102
|
+
hasCompositeTools,
|
|
94
103
|
};
|
|
95
|
-
|
|
104
|
+
const units = [
|
|
96
105
|
{
|
|
97
106
|
filePath: 'src/index.ts',
|
|
98
107
|
content: renderTemplate(manifest.transport === 'http' ? 'server-main-http.ts' : 'server-main.ts', templateData),
|
|
@@ -126,5 +135,42 @@ export function scaffoldSharedModules(manifest) {
|
|
|
126
135
|
content: renderTemplate('types.ts', manifest),
|
|
127
136
|
},
|
|
128
137
|
];
|
|
138
|
+
// MCP Apps output: also ship a ui:// tool-launcher module (registered in src/index.ts
|
|
139
|
+
// via the hasMcpUi template branch).
|
|
140
|
+
if (hasMcpUi) {
|
|
141
|
+
units.push({
|
|
142
|
+
filePath: 'src/mcp-ui.ts',
|
|
143
|
+
content: buildMcpUiModule(manifest.serverName, manifest.tools.map((t) => ({ name: t.name, description: t.description ?? '' }))),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
// Composite tools: also ship a composite-tools module that registers each
|
|
147
|
+
// declared composite (one tool spanning several existing tools), registered in
|
|
148
|
+
// src/index.ts via the hasCompositeTools template branch. buildCompositeToolsModule
|
|
149
|
+
// validates every step/returns/tool reference and throws a clear build error on
|
|
150
|
+
// any invalid reference.
|
|
151
|
+
if (hasCompositeTools) {
|
|
152
|
+
units.push({
|
|
153
|
+
filePath: 'src/composite-tools.ts',
|
|
154
|
+
content: buildCompositeToolsModule(manifest.compositeTools ?? [], manifest.tools),
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
// A2A output: also ship an A2A server-wrapper module (AgentCard + JSON-RPC),
|
|
158
|
+
// registered in src/index.ts via the hasA2a template branch.
|
|
159
|
+
if (hasA2a) {
|
|
160
|
+
units.push({
|
|
161
|
+
filePath: 'src/a2a.ts',
|
|
162
|
+
content: buildA2aModule({
|
|
163
|
+
serverName: manifest.serverName,
|
|
164
|
+
serverVersion: manifest.serverVersion,
|
|
165
|
+
baseUrl: manifest.baseUrl,
|
|
166
|
+
tools: manifest.tools.map((t) => ({
|
|
167
|
+
name: t.name,
|
|
168
|
+
title: t.title,
|
|
169
|
+
description: t.description ?? '',
|
|
170
|
+
})),
|
|
171
|
+
}),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return units;
|
|
129
175
|
}
|
|
130
176
|
//# sourceMappingURL=project-scaffolder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-scaffolder.js","sourceRoot":"","sources":["../../src/emitter/project-scaffolder.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"project-scaffolder.js","sourceRoot":"","sources":["../../src/emitter/project-scaffolder.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"python-template-loader.d.ts","sourceRoot":"","sources":["../../src/emitter/python-template-loader.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"python-template-loader.d.ts","sourceRoot":"","sources":["../../src/emitter/python-template-loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAuCH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,CAUpE"}
|
|
@@ -20,7 +20,12 @@ Handlebars.registerHelper('or', function (a, b) {
|
|
|
20
20
|
Handlebars.registerHelper('pyDocstring', function (str) {
|
|
21
21
|
if (!str)
|
|
22
22
|
return '';
|
|
23
|
-
|
|
23
|
+
// Escape backslashes first, then EVERY double-quote. Escaping only literal
|
|
24
|
+
// `"""` runs left a lone trailing/adjacent quote intact, so a description
|
|
25
|
+
// ending in `"` (e.g. `Search the "Inbox"`) produced four consecutive quotes
|
|
26
|
+
// at the `"""{{pyDocstring}}"""` close — an unterminated-string SyntaxError
|
|
27
|
+
// that broke the whole generated server.py on import.
|
|
28
|
+
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
24
29
|
});
|
|
25
30
|
// Escape a value for embedding in a double-quoted Python string literal.
|
|
26
31
|
Handlebars.registerHelper('pyStr', function (str) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"python-template-loader.js","sourceRoot":"","sources":["../../src/emitter/python-template-loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,mBAAmB,GAAG,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;AAEnE,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAuC,CAAC;AAE3E,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,CAAU,EAAE,CAAU;IAC9D,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC;AAEH,4EAA4E;AAC5E,8DAA8D;AAC9D,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,CAAU,EAAE,CAAU;IAC9D,OAAO,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,UAAU,CAAC,cAAc,CAAC,aAAa,EAAE,UAAU,GAAW;IAC5D,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"python-template-loader.js","sourceRoot":"","sources":["../../src/emitter/python-template-loader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,mBAAmB,GAAG,OAAO,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;AAEnE,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAuC,CAAC;AAE3E,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,CAAU,EAAE,CAAU;IAC9D,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC;AAEH,4EAA4E;AAC5E,8DAA8D;AAC9D,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,CAAU,EAAE,CAAU;IAC9D,OAAO,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC,CAAC,CAAC;AAEH,UAAU,CAAC,cAAc,CAAC,aAAa,EAAE,UAAU,GAAW;IAC5D,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,2EAA2E;IAC3E,0EAA0E;IAC1E,6EAA6E;IAC7E,4EAA4E;IAC5E,sDAAsD;IACtD,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC;AAEH,yEAAyE;AACzE,UAAU,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,GAAY;IACvD,OAAO,cAAc,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,8DAA8D;AAC9D,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,IAAS;IAC1D,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,YAAY,GAAG,OAAO,CAAC,mBAAmB,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;QACjE,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,mBAAmB,GAAG,GAAG,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;QACD,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAChD,mBAAmB,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
4
|
+
{{#if hasStaticTools}}
|
|
4
5
|
import { registerAllTools } from './tools/index.js';
|
|
6
|
+
{{/if}}
|
|
7
|
+
{{#if hasDynamicDiscovery}}
|
|
8
|
+
import { registerDiscoveryTools } from './discovery.js';
|
|
9
|
+
{{/if}}
|
|
5
10
|
{{#if hasResources}}
|
|
6
11
|
import { registerAllResources } from './resources.js';
|
|
7
12
|
{{/if}}
|
|
8
13
|
{{#if hasPrompts}}
|
|
9
14
|
import { registerAllPrompts } from './prompts.js';
|
|
10
15
|
{{/if}}
|
|
16
|
+
{{#if hasMcpUi}}
|
|
17
|
+
import { registerMcpUi } from './mcp-ui.js';
|
|
18
|
+
{{/if}}
|
|
19
|
+
{{#if hasA2a}}
|
|
20
|
+
import { registerA2a } from './a2a.js';
|
|
21
|
+
{{/if}}
|
|
22
|
+
{{#if hasCompositeTools}}
|
|
23
|
+
import { registerCompositeTools } from './composite-tools.js';
|
|
24
|
+
{{/if}}
|
|
11
25
|
import { loadConfig } from './config.js';
|
|
12
26
|
{{#if hasAsyncTools}}
|
|
13
27
|
import { handleTaskRoutes, handleTaskRpc } from './task-handlers.js';
|
|
@@ -151,12 +165,33 @@ function createMcpServer(config: ReturnType<typeof loadConfig>): McpServer {
|
|
|
151
165
|
name: '{{serverName}}',
|
|
152
166
|
version: '{{serverVersion}}',
|
|
153
167
|
});
|
|
168
|
+
{{#if hasStaticTools}}
|
|
154
169
|
registerAllTools(server, config);
|
|
170
|
+
{{/if}}
|
|
171
|
+
{{#if hasDynamicDiscovery}}
|
|
172
|
+
registerDiscoveryTools(server, config);
|
|
173
|
+
{{/if}}
|
|
155
174
|
{{#if hasResources}}
|
|
156
175
|
registerAllResources(server, config);
|
|
157
176
|
{{/if}}
|
|
158
177
|
{{#if hasPrompts}}
|
|
159
178
|
registerAllPrompts(server);
|
|
179
|
+
{{/if}}
|
|
180
|
+
{{#if hasMcpUi}}
|
|
181
|
+
registerMcpUi(server);
|
|
182
|
+
{{/if}}
|
|
183
|
+
{{#if hasCompositeTools}}
|
|
184
|
+
// Composite tools run existing tools in sequence via an in-process loopback MCP
|
|
185
|
+
// client (stood up lazily on the first composite call) populated with the same
|
|
186
|
+
// tool surface, so a step never contends with this server's transport.
|
|
187
|
+
registerCompositeTools(server, (s) => {
|
|
188
|
+
{{#if hasStaticTools}}
|
|
189
|
+
registerAllTools(s, config);
|
|
190
|
+
{{/if}}
|
|
191
|
+
{{#if hasDynamicDiscovery}}
|
|
192
|
+
registerDiscoveryTools(s, config);
|
|
193
|
+
{{/if}}
|
|
194
|
+
});
|
|
160
195
|
{{/if}}
|
|
161
196
|
return server;
|
|
162
197
|
}
|
|
@@ -164,6 +199,19 @@ function createMcpServer(config: ReturnType<typeof loadConfig>): McpServer {
|
|
|
164
199
|
/* ── Bootstrap ───────────────────────────────────────────────────────── */
|
|
165
200
|
|
|
166
201
|
const config = loadConfig();
|
|
202
|
+
{{#if hasA2a}}
|
|
203
|
+
// A2A wrapper: serves the AgentCard + maps A2A message/send → MCP tools/call against a
|
|
204
|
+
// dedicated server populated with the same tools (so it never contends with the MCP HTTP
|
|
205
|
+
// transport). The A2A HTTP listener is opt-in via A2A_HTTP=true.
|
|
206
|
+
await registerA2a(createMcpServer(config), (s) => {
|
|
207
|
+
{{#if hasStaticTools}}
|
|
208
|
+
registerAllTools(s, config);
|
|
209
|
+
{{/if}}
|
|
210
|
+
{{#if hasDynamicDiscovery}}
|
|
211
|
+
registerDiscoveryTools(s, config);
|
|
212
|
+
{{/if}}
|
|
213
|
+
});
|
|
214
|
+
{{/if}}
|
|
167
215
|
const transportMode = process.env.TRANSPORT ?? 'stdio';
|
|
168
216
|
|
|
169
217
|
if (transportMode === 'http') {
|
|
@@ -12,6 +12,15 @@ import { registerAllResources } from './resources.js';
|
|
|
12
12
|
{{#if hasPrompts}}
|
|
13
13
|
import { registerAllPrompts } from './prompts.js';
|
|
14
14
|
{{/if}}
|
|
15
|
+
{{#if hasMcpUi}}
|
|
16
|
+
import { registerMcpUi } from './mcp-ui.js';
|
|
17
|
+
{{/if}}
|
|
18
|
+
{{#if hasA2a}}
|
|
19
|
+
import { registerA2a } from './a2a.js';
|
|
20
|
+
{{/if}}
|
|
21
|
+
{{#if hasCompositeTools}}
|
|
22
|
+
import { registerCompositeTools } from './composite-tools.js';
|
|
23
|
+
{{/if}}
|
|
15
24
|
import { loadConfig } from './config.js';
|
|
16
25
|
|
|
17
26
|
const config = loadConfig();
|
|
@@ -33,6 +42,35 @@ registerAllResources(server, config);
|
|
|
33
42
|
{{#if hasPrompts}}
|
|
34
43
|
registerAllPrompts(server);
|
|
35
44
|
{{/if}}
|
|
45
|
+
{{#if hasMcpUi}}
|
|
46
|
+
registerMcpUi(server);
|
|
47
|
+
{{/if}}
|
|
48
|
+
{{#if hasCompositeTools}}
|
|
49
|
+
// Composite tools run existing tools in sequence via an in-process loopback MCP
|
|
50
|
+
// client populated with the same tool surface (so a step never contends with the
|
|
51
|
+
// stdio transport). The loopback is stood up lazily on the first composite call.
|
|
52
|
+
registerCompositeTools(server, (s) => {
|
|
53
|
+
{{#if hasStaticTools}}
|
|
54
|
+
registerAllTools(s, config);
|
|
55
|
+
{{/if}}
|
|
56
|
+
{{#if hasDynamicDiscovery}}
|
|
57
|
+
registerDiscoveryTools(s, config);
|
|
58
|
+
{{/if}}
|
|
59
|
+
});
|
|
60
|
+
{{/if}}
|
|
61
|
+
{{#if hasA2a}}
|
|
62
|
+
// A2A wrapper: serves the AgentCard + maps A2A message/send → MCP tools/call against a
|
|
63
|
+
// dedicated server populated with the same tool surface (so it never contends with the
|
|
64
|
+
// stdio transport). The HTTP listener is opt-in via A2A_HTTP=true.
|
|
65
|
+
await registerA2a(server, (s) => {
|
|
66
|
+
{{#if hasStaticTools}}
|
|
67
|
+
registerAllTools(s, config);
|
|
68
|
+
{{/if}}
|
|
69
|
+
{{#if hasDynamicDiscovery}}
|
|
70
|
+
registerDiscoveryTools(s, config);
|
|
71
|
+
{{/if}}
|
|
72
|
+
});
|
|
73
|
+
{{/if}}
|
|
36
74
|
|
|
37
75
|
const transport = new StdioServerTransport();
|
|
38
76
|
await server.connect(transport);
|