Appendix G: Agent Extension Points — Tools, Skills, Hooks, MCP, and Subagents
Version: 1.0 Last updated: February 2026
Navigation: ← Appendix F | Appendix Index | Appendix H →
G.0 Why This Appendix Exists
Chapter 2 introduces tools, skills, MCP, and A2A as core building blocks. Chapter 4 covers scaffolds and evaluation hooks. Chapter 5 covers harnesses. But a recurring question from builders is: "I need my agent to do something new — which extension mechanism should I reach for?"
This appendix provides a single reference that compares all five extension points side-by-side, explains when to use each, shows how they compose, and walks through practical examples using the HR Leave Agent.
Related sections:
- Core concepts → Chapter 2, §2.2 (Tools, MCP, A2A) and §2.4.6 (Skills)
- Scaffold design → Chapter 4, §4.7 (Evaluation hooks)
- Harnesses → Chapter 5
- Production operations → Chapter 11, §11.4 (Observability)
- Governance → Chapter 12, §12.2.4 (Policy-as-code)
G.1 The Five Extension Points at a Glance
An agent's capabilities grow through five distinct mechanisms. Each serves a different purpose, operates at a different level of abstraction, and has different trade-offs around setup complexity, determinism, and maintenance burden. The table below summarises the landscape before we dive into each one.
Table G.1 — Extension point comparison
| Extension point | What it is | Abstraction level | Execution model | Best for | HR Leave example |
|---|---|---|---|---|---|
| Tool | A single external function the agent can call | Lowest — one function | Deterministic API call with schema | Precise, well-scoped operations | get_leave_balance(employee_id) |
| Skill | A reusable mini-procedure (prompt + tools + light orchestration) | Mid — bundles 2–10 steps | LLM interprets instructions and selects tools | Recurring multi-step tasks across agents | "Interpret leave policy for a given request" |
| Hook | A callback that fires at a specific point in the agent lifecycle | Cross-cutting — attaches to lifecycle events | Deterministic code, runs synchronously or async | Logging, guardrails, audit, telemetry | Log every tool call; block dangerous HRIS writes |
| MCP server | A standardised server exposing tools, resources, and prompts | Infrastructure — wraps many tools behind a protocol | Deterministic API via standard protocol | Reusable connectors, centralised auth, enterprise integration | MCP server wrapping HRIS and policy corpus |
| Subagent | A specialist agent that receives delegated work from a supervisor | Highest — a full agent with its own scaffold | LLM-driven, with its own reasoning loop | Complex subtasks needing separate reasoning, policies, or models | Policy Interpreter agent, Action Executor agent |
G.2 Tools: The Atomic Building Block
A tool is the simplest extension point. It is a single function — with a typed input schema, a typed output, and well-defined side effects — that the agent can call when it decides to act on the world.
G.2.1 What makes a good tool
Think of tools as contracts. When you expose a tool to an agent, you are saying: "Here is something you are allowed to do. The inputs look like this. The outputs look like that. Do not improvise beyond this."
Good tools share several characteristics. They are narrow in scope, doing exactly one thing. They validate their inputs before executing. They handle errors gracefully, returning structured error responses rather than crashing. They are where you enforce RBAC, audit logging, and rate limits. And they have clear, descriptive names and docstrings, because the LLM uses these to decide when and how to call them.
from pydantic import BaseModel
class LeaveBalanceRequest(BaseModel):
employee_id: str
class LeaveBalance(BaseModel):
employee_id: str
annual_leave_remaining: float
medical_leave_remaining: float
as_of_date: str
def get_leave_balance(request: LeaveBalanceRequest) -> LeaveBalance:
"""Retrieve the current leave balance for an employee from the HRIS.
Returns remaining days for each leave type as of today.
Requires HRIS read permission for the employee's business unit.
"""
# validate permissions, call HRIS, return typed response
...
G.2.2 Tool design principles
Several principles keep tools reliable in production. First, keep schemas tight. Every field should have a type, a description, and validation constraints. Loose schemas lead to hallucinated inputs. Second, make tools idempotent where possible. If the agent retries a tool call due to a timeout, you do not want duplicate side effects. Third, separate read tools from write tools. Read tools are low-risk and can be called freely. Write tools need confirmation flows, staging, and approval gates. Fourth, return structured data rather than natural language. The LLM can always summarise structured data for the user, but it cannot reliably parse a wall of prose back into structured form.
Table G.2 — Read vs write tool design
| Aspect | Read tool | Write tool |
|---|---|---|
| Risk | Low — no side effects | Higher — changes state |
| Retry safety | Safe to retry | Must be idempotent or gated |
| Auth | Read-only scope | Write scope with approval |
| Example | get_leave_balance |
submit_leave_request |
| Guardrail | Rate limiting | Preview → confirm → execute |
Related: Tool contracts and safety boundaries → Chapter 2, §2.2.2; Safe tool patterns → Chapter 9, Pattern 9.2A
G.3 Skills: Reusable Multi-Step Capabilities
A skill sits one level above a tool. Where a tool is a single function call, a skill is a small, named procedure — typically implemented as a prompt plus tool access plus light orchestration — that performs a coherent chunk of work. Skills are the reuse unit that lets teams build new agents faster by composing proven capabilities rather than reinventing behaviour.
The critical insight about skills is that they are deployment-context-agnostic. The same skill abstraction — markdown instructions interpreted by an LLM at runtime — operates identically whether it runs in a developer's terminal, a production workflow, or an autonomous agent. What changes across these contexts is not the skill itself, but the oversight level configured around it. A developer using Claude Code's /commit skill sees terminal permission prompts. An HR Leave Agent running a policy-check skill in production might operate under human-on-the-loop oversight with audit logging. The skill mechanism is the same; the governance wrapper differs.
G.3.1 Anatomy of a skill
Anthropic's Agent Skills standard formalises skills as filesystem-based markdown modules with a SKILL.md entry point. Each skill has a name and description (in YAML frontmatter) that let the agent — or a human — understand what the skill does and when to use it. It has instructions in natural language that guide the LLM through the procedure. It has optional tool and invocation controls specified in frontmatter. And it can bundle supporting resources — reference documents, templates, scripts — that load only when needed.
The standard uses progressive disclosure to manage context window costs:
| Level | What loads | When | Typical cost |
|---|---|---|---|
| L1: Metadata | name + description from YAML frontmatter |
Always in context | ~100 tokens per skill |
| L2: Instructions | Main SKILL.md body |
When skill is triggered or invoked | <5k tokens |
| L3: Resources | Bundled scripts, templates, reference docs | Only when referenced during execution | Variable |
This means you can create skills with substantial reference material without paying context penalties when the skill is not active.
.claude/skills/
├── policy-check/
│ ├── SKILL.md # Main instructions (required)
│ ├── REFERENCE.md # Detailed policy interpretation rules (L3)
│ └── examples.yaml # Few-shot examples for edge cases (L3)
├── draft-response/
│ └── SKILL.md
└── balance-verification/
├── SKILL.md
└── script.py # Helper script for date calculations (L3)
A typical SKILL.md uses YAML frontmatter for metadata and control, followed by natural-language instructions:
---
name: policy-check
description: >
Interpret leave policy for a specific request. Checks eligibility,
constraints, and special conditions. Returns a structured assessment.
allowed-tools:
- retrieve_policy_clauses
- get_employee_profile
- check_public_holidays
---
When asked to check leave policy for a request, follow these steps:
1. Retrieve the relevant policy clauses using the employee's scheme and leave type.
2. Get the employee's profile to check tenure, employment type, and special conditions.
3. Verify the requested dates against public holidays and blackout periods.
4. Assess eligibility based on all retrieved information.
5. Return a structured assessment with: eligible (yes/no/maybe),
relevant clauses cited, any conditions or warnings, and confidence level.
If any information is ambiguous or conflicting, flag it explicitly
rather than making assumptions. When in doubt, recommend escalation.
Beyond name, description, and allowed-tools, the frontmatter supports additional controls:
| Field | Purpose | Example |
|---|---|---|
disable-model-invocation |
Prevents the LLM from auto-triggering; only manual /skill-name invocation |
true for destructive operations like deploy |
user-invocable |
Controls whether users can invoke directly | false for internal-only skills |
context |
Run in isolated subagent context | fork for skills that should not pollute the main context |
model |
Override which model runs the skill | Use a stronger model for complex policy interpretation |
These controls are important because they allow builders to configure skill-level governance — restricting who can trigger a skill and how it executes — independent of the broader oversight configuration around the agent.
G.3.2 Skills vs tools: the key distinction
The LlamaIndex team captured this distinction well in their experience building coding agents. With an MCP tool, the agent's challenge is limited to deciding which tool to run and when. The tool itself executes deterministically — given the same inputs, you get the same outputs. With a skill, the agent faces a broader challenge: it must decide which skill to use, when, and how. The "how" is answered by the agent itself, interpreting the natural-language instructions and deciding which tools to invoke in what order.
This means skills introduce an additional failure mode that tools do not have. A tool can fail because the agent chose the wrong tool or provided bad inputs. A skill can fail for those same reasons, but also because the agent misinterpreted the instructions, skipped steps, hallucinated intermediate results, or combined tools in an unintended sequence.
Crucially, these failure modes apply uniformly regardless of deployment context. A /commit skill in a developer's terminal can misinterpret instructions just as a policy-check skill in production can. The difference is not in the mechanism — it is in the oversight configuration that catches failures:
| Oversight level | Who catches failures | Latency cost | Example context |
|---|---|---|---|
| Human-in-the-loop | User approves each action before execution | High | Developer terminal with permission prompts |
| Human-on-the-loop | User monitors and can intervene | Medium | Dashboard watching agent process requests |
| Human-out-of-the-loop | Post-hoc audit and automated guardrails | Low | Fully autonomous agent with hook-based guardrails |
G.3.3 When skills shine
Despite this additional complexity, skills have clear advantages. They require minimal setup — just markdown files and a directory structure. They are easy to maintain and version, because they are human-readable text. They run locally without network overhead, which reduces latency. And they enable powerful behavioural customisation through natural language, which means non-developers can contribute to and review skill definitions.
Skills are particularly effective for tasks that benefit from contextual adaptation rather than rigid execution. Policy interpretation is a good example: the right answer depends on combining multiple pieces of information in context-sensitive ways, which is exactly what LLMs do well when given clear instructions.
Skills also benefit from scope hierarchy. They can be defined at multiple levels — personal (~/.claude/skills/), project (.claude/skills/), or organisation-wide (admin-managed) — allowing teams to share proven procedures while letting individuals customise for their own workflows.
G.3.4 Skill design principles
Design each skill to be well-bounded — it does one coherent job. Make it idempotent when possible, so it is safe to retry. Give it a contract with schemas for inputs and outputs. Evaluate it with a small, repeatable test set. Over time, a skill library becomes your real acceleration lever: new agents get built faster because you assemble proven skills rather than invent new behaviour every time.
Additionally, choose frontmatter controls deliberately. Mark destructive skills with disable-model-invocation: true so they cannot auto-trigger. Use context: fork for skills that produce large intermediate outputs, keeping the main agent's context clean. Specify a stronger model for skills requiring complex reasoning, and a cheaper one for routine formatting tasks.
Table G.3 — Tool vs skill comparison
| Dimension | Tool | Skill |
|---|---|---|
| Granularity | One function call | 2–10 coordinated steps |
| Execution | Deterministic API call | LLM interprets instructions |
| Failure modes | Wrong tool, bad inputs | + misinterpretation, step skipping |
| Setup | Code + schema definition | Markdown files + directory |
| Maintenance | Code changes, deploy | Edit markdown, local files |
| Latency | Network call per tool | Local (no network for skill loading) |
| Who can author | Developers | Developers + domain experts |
| Context cost | Schema always loaded | Progressive: metadata → instructions → resources |
| Oversight | Per-tool permission | Configurable per-skill via frontmatter |
| Best for | Precise operations | Recurring multi-step procedures |
Related: Skills as building blocks → Chapter 2, §2.4.6; Skill library strategy → Chapter 13, §13.1.5; Anthropic Agent Skills standard → Agent Skills documentation
G.4 Hooks: Cross-Cutting Lifecycle Callbacks
Hooks are the extension point that most builders discover later than they should. While tools and skills extend what the agent can do, hooks extend what happens around the agent — at specific moments in the agent's lifecycle, deterministic code runs to log, validate, audit, block, or enrich the agent's behaviour.
G.4.1 What hooks are
A hook is a callback function that fires at a defined lifecycle event. Common lifecycle events include agent start and end, LLM call start and end, tool call start and end, handoff events (when one agent delegates to another), and output production. Hooks receive context about the event — which agent is running, which tool was called, what the inputs and outputs were — and can perform side effects like logging, or even intervene by blocking an action.
The key characteristic of hooks is that they are deterministic code, not LLM-driven. The agent does not decide whether to invoke a hook. The runtime invokes hooks automatically at the appropriate lifecycle points. This makes hooks the right place for concerns that must be reliable, consistent, and auditable — precisely the properties that LLM-driven decision-making cannot guarantee.
G.4.2 Hook types and placement
Two broad categories of hooks appear across agent frameworks.
Run-level hooks apply to the entire agent run, regardless of which specific agent is active. Use these for global observability — logging every LLM call, tracking total latency and cost across the run, or emitting telemetry to your monitoring system.
Agent-level hooks are scoped to a specific agent. Use these when tracking or customisation only matters within one agent's logic — for example, logging only the policy-check agent's tool calls, or adding a pre-flight validation that only applies to the HRIS-writer agent.
G.4.3 Common hook patterns
Several patterns recur across production agent systems.
Audit logging. A pre-tool hook that logs every tool invocation with timestamp, agent identity, tool name, and sanitised arguments. This is essential for compliance in regulated environments. The hook runs before the tool executes, so even failed or blocked calls get logged.
# Conceptual hook — framework syntax varies
class AuditHook:
async def on_tool_start(self, context, agent, tool):
audit_log.write({
"timestamp": datetime.utcnow().isoformat(),
"agent": agent.name,
"tool": tool.name,
"args": sanitize(tool.args),
"session_id": context.session_id,
"user_id": context.user_id,
})
Guardrail enforcement. A pre-tool hook that checks whether a tool call should be allowed. For example, blocking any HRIS write operation that was not preceded by an approval step, or denying commands that match a dangerous pattern.
class SafetyHook:
async def on_tool_start(self, context, agent, tool):
if tool.name == "submit_leave_request":
if not context.state.get("manager_approved"):
return BlockAction(
reason="Leave submission requires manager approval"
)
Telemetry emission. Post-LLM hooks that record latency, token usage, and model version for every LLM call, feeding into dashboards and SLO tracking.
Context enrichment. A pre-LLM hook that injects additional context before each LLM call — for example, appending the latest policy update notice or the user's recent interaction history.
Outcome labelling. A post-run hook that writes a final outcome label (success, partial, escalation, failure) to the trace, enabling downstream harness scoring.
G.4.4 Hooks vs guardrails vs harness
These three concepts are often confused, so it is worth being precise. Hooks are lifecycle callbacks in the runtime — they fire deterministically at specific points. Guardrails are a subset of hook behaviour: they use hooks (typically pre-tool or post-output) to enforce safety and policy rules. Harnesses are the outer-loop evaluation rig — they consume the data that hooks produce (traces, spans, outcome labels) and use it for scoring, comparison, and regression testing.
In short: hooks produce the raw signal, guardrails enforce rules using that signal in real time, and harnesses analyse the signal after the fact.
Table G.4 — Hook vs guardrail vs harness
| Concept | Runs when | Purpose | Deterministic? | Example |
|---|---|---|---|---|
| Hook | During agent execution, at lifecycle events | Observe, log, enrich, block | Yes | Log tool call to audit trail |
| Guardrail | During agent execution, via hooks | Enforce safety and policy rules | Yes | Block unapproved HRIS write |
| Harness | After execution (or on replay) | Score, compare, regress | Yes | Score policy-check accuracy across 200 scenarios |
Related: Evaluation hooks in scaffolds → Chapter 4, §4.7.2; Harness design → Chapter 5, §5.3; Production observability → Chapter 11, §11.4
G.5 MCP: Standardising Tool and Context Integration
As your toolset grows beyond a handful of tools, integration sprawl becomes the dominant pain. Every agent framework needs connectors, every connector needs auth handling, every auth flow needs maintenance, and every upgrade risks breaking something. MCP (Model Context Protocol) is the industry's answer to this problem.
G.5.1 What MCP provides
MCP is a standard protocol for exposing tools and context sources via servers that agent runtimes can discover and call consistently. Think of MCP as "tool servers with a standard interface" or "a clean boundary between agent logic and enterprise integrations."
An MCP server exposes three types of capabilities. Tools are functions the agent can call, with typed schemas — these are equivalent to the tools described in §G.2, but wrapped in a standard protocol. Resources are extra context exposed in a file-like interface — documents, configuration, reference data that the agent can read. Prompts are parameterised, use-case-specific prompt templates that the server makes available.
G.5.2 MCP architecture
The architecture follows a client-server model. The agent runtime includes an MCP client. Each integration — HRIS, policy corpus, calendar system — runs as a separate MCP server. The runtime discovers available servers, queries their capabilities, and routes tool calls through the standard protocol.
flowchart LR
subgraph RT["Agent Runtime"]
AG["Agent + Scaffold"]
MC["MCP Client"]
AG <--> MC
end
subgraph S1["MCP Server: HRIS"]
T1["get_leave_balance"]
T2["submit_leave_request"]
R1["employee_profiles (resource)"]
end
subgraph S2["MCP Server: Policy"]
T3["search_policy"]
T4["get_clause"]
R2["policy_corpus (resource)"]
end
subgraph S3["MCP Server: Calendar"]
T5["check_holidays"]
T6["check_conflicts"]
end
MC -->|"discover + call"| S1
MC -->|"discover + call"| S2
MC -->|"discover + call"| S3
Figure G.1 — MCP servers provide a standardised interface between the agent runtime and enterprise systems.
G.5.3 Benefits of MCP
MCP brings several concrete benefits. Reusable connectors mean you build the HRIS integration once and every agent in the organisation can use it. Centralised security means auth, allow-lists, auditing, and rate limits live in the MCP server, not scattered across each agent's code. Faster iteration means you can swap or upgrade an integration without rewriting agent code — the protocol contract stays the same. Better ops means you get versioning, consistent tool schemas, and a single place to monitor integration health.
G.5.4 MCP trade-offs
MCP is not free. It introduces network latency on every tool call, because the call travels from the agent runtime to the MCP server over the network. For latency-sensitive operations that do not inherently require external data, local tools or skills will be faster. It requires server operations — someone needs to deploy, version, monitor, and maintain MCP servers. And it introduces a discovery challenge at scale: as the number of available MCP tools grows, the agent needs help navigating them, which has prompted the development of MCP gateways and discovery middleware.
There is also a practical risk of context pollution. Unoptimised MCP tools can return large payloads that clutter the agent's context window, reducing the space available for reasoning. Good MCP server design keeps tool responses concise and structured.
G.5.5 MCP vs direct tool integration
When should you use MCP versus wiring tools directly? The decision depends on reuse and scale. If a single agent needs a handful of tools that no one else will use, direct integration is simpler. If multiple agents across the organisation need access to the same enterprise systems, MCP pays for itself quickly through reduced duplication and centralised governance.
Table G.5 — Direct tools vs MCP
| Dimension | Direct tool integration | MCP |
|---|---|---|
| Setup | Simple — code tools directly | Moderate — deploy MCP server |
| Reuse | Per-agent | Organisation-wide |
| Auth management | Per-agent | Centralised in server |
| Latency | In-process (fast) | Network call (slower) |
| Maintenance | Connector sprawl as agents grow | Single server to maintain per system |
| Best for | Small systems, fast iteration | Enterprise scale, multi-agent reuse |
Related: MCP concepts → Chapter 2, §2.2.3; Integration choices table → Chapter 2, Table 2.1; Platform team responsibilities → Chapter 13, §13.1.4
G.6 Subagents: Delegating to Specialist Agents
The final extension point is the most powerful and the most complex. A subagent is not a function or a procedure — it is a full agent with its own scaffold, tools, policies, and reasoning loop, that receives delegated work from a supervisor agent and returns a result.
G.6.1 When single-agent is not enough
For many production use cases, a single agent can handle the work. The HR Leave Agent described throughout this handbook works well as a single agent for most queries. But as scope grows, single-agent architectures strain. You might need different security policies for reading versus writing — a "reader" agent with broad access and a "writer" agent with tightly scoped permissions. You might want different models for different tasks — a stronger, more expensive model for policy interpretation and a cheaper, faster model for formatting responses. You might need to parallelise work — researching policy, checking balances, and verifying calendar conflicts simultaneously. Or you might want clean separation of concerns so that each specialist can be developed, tested, and improved independently.
G.6.2 Subagent architecture patterns
Three patterns dominate.
Supervisor-specialist. A supervisor agent receives the user's request, breaks it into subtasks, delegates each to a specialist subagent, and composes the results into a final response. This is the most common pattern and maps naturally to team structures.
flowchart TB
U[User] --> SUP[Supervisor Agent]
SUP --> PA[Policy Agent]
SUP --> BA[Balance Agent]
SUP --> CA[Calendar Agent]
PA --> SUP
BA --> SUP
CA --> SUP
SUP --> OUT[Composed Response]
Figure G.2 — Supervisor delegates to specialists and composes the result.
Pipeline. Agents are arranged in sequence, each processing and enriching the request before passing it to the next. Useful when the work naturally flows in stages — for example, parse request → check policy → verify balance → draft response.
Peer-to-peer. Agents communicate directly with each other, without a central supervisor. This is less common in enterprise settings because it is harder to trace and govern, but it can be useful for collaborative tasks like research where multiple agents contribute different perspectives.
G.6.3 Subagent design principles
Several principles keep multi-agent systems manageable. First, define explicit contracts between agents. Each subagent should have a clear input schema, output schema, and description of what it does and does not handle. Without contracts, the supervisor cannot reliably decide which subagent to delegate to, and you cannot test subagents in isolation.
Second, scope tools per subagent. Do not give every subagent access to every tool. The Policy Agent needs policy retrieval tools. The Balance Agent needs HRIS read tools. The Action Executor needs HRIS write tools with approval gates. Tight scoping reduces the blast radius of errors and makes security review tractable.
Third, keep subagent count low. Every additional subagent adds coordination overhead, latency, and debugging complexity. Start with one agent and split only when you have a concrete reason — different security requirements, different models, or a clear need for parallel execution.
Fourth, make delegation observable. Use hooks to log every delegation event — which subagent was called, with what inputs, and what it returned. Without this, debugging multi-agent systems is nearly impossible.
G.6.4 Subagent trade-offs
The benefits of multi-agent architectures are real, but so are the costs. Each subagent invocation adds a full LLM call (at minimum), increasing latency and cost. Coordination between agents can fail in subtle ways — the supervisor might misroute a request, a subagent might return an ambiguous result, or context might be lost in translation between agents. Testing and evaluation become more complex, because you need to test both individual subagents and their composition. And governance must now track permissions, policies, and audit trails across multiple agents.
Table G.6 — Single agent vs subagent architecture
| Dimension | Single agent | Subagent architecture |
|---|---|---|
| Complexity | Lower | Higher — coordination, contracts, routing |
| Latency | One reasoning loop | Multiple LLM calls |
| Cost | Lower | Higher — more LLM invocations |
| Security | One permission scope | Per-subagent scoping (better isolation) |
| Testability | Test one agent | Test each subagent + composition |
| Debuggability | One trace | Multi-agent traces, delegation logs |
| When to use | Most cases | When you need isolation, parallelism, or different models |
Related: A2A concepts → Chapter 2, §2.1.4; Multi-agent orchestration → Chapter 13, §13.1.4
G.7 How Extension Points Compose
In practice, you rarely use just one extension point. A well-designed agent system composes them. Here is how the five extension points typically layer together in a production HR Leave Agent.
The agent runtime hosts the supervisor agent and its subagents. Each agent has a scaffold that defines its reasoning loop. The scaffold invokes skills for recurring multi-step procedures like policy interpretation. Skills call tools for atomic operations like retrieving leave balances. Tools may be served via MCP servers for standardisation and reuse. Hooks fire at every lifecycle point — logging tool calls for audit, enforcing guardrails before writes, emitting telemetry for monitoring, and labelling outcomes for the harness.
flowchart TB
subgraph Runtime["Agent Runtime"]
SUP["Supervisor Agent"]
subgraph Sub1["Policy Subagent"]
SK1["Skill: Policy Check"]
SK1 --> T1["Tool: retrieve_policy"]
SK1 --> T2["Tool: get_employee_profile"]
end
subgraph Sub2["Action Subagent"]
SK2["Skill: Submit Request"]
SK2 --> T3["Tool: submit_leave_request"]
end
SUP --> Sub1
SUP --> Sub2
end
subgraph MCP["MCP Servers"]
M1["HRIS Server"]
M2["Policy Server"]
end
subgraph Hooks["Hook Layer"]
H1["Audit Logger"]
H2["Guardrail Enforcer"]
H3["Telemetry Emitter"]
end
T1 -.-> M2
T2 -.-> M1
T3 -.-> M1
Runtime -.-> Hooks
Figure G.3 — Extension points compose: subagents use skills, skills call tools, tools connect via MCP, hooks observe everything.
Table G.7 — Composition patterns
| Pattern | What composes | Example |
|---|---|---|
| Tool via MCP | Tool → MCP server | get_leave_balance routed through HRIS MCP server |
| Skill using tools | Skill → multiple tools | Policy-check skill calls retrieve_policy + get_employee_profile |
| Subagent with skills | Subagent → skills → tools | Policy subagent invokes policy-check skill |
| Hooks on everything | Hooks → tools, skills, subagents | Audit hook logs every tool call across all subagents |
| Guardrail via hook | Hook → blocks tool | Pre-tool hook blocks unapproved HRIS writes |
G.8 Decision Framework: Which Extension Point to Use
When you need to extend your agent's capabilities, use this decision framework to choose the right mechanism.
Start with a tool when the capability is a single, well-defined operation with clear inputs and outputs. Most extensions start here. If you find yourself creating a cluster of related tools that are always used together in sequence, that is a signal to package them as a skill.
Promote to a skill when the same multi-step procedure appears in more than one agent, or when domain experts (not just developers) need to author and review the procedure. Skills are also the right choice when the procedure requires contextual interpretation — the kind of nuanced, context-dependent reasoning that LLMs handle better than rigid code.
Wrap in MCP when multiple agents or teams need the same tool integration, or when you want to centralise auth, rate limiting, and versioning for enterprise systems. MCP is an infrastructure decision, not a capability decision — it changes how tools are served, not what they do.
Add hooks whenever you need cross-cutting concerns — logging, audit, guardrails, telemetry, enrichment — that must fire reliably regardless of which agent or skill is running. Hooks are deterministic code, not LLM-driven, so they are the right place for anything that must be consistent and auditable.
Introduce a subagent only when you have a concrete architectural reason: different security scopes, different models for different tasks, a need for parallel execution, or a subtask complex enough to warrant its own reasoning loop. Do not split into subagents just because you can — coordination overhead is real.
Figure G.4 — Decision flowchart
flowchart TD
START["Need to extend agent capabilities"] --> Q1{"Single operation\nwith clear I/O?"}
Q1 -->|Yes| TOOL["Use a Tool"]
Q1 -->|No| Q2{"Multi-step procedure\nreused across agents?"}
Q2 -->|Yes| SKILL["Use a Skill"]
Q2 -->|No| Q3{"Need cross-cutting\nconcern (logging,\nguardrails, audit)?"}
Q3 -->|Yes| HOOK["Use a Hook"]
Q3 -->|No| Q4{"Multiple agents/teams\nneed same integration?"}
Q4 -->|Yes| MCP["Wrap in MCP Server"]
Q4 -->|No| Q5{"Need separate reasoning,\nsecurity scope, or model?"}
Q5 -->|Yes| SUBAGENT["Create a Subagent"]
Q5 -->|No| TOOL
TOOL --> QMCP{"Reuse needed\nacross org?"}
QMCP -->|Yes| MCP
QMCP -->|No| DONE["Done"]
SKILL --> DONE
HOOK --> DONE
MCP --> DONE
SUBAGENT --> DONE
Figure G.4 — Decision flowchart for choosing extension points.
G.9 HR Leave Agent: Putting It All Together
To make this concrete, here is how the HR Leave Agent uses all five extension points in a production deployment.
Tools provide the atomic operations. get_leave_balance reads from HRIS. retrieve_policy_clauses searches the policy corpus. check_public_holidays queries the calendar system. submit_leave_request writes to HRIS (with approval gating). Each tool has a typed schema, validation, and error handling.
Skills package recurring procedures. The "policy-check" skill combines policy retrieval, employee profile lookup, and date validation into a coherent assessment procedure. The "draft-response" skill takes an assessment and formats it as a clear employee-facing message. New leave types can be supported by updating the skill's markdown instructions without changing code.
Hooks enforce cross-cutting concerns. An audit hook logs every tool call for compliance. A guardrail hook blocks any HRIS write that lacks a preceding approval. A telemetry hook emits latency and token usage to the monitoring dashboard. An outcome hook labels each completed request for harness scoring.
MCP servers standardise enterprise integration. The HRIS MCP server wraps SAP/Workday behind the standard protocol, handling auth, rate limiting, and schema versioning. The policy MCP server indexes the policy corpus and exposes search and retrieval tools. Both servers are shared with other agents in the organisation — the onboarding agent, the payroll agent, and the benefits agent all use the same HRIS MCP server.
Subagents are used selectively. In a large deployment with complex policy interpretation, a separate Policy Interpreter subagent runs with a stronger model and read-only tools, while the main agent handles conversation flow and writes. In simpler deployments, a single agent handles everything, and the subagent pattern is not needed. The architecture supports both, and teams migrate from single-agent to multi-agent as complexity warrants.
G.10 Common Pitfalls
Several pitfalls recur when teams adopt these extension points.
Over-engineering with subagents. Teams introduce multi-agent architectures before they have evidence that a single agent cannot handle the work. This adds coordination complexity, latency, and cost without clear benefit. Start simple, measure, and split only when you have a concrete reason.
Under-investing in hooks. Teams build sophisticated tools and skills but skip hooks, losing observability and guardrail enforcement. In regulated environments, this creates compliance gaps. Hooks should be among the first things you implement, not the last.
Treating skills as tools. Wrapping every small operation as a skill adds unnecessary LLM interpretation overhead. If the operation is deterministic with clear inputs and outputs, it should be a tool. Skills are for procedures that benefit from contextual reasoning.
MCP without governance. Deploying MCP servers without versioning, monitoring, or access control creates a different kind of sprawl — now you have unmanaged infrastructure rather than unmanaged code. Treat MCP servers with the same operational discipline as any other production service.
Ignoring the composition. Building tools, skills, hooks, and subagents in isolation without thinking about how they interact leads to gaps — guardrail hooks that do not cover subagent tool calls, audit logging that misses MCP-routed tools, or skills that call tools with different schemas than the MCP server expects.
G.11 Chapter Cross-References
| Topic | Chapter | Sections |
|---|---|---|
| Tool contracts and schemas | Ch 2 | §2.2.2 (Tools as Contracts) |
| MCP concepts and architecture | Ch 2 | §2.2.3 (MCP) |
| Skills as building blocks | Ch 2 | §2.4.6 (Skills) |
| A2A and multi-agent patterns | Ch 2 | §2.1.4 (A2A) |
| Integration choices table | Ch 2 | Table 2.1 |
| Scaffold design and evaluation hooks | Ch 4 | §4.7 (Harness-Ready Scaffolds) |
| Harness design and operation | Ch 5 | §5.1–§5.3 |
| Safe tool patterns | Ch 9 | Pattern 9.2A |
| Production observability | Ch 11 | §11.4 |
| Policy-as-code | Ch 12 | §12.2.4 |
| Platform team and tool catalogue | Ch 13 | §13.1.4 |
Navigation: ← Appendix F | Appendix Index | Appendix H →