中文 | English
Why does Claude Code expose multiple extension surfaces instead of one single “plugin API”?
l3-tool-systeml6-advanced
main.tsxplugins/builtinPlugins.tsutils/hooks/hookHelpers.tsutils/hooks/execAgentHook.tscomponents/mcp/*
mcpcreateStructuredOutputToolregisterStructuredOutputEnforcementgetBuiltinPluginsexecAgentHook
- MCP solves “bring external capabilities into the runtime”
- hooks solve “inject behavior at lifecycle boundaries”
- plugins solve “package skills/hooks/MCP into toggleable feature groups”
main.tsx: heavy MCP initialization and CLI entry logicplugins/builtinPlugins.ts: built-in plugin registry and enable/disable policyutils/hooks/hookHelpers.ts: structured output enforcement helpersutils/hooks/execAgentHook.ts: hooks can run a restricted agent throughquery()
The point is not merely that Claude Code supports many extension types. The point is that different extension problems get different abstractions. A single plugin API would look simpler, but the boundaries would be blurrier.
- Which of MCP, hooks, and plugins is closest to capability ingress, lifecycle interception, and feature packaging?
- Why do hooks also use
SyntheticOutputTool? - If you wanted to integrate an external service, would you start with MCP or a plugin, and why?