frontmcp 1.4.0 → 1.5.0-rc.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/package.json +11 -13
- package/src/commands/build/adapters/cloudflare.d.ts +10 -1
- package/src/commands/build/adapters/cloudflare.js +57 -62
- package/src/commands/build/adapters/cloudflare.js.map +1 -1
- package/src/commands/build/exec/cli-runtime/generate-cli-entry.js +1 -0
- package/src/commands/build/exec/cli-runtime/generate-cli-entry.js.map +1 -1
- package/src/commands/build/index.js +8 -0
- package/src/commands/build/index.js.map +1 -1
- package/src/commands/scaffold/create.js +18 -5
- package/src/commands/scaffold/create.js.map +1 -1
- package/src/config/frontmcp-config.schema.d.ts +4 -0
- package/src/config/frontmcp-config.schema.js +1 -0
- package/src/config/frontmcp-config.schema.js.map +1 -1
- package/src/config/frontmcp-config.types.d.ts +7 -1
- package/src/config/frontmcp-config.types.js.map +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frontmcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0-rc.1",
|
|
4
4
|
"description": "FrontMCP command line interface",
|
|
5
5
|
"author": "AgentFront <info@agentfront.dev>",
|
|
6
6
|
"homepage": "https://docs.agentfront.dev",
|
|
@@ -23,31 +23,29 @@
|
|
|
23
23
|
},
|
|
24
24
|
"main": "./src/index.js",
|
|
25
25
|
"types": "./src/index.d.ts",
|
|
26
|
-
"bin":
|
|
27
|
-
"frontmcp": "./src/core/cli.js"
|
|
28
|
-
},
|
|
26
|
+
"bin": "./src/core/cli.js",
|
|
29
27
|
"engines": {
|
|
30
28
|
"node": ">=24.0.0"
|
|
31
29
|
},
|
|
32
30
|
"dependencies": {
|
|
33
31
|
"@clack/prompts": "^0.10.0",
|
|
34
|
-
"@frontmcp/lazy-zod": "1.
|
|
35
|
-
"@frontmcp/
|
|
36
|
-
"@frontmcp/
|
|
37
|
-
"commander": "^13.0.0",
|
|
38
|
-
"tslib": "^2.3.0",
|
|
39
|
-
"vectoriadb": "^2.2.0",
|
|
32
|
+
"@frontmcp/lazy-zod": "1.5.0-rc.1",
|
|
33
|
+
"@frontmcp/skills": "1.5.0-rc.1",
|
|
34
|
+
"@frontmcp/utils": "1.5.0-rc.1",
|
|
40
35
|
"@rspack/core": "^1.7.6",
|
|
36
|
+
"commander": "^13.0.0",
|
|
41
37
|
"esbuild": "^0.27.3",
|
|
38
|
+
"tslib": "^2.3.0",
|
|
39
|
+
"vectoriadb": "^2.3.2",
|
|
42
40
|
"yauzl": "^3.2.0",
|
|
43
41
|
"yazl": "^3.3.1"
|
|
44
42
|
},
|
|
45
43
|
"devDependencies": {
|
|
46
|
-
"typescript": "^5.5.3",
|
|
47
|
-
"tsx": "^4.20.6",
|
|
48
44
|
"@types/node": "^24.0.0",
|
|
49
45
|
"@types/yauzl": "^2.10.3",
|
|
50
|
-
"@types/yazl": "^2.4.5"
|
|
46
|
+
"@types/yazl": "^2.4.5",
|
|
47
|
+
"tsx": "^4.20.6",
|
|
48
|
+
"typescript": "^5.5.3"
|
|
51
49
|
},
|
|
52
50
|
"type": "commonjs"
|
|
53
51
|
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import type { AdapterTemplate } from '../types';
|
|
2
2
|
/**
|
|
3
3
|
* Cloudflare Workers adapter - edge deployment on Cloudflare.
|
|
4
|
-
* Compiles to
|
|
4
|
+
* Compiles to an ES Module Worker that routes the native Web `Request` into the
|
|
5
|
+
* SDK's web-fetch handler (`getServerlessHandlerAsync` in worker mode) — no
|
|
6
|
+
* Express, no Node `req`/`res` shim.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: this decorator-build path does NOT emit KV / Durable Object / R2 / D1
|
|
9
|
+
* bindings or `[triggers] crontabs` into `wrangler.toml`, and the entry passes
|
|
10
|
+
* only the `Request` to the handler (not `env`/`ctx`). Workers needing bindings
|
|
11
|
+
* or the managed auto-update Cron (`scheduled`) should use `@frontmcp/edge`
|
|
12
|
+
* `createEdgeMcp` with a hand-written `wrangler.toml`. See
|
|
13
|
+
* docs/frontmcp/deployment/cloudflare-worker.mdx.
|
|
5
14
|
*
|
|
6
15
|
* @see https://developers.cloudflare.com/workers/
|
|
7
16
|
*/
|
|
@@ -3,73 +3,56 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.cloudflareAdapter = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Cloudflare Workers adapter - edge deployment on Cloudflare.
|
|
6
|
-
* Compiles to
|
|
6
|
+
* Compiles to an ES Module Worker that routes the native Web `Request` into the
|
|
7
|
+
* SDK's web-fetch handler (`getServerlessHandlerAsync` in worker mode) — no
|
|
8
|
+
* Express, no Node `req`/`res` shim.
|
|
9
|
+
*
|
|
10
|
+
* NOTE: this decorator-build path does NOT emit KV / Durable Object / R2 / D1
|
|
11
|
+
* bindings or `[triggers] crontabs` into `wrangler.toml`, and the entry passes
|
|
12
|
+
* only the `Request` to the handler (not `env`/`ctx`). Workers needing bindings
|
|
13
|
+
* or the managed auto-update Cron (`scheduled`) should use `@frontmcp/edge`
|
|
14
|
+
* `createEdgeMcp` with a hand-written `wrangler.toml`. See
|
|
15
|
+
* docs/frontmcp/deployment/cloudflare-worker.mdx.
|
|
7
16
|
*
|
|
8
17
|
* @see https://developers.cloudflare.com/workers/
|
|
9
18
|
*/
|
|
10
19
|
exports.cloudflareAdapter = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
//
|
|
20
|
+
// ES Module format — modern Cloudflare Workers (and `nodejs_compat`) require
|
|
21
|
+
// the Module Worker shape (`export default { fetch }`). The legacy CommonJS
|
|
22
|
+
// `module.exports` is interpreted as a Service Worker, where `nodejs_compat`
|
|
23
|
+
// cannot externalize Node builtins and the build fails.
|
|
24
|
+
moduleFormat: 'esnext',
|
|
25
|
+
// Emitted as `serverless-setup.js` and imported FIRST by the entry, so the
|
|
26
|
+
// env flags are set before the user module's `@FrontMcp` decorator evaluates
|
|
27
|
+
// (ESM import evaluation is ordered, and the decorator reads these at import
|
|
28
|
+
// time). FRONTMCP_WORKER selects FrontMCP's Web-standard fetch handler.
|
|
29
|
+
getSetupTemplate: () => `// Auto-generated — sets env before the @FrontMcp decorator runs.
|
|
14
30
|
process.env.FRONTMCP_SERVERLESS = '1';
|
|
15
31
|
process.env.FRONTMCP_DEPLOYMENT_MODE = 'serverless';
|
|
32
|
+
process.env.FRONTMCP_WORKER = '1';
|
|
33
|
+
`,
|
|
34
|
+
getEntryTemplate: (mainModulePath) => `// Auto-generated Cloudflare Workers entry point (ES Module / Module Worker).
|
|
35
|
+
// Generated by: frontmcp build --target cloudflare
|
|
36
|
+
//
|
|
37
|
+
// The Worker receives the native Web Request and the SDK routes it straight
|
|
38
|
+
// into the MCP WebStandard transport (Request/Response). No Express, no Node
|
|
39
|
+
// req/res shim.
|
|
40
|
+
import './serverless-setup.js';
|
|
41
|
+
import '${mainModulePath}';
|
|
42
|
+
import { getServerlessHandlerAsync } from '@frontmcp/sdk';
|
|
16
43
|
|
|
17
|
-
|
|
18
|
-
const { getServerlessHandlerAsync } = require('@frontmcp/sdk');
|
|
19
|
-
|
|
20
|
-
let app = null;
|
|
21
|
-
|
|
22
|
-
async function handleRequest(request) {
|
|
23
|
-
if (!app) {
|
|
24
|
-
app = await getServerlessHandlerAsync();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Convert Cloudflare Request to Node.js format
|
|
28
|
-
const url = new URL(request.url);
|
|
29
|
-
const req = {
|
|
30
|
-
method: request.method,
|
|
31
|
-
url: url.pathname + url.search,
|
|
32
|
-
headers: Object.fromEntries(request.headers),
|
|
33
|
-
body: request.body,
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
return new Promise((resolve) => {
|
|
37
|
-
const res = {
|
|
38
|
-
statusCode: 200,
|
|
39
|
-
headers: {},
|
|
40
|
-
body: '',
|
|
41
|
-
status(code) { this.statusCode = code; return this; },
|
|
42
|
-
setHeader(key, value) { this.headers[key] = value; },
|
|
43
|
-
json(data) {
|
|
44
|
-
this.headers['Content-Type'] = 'application/json';
|
|
45
|
-
this.body = JSON.stringify(data);
|
|
46
|
-
resolve(new Response(this.body, {
|
|
47
|
-
status: this.statusCode,
|
|
48
|
-
headers: this.headers,
|
|
49
|
-
}));
|
|
50
|
-
},
|
|
51
|
-
send(data) {
|
|
52
|
-
this.body = data;
|
|
53
|
-
resolve(new Response(this.body, {
|
|
54
|
-
status: this.statusCode,
|
|
55
|
-
headers: this.headers,
|
|
56
|
-
}));
|
|
57
|
-
},
|
|
58
|
-
end() {
|
|
59
|
-
resolve(new Response(this.body, {
|
|
60
|
-
status: this.statusCode,
|
|
61
|
-
headers: this.headers,
|
|
62
|
-
}));
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
app(req, res);
|
|
66
|
-
});
|
|
67
|
-
}
|
|
44
|
+
let handlerPromise = null;
|
|
68
45
|
|
|
69
|
-
|
|
46
|
+
export default {
|
|
70
47
|
async fetch(request, env, ctx) {
|
|
71
|
-
|
|
72
|
-
|
|
48
|
+
if (!handlerPromise) {
|
|
49
|
+
handlerPromise = getServerlessHandlerAsync();
|
|
50
|
+
}
|
|
51
|
+
// In worker mode the stored handler is a Web fetch handler:
|
|
52
|
+
// (Request) => Promise<Response>.
|
|
53
|
+
const handler = await handlerPromise;
|
|
54
|
+
return handler(request);
|
|
55
|
+
},
|
|
73
56
|
};
|
|
74
57
|
`,
|
|
75
58
|
// #375 — fail the build when the user's @FrontMcp config references
|
|
@@ -116,16 +99,28 @@ module.exports = {
|
|
|
116
99
|
// wrangler deploy silently failed.
|
|
117
100
|
alwaysWriteConfig: true,
|
|
118
101
|
// #374 round-2 — merge `frontmcp.config.deployments[].wrangler.{name,
|
|
119
|
-
// compatibilityDate}` into the rendered TOML so values
|
|
120
|
-
// user's config actually reach `wrangler deploy`. Defaults
|
|
121
|
-
// the field is absent or no deployment was matched.
|
|
102
|
+
// compatibilityDate, compatibilityFlags}` into the rendered TOML so values
|
|
103
|
+
// declared in the user's config actually reach `wrangler deploy`. Defaults
|
|
104
|
+
// preserved when the field is absent or no deployment was matched.
|
|
122
105
|
getConfig: (_cwd, deployment) => {
|
|
123
106
|
const wrangler = deployment?.wrangler ?? {};
|
|
124
107
|
const name = wrangler.name ?? 'frontmcp-worker';
|
|
125
|
-
|
|
108
|
+
// The cloudflare entry (getEntryTemplate) is an ES Module that imports the
|
|
109
|
+
// SDK's web-fetch handler, which still transitively pulls in Node builtins
|
|
110
|
+
// (node:*, Buffer, process, streams) through the SDK runtime. On Workers
|
|
111
|
+
// those exist ONLY behind the `nodejs_compat` flag — without it the Worker
|
|
112
|
+
// fails to even load. The flag is therefore non-negotiable for this target;
|
|
113
|
+
// we always emit it and merge in any extra flags the user declared (deduped,
|
|
114
|
+
// `nodejs_compat` guaranteed first).
|
|
115
|
+
const flags = Array.from(new Set(['nodejs_compat', ...(wrangler.compatibilityFlags ?? [])]));
|
|
116
|
+
// `nodejs_compat` only provides the full Node API surface (incl. `require`
|
|
117
|
+
// of builtins) when compatibility_date >= 2024-09-23; default to that so a
|
|
118
|
+
// freshly-built worker boots. Users can still pin an older/newer date.
|
|
119
|
+
const compatibilityDate = wrangler.compatibilityDate ?? '2024-09-23';
|
|
126
120
|
return `name = "${name}"
|
|
127
121
|
main = "dist/cloudflare/index.js"
|
|
128
122
|
compatibility_date = "${compatibilityDate}"
|
|
123
|
+
compatibility_flags = [${flags.map((f) => `"${f}"`).join(', ')}]
|
|
129
124
|
`;
|
|
130
125
|
},
|
|
131
126
|
configFileName: 'wrangler.toml',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../../../../src/commands/build/adapters/cloudflare.ts"],"names":[],"mappings":";;;AAGA
|
|
1
|
+
{"version":3,"file":"cloudflare.js","sourceRoot":"","sources":["../../../../../src/commands/build/adapters/cloudflare.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CloudflareDeployment } from '../../../config/frontmcp-config.types';\nimport type { AdapterTemplate } from '../types';\n\n/**\n * Cloudflare Workers adapter - edge deployment on Cloudflare.\n * Compiles to an ES Module Worker that routes the native Web `Request` into the\n * SDK's web-fetch handler (`getServerlessHandlerAsync` in worker mode) — no\n * Express, no Node `req`/`res` shim.\n *\n * NOTE: this decorator-build path does NOT emit KV / Durable Object / R2 / D1\n * bindings or `[triggers] crontabs` into `wrangler.toml`, and the entry passes\n * only the `Request` to the handler (not `env`/`ctx`). Workers needing bindings\n * or the managed auto-update Cron (`scheduled`) should use `@frontmcp/edge`\n * `createEdgeMcp` with a hand-written `wrangler.toml`. See\n * docs/frontmcp/deployment/cloudflare-worker.mdx.\n *\n * @see https://developers.cloudflare.com/workers/\n */\nexport const cloudflareAdapter: AdapterTemplate = {\n // ES Module format — modern Cloudflare Workers (and `nodejs_compat`) require\n // the Module Worker shape (`export default { fetch }`). The legacy CommonJS\n // `module.exports` is interpreted as a Service Worker, where `nodejs_compat`\n // cannot externalize Node builtins and the build fails.\n moduleFormat: 'esnext',\n\n // Emitted as `serverless-setup.js` and imported FIRST by the entry, so the\n // env flags are set before the user module's `@FrontMcp` decorator evaluates\n // (ESM import evaluation is ordered, and the decorator reads these at import\n // time). FRONTMCP_WORKER selects FrontMCP's Web-standard fetch handler.\n getSetupTemplate: () => `// Auto-generated — sets env before the @FrontMcp decorator runs.\nprocess.env.FRONTMCP_SERVERLESS = '1';\nprocess.env.FRONTMCP_DEPLOYMENT_MODE = 'serverless';\nprocess.env.FRONTMCP_WORKER = '1';\n`,\n\n getEntryTemplate: (mainModulePath: string) => `// Auto-generated Cloudflare Workers entry point (ES Module / Module Worker).\n// Generated by: frontmcp build --target cloudflare\n//\n// The Worker receives the native Web Request and the SDK routes it straight\n// into the MCP WebStandard transport (Request/Response). No Express, no Node\n// req/res shim.\nimport './serverless-setup.js';\nimport '${mainModulePath}';\nimport { getServerlessHandlerAsync } from '@frontmcp/sdk';\n\nlet handlerPromise = null;\n\nexport default {\n async fetch(request, env, ctx) {\n if (!handlerPromise) {\n handlerPromise = getServerlessHandlerAsync();\n }\n // In worker mode the stored handler is a Web fetch handler:\n // (Request) => Promise<Response>.\n const handler = await handlerPromise;\n return handler(request);\n },\n};\n`,\n\n // #375 — fail the build when the user's @FrontMcp config references\n // Node-only storage providers that can't run on Workers.\n //\n // Round 1 only inspected the runtime-evaluated config object. The reporter's\n // failure case was `sqlite: process.env.REDIS_HOST ? {…} : { sqlite: {…} }` —\n // a ternary that may evaluate to `undefined` at decorator-load time (so the\n // runtime check sees nothing) but still ships the Node-only branch in the\n // bundled worker. Round 2 also inspects `info.keysSeenInSource`, which is\n // collected by walking the @FrontMcp({...}) source expression — that captures\n // the property name regardless of whether its value is a literal, a ternary,\n // or a function call. If `sqlite`/`redis` appear at all, fail loud and tell\n // the user how to gate them at the source level.\n validate: (decoratorConfig, info) => {\n const errors: string[] = [];\n\n const sqliteIsLiteral =\n decoratorConfig?.['sqlite'] !== undefined &&\n typeof decoratorConfig['sqlite'] === 'object' &&\n decoratorConfig['sqlite'] !== null;\n const redisIsLiteral =\n decoratorConfig?.['redis'] !== undefined &&\n typeof decoratorConfig['redis'] === 'object' &&\n decoratorConfig['redis'] !== null;\n const sqliteSeen = sqliteIsLiteral || !!info?.keysSeenInSource?.includes('sqlite');\n const redisSeen = redisIsLiteral || !!info?.keysSeenInSource?.includes('redis');\n\n if (sqliteSeen) {\n errors.push(\n 'sqlite storage is not supported on --target cloudflare (no fs / native modules on Workers). ' +\n 'Even an env-gated `sqlite: process.env.X ? {...} : undefined` still ships the Node-only ' +\n 'branch in the worker bundle. Use Cloudflare KV / Durable Objects, or move the sqlite ' +\n 'config behind a build-time `define` so the bundler can dead-code-eliminate it.',\n );\n }\n if (redisSeen) {\n errors.push(\n 'ioredis-style `redis` storage is not supported on --target cloudflare (no Node net). ' +\n 'Even an env-gated `redis: process.env.X ? {...} : undefined` still ships the Node-only ' +\n 'branch in the worker bundle. Use Vercel KV / Upstash Redis (HTTP), or move the redis ' +\n 'config behind a build-time `define` so the bundler can dead-code-eliminate it.',\n );\n }\n if (errors.length) {\n throw new Error(\n `[--target cloudflare] config incompatible with Cloudflare Workers:\\n - ${errors.join('\\n - ')}`,\n );\n }\n },\n\n // #374 — always write wrangler.toml from the build output. Skipping when\n // the file already exists left users with a wrangler.toml that pointed at\n // dist/index.js while the build emitted dist/cloudflare/index.js, and\n // wrangler deploy silently failed.\n alwaysWriteConfig: true,\n\n // #374 round-2 — merge `frontmcp.config.deployments[].wrangler.{name,\n // compatibilityDate, compatibilityFlags}` into the rendered TOML so values\n // declared in the user's config actually reach `wrangler deploy`. Defaults\n // preserved when the field is absent or no deployment was matched.\n getConfig: (_cwd, deployment) => {\n const wrangler = (deployment as CloudflareDeployment | undefined)?.wrangler ?? {};\n const name = wrangler.name ?? 'frontmcp-worker';\n // The cloudflare entry (getEntryTemplate) is an ES Module that imports the\n // SDK's web-fetch handler, which still transitively pulls in Node builtins\n // (node:*, Buffer, process, streams) through the SDK runtime. On Workers\n // those exist ONLY behind the `nodejs_compat` flag — without it the Worker\n // fails to even load. The flag is therefore non-negotiable for this target;\n // we always emit it and merge in any extra flags the user declared (deduped,\n // `nodejs_compat` guaranteed first).\n const flags = Array.from(new Set(['nodejs_compat', ...(wrangler.compatibilityFlags ?? [])]));\n // `nodejs_compat` only provides the full Node API surface (incl. `require`\n // of builtins) when compatibility_date >= 2024-09-23; default to that so a\n // freshly-built worker boots. Users can still pin an older/newer date.\n const compatibilityDate = wrangler.compatibilityDate ?? '2024-09-23';\n return `name = \"${name}\"\nmain = \"dist/cloudflare/index.js\"\ncompatibility_date = \"${compatibilityDate}\"\ncompatibility_flags = [${flags.map((f) => `\"${f}\"`).join(', ')}]\n`;\n },\n\n configFileName: 'wrangler.toml',\n};\n"]}
|
|
@@ -586,6 +586,7 @@ var _getCmd = promptCmd
|
|
|
586
586
|
.description('Render a prompt by name')
|
|
587
587
|
${promptGetOptionLines}
|
|
588
588
|
.allowUnknownOption(true)
|
|
589
|
+
.allowExcessArguments(true) // #382 — without this, an out-of-spec flag like \`--bogus x\` becomes excess operands and Commander throws "too many arguments" before the action can emit the precise "unknown option(s) for prompt" error.
|
|
589
590
|
.action(async function(name) {
|
|
590
591
|
try {
|
|
591
592
|
var spec = promptArgs[name];
|