Skip to content

MCP, plugins, and hooks

This page maps the MCP, plugin, and hook surfaces in the extracted cli.js.

Use Hooks and events reference for the canonical hook/frame/method list and Tool inventory and schemas for MCP/plugin tool schema ownership. This page owns MCP/plugin runtime wiring.

Source anchors

Semantic aliasSourceApproximate locationString or symbolMeaning
McpCommandRegistrarcli.jsline ~9173, byte 0xbf3c40function rR4(H)Registers the mcp command family.
McpServeCommandcli.jsline ~9173, byte 0xbf3ccbcommand("serve")Starts the Claude Code MCP server.
McpListCommandcli.jsline ~9173, byte 0xbf3fbacommand("list")Lists configured MCP servers.
McpDesktopImportCommandcli.jsline ~9173, byte 0xbf44e2command("add-from-claude-desktop")Imports MCP servers from Claude Desktop.
McpProjectChoiceResetcli.jsline ~9173, byte 0xbf461ereset-project-choicesResets approved/rejected project-scoped MCP choices.
McpNonblockingGatecli.jsline ~19294, byte 0xd91824MCP_CONNECTION_NONBLOCKINGRuntime MCP connection non-blocking gate.
McpToolTimeoutcli.jsline ~4980, byte 0x937240MCP_TIMEOUTMCP tool timeout environment variable.
McpConfigFlagcli.jsline ~19525, byte 0xdc0b90--mcp-config <configs...>Loads MCP config from JSON files or strings.
StrictMcpConfigFlagcli.jsline ~19525, byte 0xdc1e70--strict-mcp-configIgnores non-flag MCP configurations.
PluginCommandRegistrarcli.jsline ~9297, byte 0xbfca96function fC4(H)Registers plugin / plugins command family.
PluginTuiManagercli.jsline ~7184, byte 0xb06c21description:"Manage Claude Code plugins"In-session slash/TUI plugin management surface.
PluginMarketplaceCommandcli.jsline ~9297, byte 0xbfd24dManage Claude Code marketplacesCLI marketplace subcommand root.
PluginMarketplaceAddCommandcli.jsline ~9297, byte 0xbfd2abAdd a marketplace from a URL, path, or GitHub repoMarketplace add command and source ingestion surface.
EnabledPluginsSettingcli.jsline ~185, byte 0x11b66denabledPluginsSettings key storing enabled plugin IDs and version constraints.
ExtraMarketplacesSettingcli.jsline ~185, byte 0x11b871extraKnownMarketplacesSettings key registering repository/team marketplaces.
StrictMarketplacePolicycli.jsline ~185, byte 0x113422strictKnownMarketplacesManaged allowlist for marketplace sources.
BlockedMarketplacePolicycli.jsline ~185, byte 0x113479blockedMarketplacesManaged blocklist for marketplace sources.
DependencyMarketplacePolicyBlockcli.jsline ~1291, byte 0x4dad4ddependency-marketplace-blocked-by-policyPlugin dependency install can be blocked by marketplace policy.
PluginInstallTelemetrycli.jsline ~1291, byte 0x4dbe08plugin_installedPlugin install telemetry after dependency resolution and settings write.
PluginUninstallTelemetrycli.jsline ~9173, byte 0xbf4ad9tengu_plugin_uninstalled_cliCLI uninstall telemetry and orphan-scan follow-up.
PluginDisableTelemetrycli.jsline ~9180, byte 0xbf52cetengu_plugin_disabled_cliCLI disable telemetry.
PluginUpdateTelemetrycli.jsline ~9182, byte 0xbf54detengu_plugin_updated_cliCLI update telemetry after version check.
HookEventSchemacli.jsline ~185, byte 0x10b6b4PreToolUse, PostToolUse, SessionStart, SessionEndHook event schema.

MCP runtime map

flowchart TD
Flags[--mcp-config / --strict-mcp-config] --> Config[MCP config set]
Settings[settings / project / managed policy] --> Config
Plugins[plugin-provided MCP] --> Config
Config --> Coordinator[MCP runtime coordinator]
Coordinator --> Always[alwaysLoad servers]
Coordinator --> Deferred[non-alwaysLoad servers]
Coordinator --> ClaudeAi[claude.ai connectors]
Coordinator --> Tools[MCP tools/resources/prompts]

McpRuntimeCoordinator splits regular configs into always-load and non-always-load groups, honors MCP_CONNECTION_NONBLOCKING, connects regular and claude.ai connector configs, and deduplicates overlapping plugin/connector surfaces.

MCP command surface

SubcommandRuntime role
serveStarts Claude Code’s MCP server.
listLists configured MCP servers; help text warns that stdio servers can be spawned for health checks.
add, remove, get, add-jsonPresent in the command family by surrounding command registration, though individual anchors are less stable than McpCommandRegistrar.
add-from-claude-desktopImports MCP servers from Claude Desktop on supported platforms.
reset-project-choicesClears project-scoped approve/reject choices for .mcp.json servers.

Plugin surfaces

PluginCommandRegistrar registers plugin / plugins. High-signal plugin strings show:

  • session-only plugins through --plugin-dir and --plugin-url;
  • marketplace concepts and reserved marketplace names;
  • plugin-provided agents, skills, hooks, mcpServers, and outputStyles schema surfaces;
  • plugin autoupdate guarded by updater state.

Plugin marketplace lifecycle

The plugin path has two user-facing entry surfaces: an in-session slash/TUI plugin menu and the CLI plugin / plugins command family. The CLI tree contains a marketplace root with add/list/update/remove-style wording, while settings and policy carry the durable state.

flowchart TD
Source[Marketplace source: URL / path / GitHub repo / settings] --> Register[extraKnownMarketplaces]
Policy[strictKnownMarketplaces / blockedMarketplaces] --> Register
Register --> Catalog[Known marketplace catalog]
Catalog --> Install[Install plugin + dependencies]
Install --> Enabled[enabledPlugins setting]
Enabled --> Runtime[hooks / MCP / skills / agents / output styles]
Runtime --> Reload[plugin-affecting settings reload]
StageSource-visible evidenceRuntime implication
Register marketplacemarketplace add <source>, extraKnownMarketplaces, sparse checkout and scope optionsMarketplaces can be declared from CLI or settings and scoped to user/project/local contexts.
Apply policystrictKnownMarketplaces, blockedMarketplaces, dependency-marketplace-blocked-by-policyManaged policy can allowlist or block sources before plugin/dependency installation completes.
Install pluginplugin_installed, dependency closure handling, enabledPlugins writesInstall resolves dependency closure, writes enabled plugin state, and emits plugin/marketplace telemetry.
Update plugintengu_plugin_updated_cli, autoUpdate settingsUpdates can be triggered from CLI and may be gated by marketplace auto-update configuration.
Disable or uninstalltengu_plugin_disabled_cli, tengu_plugin_uninstalled_cliDisable changes enabled state; uninstall can also run orphan scans/pruning.
Runtime contributionplugin hooks, mcpServers, skills, agents, outputStylesEnabled plugins become capability injectors, but still flow through settings, hooks, MCP, and permission boundaries.

This narrows the previous marketplace gap from “command surfaces only” to a lifecycle model: source registration, policy filtering, dependency resolution, enabled-state writes, update/disable/uninstall operations, and runtime capability reloads. The remaining gap is exact per-command UI flow and every option branch inside the lazy-loaded marketplace handlers.

Hook events

The hook schema includes these high-signal lifecycle events:

Hook familyExamples
Tool lifecyclePreToolUse, PostToolUse, PostToolUseFailure, PostToolBatch
Prompt/session lifecycleUserPromptSubmit, UserPromptExpansion, SessionStart, SessionEnd
Stop/compactionStop, StopFailure, PreCompact, PostCompact
Agent/task lifecycleSubagentStart, SubagentStop, TaskCreated, TaskCompleted
Permission/config/worktreePermissionRequest, PermissionDenied, ConfigChange, WorktreeCreate, WorktreeRemove

Security interpretation

MCP and plugins extend model-visible capabilities, but they do not bypass the rest of the runtime. The same command surface also exposes strict config, project-choice reset, hook validation, timeouts, and permission-prompt routing, which indicates that external capabilities are integrated through guarded runtime boundaries.

MCP runtime internals

This section separates MCP command management from runtime MCP connection and event handling.

Additional anchors

Semantic aliasSourceApproximate locationString or symbolMeaning
McpRuntimeCoordinatorcli.jsline ~19294, byte 0xd917c8function fH9(H)Runtime MCP connection coordinator.
RequiredMcpConfigSplitcli.jsline ~19294, byte 0xd918a0alwaysLoad===!0Split between required and normal MCP configs.
RequiredMcpConnectLabelcli.jsline ~19294, byte 0xd91940--mcp-config alwaysLoad serversRequired MCP config connect label.
ClaudeAiConnectorLabelcli.jsline ~19294, byte 0xd919b0claude.ai connectorsRuntime connector connect label.
McpToolsListSchemacli.jsline ~95, byte 0x907a4tools/listMCP tools/list protocol schema.
McpResourceListSchemascli.jsline ~95, byte 0x8fe5cresources/list, resources/templates/listMCP resource listing schemas.
McpPromptSchemascli.jsline ~95, byte 0x9017aprompts/list, prompts/getMCP prompt listing/get schemas.
McpToolTimeoutEnvcli.jsline ~4980, byte 0x937240MCP_TIMEOUTMCP tool timeout env var, defaulting to 30000 ms.
McpConnectTimeoutEnvcli.jsline ~4980, byte 0x9372a0MCP_CONNECT_TIMEOUT_MSMCP connection timeout env var, defaulting to 5000 ms.
McpAuthErrorTelemetrycli.jsline ~4983, byte 0x93fec6tengu_mcp_tool_call_auth_errorMCP tool-call auth-expiry telemetry/error path.
McpElicitationFramecli.jsline ~19349, byte 0xda6206elicitation_completeMCP elicitation completion is bridged into headless frames.

Runtime coordinator

The complete McpRuntimeCoordinator function is small enough to reconstruct:

  1. Receives regularMcpConfigs, claudeaiConfigPromise, and state.
  2. Computes a non-blocking flag from MCP_CONNECTION_NONBLOCKING or an explicit nonBlocking option.
  3. Stores the non-blocking state through IV8(_).
  4. Partitions regular MCP configs into alwaysLoad === true and all other configs.
  5. Returned connect() starts two parallel connection groups: regular configs via Br6(...) and claude.ai connectors via kKA(...) after claudeaiConfigPromise resolves.
  6. Records startup markers before_mcp_connect_user, before_mcp_connect_connector, after_mcp_connect_user, after_mcp_connect_connector.
flowchart TD
Input[regularMcpConfigs + claudeaiConfigPromise] --> NonBlocking[MCP_CONNECTION_NONBLOCKING]
Input --> Split[split alwaysLoad vs normal]
Split --> Required[alwaysLoad servers]
Split --> Normal[regular servers]
Input --> Connectors[claude.ai connectors]
Required --> Connect[connect() Promise.all]
Normal --> Connect
Connectors --> Connect

Required versus non-required servers

The alwaysLoad split is important. Required servers are labeled --mcp-config alwaysLoad servers and normal servers as --mcp-config servers. Required servers are connected as a distinct group; normal servers can honor non-blocking/deferred behavior; claude.ai connectors are a separate promise-driven group. Because connect() awaits both groups, the final headless startup waits for the coordinator as a whole even when parts are internally non-blocking.

MCP protocol surfaces

Protocol methodRole
tools/listLists tools exposed by an MCP server.
resources/listLists resources.
resources/templates/listLists resource templates.
prompts/listLists prompts.
prompts/getRetrieves a prompt by name/arguments.

These schema anchors are paired with runtime anchors in McpRuntimeCoordinator, McpCommandRegistrar, HeadlessControlLoop, and MCP tool-call error handling, confirming MCP as both a command/config system and a runtime capability provider.

Timeout and auth-error mechanics

  • MCP_TIMEOUT → tool-call timeout, falling back to 30000 ms.
  • MCP_CONNECT_TIMEOUT_MS → connection timeout, falling back to 5000 ms.

The MCP tool-call error path has a specific auth branch: on 401 or token-expiry-like errors, the runtime emits tengu_mcp_tool_call_auth_error and raises a user-facing error requiring re-authorization.

Elicitation and headless integration

MCP elicitation completion is visible in two places: the MCP client handles an elicitation completion notification and marks queued elicitation state as complete; HeadlessControlLoop emits system / elicitation_complete frames with mcp_server_name and elicitation_id. URL-mode elicitation is observable as a headless/SDK stream frame.

Command tree versus runtime connection

SurfaceFunctionRole
claude mcp ...McpCommandRegistrarManage config and run the MCP server.
root action headless setupMcpRuntimeCoordinatorConnect runtime MCP servers/connectors for a session.
MCP protocol schemasline ~95 schemasDefine method/result shapes.
Headless stream loopHeadlessControlLoopEmits MCP-related status, elicitation, auth, and tool-call state to headless consumers.

Created and maintained by Yingting Huang.