Skip to content

perf: lazy-load CLI command modules to reduce startup time#621

Open
MrRealORG wants to merge 1 commit into
XiaomiMiMo:mainfrom
MrRealORG:fix/auto-202606142359-lazy-cmd-imports
Open

perf: lazy-load CLI command modules to reduce startup time#621
MrRealORG wants to merge 1 commit into
XiaomiMiMo:mainfrom
MrRealORG:fix/auto-202606142359-lazy-cmd-imports

Conversation

@MrRealORG

Copy link
Copy Markdown

Summary

Closes #520

All 22 CLI command modules (, , , , ,
Usage: mcp [OPTIONS] COMMAND [ARGS]...

MCP development tools

╭─ Options ────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ───────────────────────────────────────────────────────────────────╮
│ version Show the MCP version. │
│ dev Run an MCP server with the MCP Inspector. │
│ run Run an MCP server. │
│ install Install an MCP server in the Claude desktop app. │
╰──────────────────────────────────────────────────────────────────────────────╯, etc.) were eagerly imported at the top of . Each command pulls in heavy transitive dependencies (tool registry with 12+ tools, provider system, app-runtime with ~50 service layers, SDK, MCP client, etc.) — even when the user is only running , , or the default TUI command.

Changes

New:

A helper that creates a lightweight yargs stub containing only:

  • (string) — for routing
  • (string) — for output
  • / (async functions) — resolve the real module via on first use

The full command module is dynamically imported only when yargs matches and executes that specific command. The helper is compatible with yargs 18's synchronous path (all accessed properties return synchronously).

Modified:

  • Replaced 22 static + calls with
  • Made a dynamic inside the middleware callback (only runs once per install, no need to load the 379-line session parser on every startup)

Impact

  • Before: Every invocation (including , ) loaded all 22 command modules and their transitive dependency trees at startup
  • After: Only the matched command's module is loaded; //default TUI no longer pay the cost of unused commands
  • Behavior: Fully backward-compatible — command names, descriptions, builders, and handlers are identical

…o#520)

All 22 CLI command modules (run, serve, web, agent, providers, etc.) were
eagerly imported at the top of src/index.ts. Each command pulls in heavy
transitive dependencies (tool registry, provider system, app-runtime, SDK,
MCP client, etc.) even when the command is not being executed.

This change introduces a  helper that creates a lightweight
command module stub containing only the command name and description. The
full module is dynamically imported only when yargs matches and executes
that specific command. This means running  or
no longer loads the entire tool/provider/agent stack.

Additionally, ClaudeImport is now dynamically imported inside the middleware
callback instead of at the top level, since it only runs once per install.

Addresses: XiaomiMiMo#520
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

启动时间明显比 OpenCode 慢

1 participant