An MCP server exposes tools that a model may choose to call. A harness plugin solves a different problem: its hooks run automatically at defined points in the loop. That distinction makes hooks useful for controls that cannot depend on model initiative.
Cline packages a plugin as one object that can be reused across its CLI, VS Code, JetBrains, and SDK surfaces. Seven lifecycle boundaries cover the whole run, individual tool calls, model calls, and streamed events: beforeRun, afterRun, beforeTool, afterTool, beforeModel, afterModel, and onEvent.
The first example is an execution journal. A beforeRun hook records the start, while afterRun appends duration, status, iterations, input and output tokens, and total cost to a JSONL file. Because failed and aborted runs also reach the hook, the journal records outcomes rather than assuming completion.
The second example is a deterministic tool guard. A beforeTool hook inspects shell commands and returns skip: true when a pattern matches operations such as recursive deletion, forced pushes, filesystem formatting, or destructive database commands. The tool never executes, and the reason returns to the agent so the loop can finish honestly.
The same boundaries can redact secrets before a model call, send progress events to an interface, rewrite tool results, or emit operational metrics. The SDK runner installs journal and guard plugins together through its extensions configuration, keeping the policy separate from the prompt that defines the task.
For New Runtime, this is a practical separation of concerns. MCP remains the capability surface. Plugins become the deterministic enforcement and observation layer. Prompts can describe policy, but controls that must always run belong at lifecycle boundaries owned by the harness.
