Repository navigation
fix(cli): the generated CLI says unknown command, prints an MCP error prefix once, and offers load_skill only the run lines it has - #1140
Merged
alexmercerpo merged 6 commits intoNov 5, 2026
Conversation
…ed, and load_skill offers only commands the CLI has A generated CLI printed a failed resource read as "MCP error -32002: MCP error -32002: Resource not found: ...": the server's McpError message already carries the prefix, and the client adds it again. _exitWithError and the Skilled OpenAPI commands now drop the leading prefixes, so the error reads as a tool's error does. An unknown command said "too many arguments": the root program's help action took the word as its own argument. Without that action, commander answers "unknown command '<name>'" with its suggestion, and exits 2. A bare invocation still prints the help, parsed as --help. The command:* listener, which never ran, is removed. With execute_action in cli.excludeTools, load_skill still printed an execute line for each action. It now prints a one-call run_workflow script instead, or no line when run_workflow is left out too.
…ing' into fix/cli-skilled-messages
…into fix/cli-skilled-messages
Contributor
|
Warning Review limit reachedYour organization has reached its usage spending cap. Adjust your spending cap in the billing tab. Next included review available in 28 minutes. View limit details
|
Contributor
Performance Test ResultsStatus: ✅ All tests passed Summary
Total: 101 tests across 21 projects 📊 View full report in workflow run Generated at: 2026-11-05T17:44:59.444Z |
…into fix/cli-skilled-messages
…into fix/cli-skilled-messages
…into fix/cli-skilled-messages
alexmercerpo
approved these changes
Nov 5, 2026
Contributor
frontegg-david
added a commit
that referenced
this pull request
Nov 5, 2026
* Cherry-pick: fix(adapters,plugins,edge): an older saas bundle, pulled or pushed, doesn't roll the server back Cherry-picked from #1119 (merged to release/1.11.x) Original commit: d88f422 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(sdk,plugins): an @app's Skilled OpenAPI credential resolver reaches execute_action and this.callTool() of an operation Cherry-picked from #1120 (merged to release/1.11.x) Original commit: 00a3b00 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(adapters,plugins,edge): a push token replayed to another replica or Worker isolate is refused Cherry-picked from #1122 (merged to release/1.11.x) Original commit: 1341026 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(plugins): a skill a skills:filter hook hides can't be run by naming its actions Cherry-picked from #1123 (merged to release/1.11.x) Original commit: a081fbf Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(sdk): a plugin listed twice in one plugins list is refused at startup instead of keeping only its last entry Cherry-picked from #1127 (merged to release/1.11.x) Original commit: 3dbadd3 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(plugins,edge): a Cron run that doesn't apply its bundle fails, and /readyz says the bundle served is stale Cherry-picked from #1128 (merged to release/1.11.x) Original commit: 4938d21 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(sdk): connect() with an authToken connects an anonymous caller again on a server without auth Cherry-picked from #1129 (merged to release/1.11.x) Original commit: 3d238da Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(auth,adapters,plugins,edge): operators can tell why a pull or push token was refused, while callers still get the generic answer Cherry-picked from #1130 (merged to release/1.11.x) Original commit: 913f4f5 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(sdk,auth,plugins): this.authProviders works: the SDK wires the AuthProviders vault from a new authProvidersVault option Cherry-picked from #1131 (merged to release/1.11.x) Original commit: e14c30c Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(sdk,auth): /oauth/connect connects a verified caller who has no vault yet, and asks an anonymous one to sign in Cherry-picked from #1132 (merged to release/1.11.x) Original commit: f46a87a Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(sdk,plugins): the SDK skill surfaces say a plugin's skills haven't loaded yet, retryable, and carry bundleVersion Cherry-picked from #1133 (merged to release/1.11.x) Original commit: 0d1dc94 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(sdk,auth,cli,plugins): the credentials-required error keeps its connect link out of the message, and asks through URL elicitation where the client supports it Cherry-picked from #1134 (merged to release/1.11.x) Original commit: 6d8ea24 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(sdk): a health check registered after startup runs in /readyz, and registerHealthProbe returns a remover Cherry-picked from #1135 (merged to release/1.11.x) Original commit: 7f2f48f Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(sdk,plugins): a bundle swap sends one list_changed per list it changed, not one per entry Cherry-picked from #1136 (merged to release/1.11.x) Original commit: 0296291 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(adapters,plugins,edge): a restarted server serves its cached bundle in place of an older or refused pull, and doesn't write it back Cherry-picked from #1137 (merged to release/1.11.x) Original commit: 358d114 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(sdk,adapters,plugins,edge): a push token with a body_sha256 claim can't carry another bundle Cherry-picked from #1138 (merged to release/1.11.x) Original commit: b870325 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(plugins,edge): managed mode takes confirm, and the audit log says whether the user confirmed a call Cherry-picked from #1139 (merged to release/1.11.x) Original commit: 588289f Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(cli): the generated CLI says unknown command, prints an MCP error prefix once, and offers load_skill only the run lines it has Cherry-picked from #1140 (merged to release/1.11.x) Original commit: 4cfe9a2 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(plugins): load_skill's outputSchema describes a loaded skill once Cherry-picked from #1141 (merged to release/1.11.x) Original commit: 470010e Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> * Cherry-pick: fix(sdk,cli): skills/load's default answer sends formattedContent again, as 1.11.0 did; format: 'markdown' is the opt-in for the smaller one Cherry-picked from #1142 (merged to release/1.11.x) Original commit: a680fe7 Co-Authored-By: frontegg-david <69419539+frontegg-david@users.noreply.github.com> --------- Co-authored-by: agentfront[bot] <agentfront[bot]@users.noreply.github.com> Co-authored-by: frontegg-david <69419539+frontegg-david@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacks on #1139.
What and why
Three messages of a generated CLI (
frontmcp build --target cli) were wrong.A failed read printed the MCP error prefix twice.
<bin> resource read app://missingprintedError: MCP error -32002: MCP error -32002: Resource not found: app://missing. Before protocol 2026-07-28, the server sends itsMcpError's message as it is, and that message already starts withMCP error <code>:. The client then adds the prefix again. A tool's error has no prefix (Error: Cannot divide by zero), so a read's error now reads the same way:_exitWithError, the error path every generated command shares, removes the leadingMCP error <code>:prefixes before it prints. It covers resources, templates, prompts and a tool call that throws.skills read <missing>.MCP_ERROR_PREFIXbeside the error snippet. The build copies the snippet's compiled module into the CLI bundle, next toskilled-commands, which imports it.An unknown command said
too many arguments. The root program had an action that printed the help. With a root action, commander takes an unknown first word as an argument of the root, and commander 13 refuses the extra argument. The footer'scommand:*listener (Unknown command: X, exit 1) never ran: commander only calls it when the root has no action. Both are removed, so:error: unknown command '<name>', with its(Did you mean <command>?)suggestion when a command is close, and exits 2 (commander.unknownCommandin the existingexitOverride);--help;search_skill [query...],skills load <skills...>) are matched by name before this point, so they work as before.allowExcessArgumentsis untouched.load_skillprintedexecutelines when the CLI had noexecutecommand. Withcli.excludeTools: ['execute_action'], the CLI has noexecutecommand, butload_skillstill printed<bin> execute <actionId> --input '<json>'for each action. The plugin has no option of its own to leave out one of its tools. A server that doesn't list all four of them gets no Skilled OpenAPI commands at all, socli.excludeToolsis the case that reaches this code. The line now follows the commands the CLI has:execute, when the CLI has it, as before;run_workflow:<bin> run_workflow 'return await callTool("getInvoice", {"id":"<id>"});'.installalready wrote this form in a bundle skill'sSKILL.md. It is now one function,workflowCommandLine, which both use;The plugin's
load_skillis unchanged. It returns the actions as data, and the CLI formats them.Scenarios covered: a missing resource (in-process), a missing skill through
skills read, an unknown command, a mistyped command (with its suggestion), a top-level skill command on a server with tools of its own, a bare invocation (help on standard output), andload_skillwithoutexecute_action(withrun_workflow, and without either).User-facing change
MCP error <code>:prefix.unknown command '<name>', with commander's suggestion, and exits 2.execute_action(cli.excludeTools),load_skillprints each action as a one-callrun_workflowscript, or prints no command line whenrun_workflowis left out too.<bin> resource read app://missing:Error: MCP error -32002: MCP error -32002: Resource not found: app://missing→Error: Resource not found: app://missing(exit 1 both).<bin> skills read refunds(Skilled OpenAPI):Error: MCP error -32002: MCP error -32002: Resource not found: skill://refunds/SKILL.md→Error: Resource not found: skill://refunds/SKILL.md.<bin> nonexistent-command:error: too many arguments. Expected 0 arguments but got 1.→error: unknown command 'nonexistent-command'(exit 2 both).<bin> greeet:error: too many arguments. ...→error: unknown command 'greeet'and(Did you mean greet?).<bin> load_skill invoiceswithexecute_actionexcluded:<bin> execute getInvoice --input '{"id":"<id>"}'→<bin> run_workflow 'return await callTool("getInvoice", {"id":"<id>"});'. Withrun_workflowexcluded too: no command line.<bin> --output jsonwith no command (options only): the help went to standard output → it goes to standard error (exit 0 both). A bare<bin>still prints it on standard output.cli.excludeTools).frontmcp-deployment/references/build-for-cli.md: a new "Usage errors and failed calls" section,load_skillwithoutexecute_action, and a troubleshooting row forerror: unknown command.The CLI's README is updated too.
Tests
Added:
extract-public-message-parity.spec.ts(2 new tests):_exitWithErrorprints a doubled-prefix error asError: Resource not found: app://missing, drops a single prefix (the daemon's), and leaves a message without a prefix as it is.skilled-commands.spec.ts(2 new tests, 1 changed):run_workflowbut notexecute_action,load_skillprints each action as a one-call workflow, and noexecuteline;skills load's help says so;skills readprints it without the prefix.generated-cli-smoke.spec.ts(2 new tests): the generated CLI runs in the test process with stubbed runtime modules. An unknown command printserror: unknown command 'gret'and(Did you mean greet?)and exits 2. No command prints the help on standard output and exits 0. The first test fails with the old root action.generate-cli-entry.spec.tsandgenerated-cli-smoke.spec.ts: the source checks for the old root action andparseAsync(process.argv)now check the new footer.demo-e2e-cli-exec:cli-errors.e2e.spec.ts: an unknown command sayserror: unknown command 'nonexistent-command'exactly (it acceptedtoo many argumentsbefore), and a mistypedgreeetsuggestsgreet;cli-resources.e2e.spec.ts:resource read app://missingexits 1 withError: Resource not found: app://missingon stderr;cli-skilled-openapi.e2e.spec.ts:skills read refundsprints the error withoutMCP error; on a server with tools of its own,search_skillsaysunknown command 'search_skill'; a new project whose CLI excludesexecute_actionprintsrun_workflowlines fromload_skill, noexecuteline, and has noexecutecommand.Run (after merging #1139, which has #1138's latest):
yarn install --immutable, thennpx nx run-many -t build -p sdk,adapters,cli,plugin-skilled-openapi,testing,plugin-cache,plugin-remember: passed.npx nx test cli: 133 suites, 2235 tests, passed.npx nx test plugin-skilled-openapi: 53 suites, 844 tests, passed.npx nx test skills: 3 suites, 249 tests, passed.npx nx test demo-e2e-cli-exec: 44 suites, 270 tests. 262 passed and 6 skipped. 2 failed because they need Docker, which this machine doesn't have:cli-build-tasks-redisandcli-build-decorated-storesstart Redis with testcontainers. The three touched specs (cli-skilled-openapi,cli-errors,cli-resources) passed.npx nx run cli:typecheck,npx tsc --noEmit -p libs/cli/tsconfig.lib.jsonandnpx nx run demo-e2e-cli-exec:typecheck-e2e: no errors.