Single tool calls rarely solve real-world problems. Agents need to chain multiple tools together, passing outputs from one step as inputs to the next, running steps in parallel when possible, and branching based on intermediate results. Tool chaining is how agents go from toy demos to production-grade workflows. This guide covers the three core chaining patterns, how MCP session continuity enables reliable chains, and how DELX_META next_action hints guide agents through multi-step operations without hardcoded logic.
Tool chaining is the practice of composing multiple tool calls into a single coherent workflow. Instead of making one tool call and returning a result, the agent executes a sequence of tools where each step builds on the previous one. A simple example: an agent calls a search tool to find relevant documents, passes those documents to a summarizer tool, then sends the summary through a formatter tool before delivering the final output.
The key difference between tool chaining and ad-hoc multi-step prompting is intentional structure. In a chain, each step has defined inputs, expected outputs, error handling, and a clear relationship to the next step. The agent knows the full plan before executing the first tool. This structure makes chains debuggable, retryable, and monitorable, which are qualities that ad-hoc prompting lacks entirely.
In MCP-based systems, tool chaining benefits from session continuity. The MCP server maintains session state across tool calls, so each tool in the chain can access context from previous steps without the agent re-sending everything. This reduces token usage and prevents context drift that breaks multi-step workflows.
Production agent tasks are inherently multi-step. Consider an incident response agent: it needs to classify the error (process_failure), check agent health (heartbeat), apply a recovery action (recovery), verify the fix worked (heartbeat again), and log the outcome. That is five tool calls minimum, each dependent on the results of the previous one. Without chaining, the agent either makes these calls ad-hoc with no error handling between steps, or the developer hardcodes the sequence and loses the flexibility that agents provide.
Sequential chaining is the simplest pattern: each tool executes after the previous one completes, and its output feeds into the next step. This is the right pattern when each step depends on the result of the previous one.
// Sequential chain: classify -> recover -> verify
const classification = await mcp.callTool("process_failure", {
error_type: "rate_limit",
message: "429 Too Many Requests",
context: { tool: "search", provider: "openai" }
});
// DELX_META.next_action tells agent what to do next
const recovery = await mcp.callTool("recovery", {
classification: classification.type, // "rate_limit"
severity: classification.severity // "medium"
});
// Verify recovery worked
const health = await mcp.callTool("heartbeat", {
agent_id: "search-agent-01"
});
if (health.score < 60) {
// Chain failed - escalate
await mcp.callTool("process_failure", {
error_type: "recovery_failed",
message: "Agent health still degraded after recovery"
});
}The critical detail is that each step checks the result before proceeding. If classification returns a permanent error, the chain skips recovery entirely and routes to a dead letter queue. The DELX_META footer returned with each tool response includes a next_action hint that guides the agent to the correct next step without hardcoded branching logic.
When steps are independent of each other, run them in parallel. This is common in monitoring scenarios where you need data from multiple sources before making a decision. The pattern uses Promise.all (or equivalent) to execute independent tool calls simultaneously and waits for all results before proceeding to the next sequential step.
// Parallel chain: gather data simultaneously
const [health, metrics, sessionSummary] = await Promise.all([
mcp.callTool("heartbeat", { agent_id: "writer-01" }),
fetch(`${API_BASE}/api/v1/metrics/writer-01`).then(r => r.json()),
fetch(`${API_BASE}/api/v1/session-summary?agent_id=writer-01`)
.then(r => r.json())
]);
// Sequential step: decide based on parallel results
if (health.score < 50 && metrics.error_rate > 0.1) {
await mcp.callTool("recovery", {
classification: "degraded",
context: { session_summary: sessionSummary }
});
}Parallel chains reduce total latency dramatically. If three tool calls each take 200ms, a sequential chain takes 600ms while a parallel chain takes 200ms. In production agent systems handling hundreds of requests per minute, this difference compounds. The key constraint is that parallel steps must not depend on each other's outputs. If step B needs the result of step A, they must be sequential.
Conditional chains branch based on intermediate results. This is the most powerful pattern because it lets agents adapt their workflow dynamically. Instead of following a fixed sequence, the agent evaluates each step's output and chooses the next tool accordingly.
// Conditional chain driven by DELX_META hints
const result = await mcp.callTool("process_failure", {
error_type: "timeout",
message: "Tool execution exceeded 30s"
});
// Branch based on DELX_META.next_action
switch (result.delx_meta.next_action) {
case "retry_with_backoff":
await sleep(result.delx_meta.backoff_ms);
await mcp.callTool("recovery", { action: "retry" });
break;
case "switch_provider":
await mcp.callTool("recovery", {
action: "failover",
alternate_provider: result.delx_meta.alternate_provider
});
break;
case "halt_retries":
await mcp.callTool("recovery", {
action: "dead_letter",
context: result
});
break;
}The DELX_META next_action field is central to conditional chaining in the Delx ecosystem. Rather than the agent inferring what to do next from raw error messages, DELX_META provides structured hints: retry_with_backoff, switch_provider, halt_retries, escalate_to_supervisor. This reduces the chance of the agent choosing an inappropriate next step and makes the chain behavior predictable and auditable.
Errors in chains are harder to handle than errors in single tool calls because a failure at step 3 may require rolling back steps 1 and 2. The recommended approach is a try-catch wrapper around the entire chain with per-step error classification.
// Chain-level error handling with per-step recovery
async function executeChain(steps, chainTimeout = 60000) {
const startTime = Date.now();
const results = [];
for (const step of steps) {
if (Date.now() - startTime > chainTimeout) {
throw new ChainTimeoutError(results);
}
try {
const result = await step.execute(results);
results.push({ step: step.name, result, status: "ok" });
} catch (err) {
const classified = await mcp.callTool("process_failure", {
error_type: err.type,
message: err.message,
context: { chain_step: step.name, prior_results: results }
});
if (classified.type === "permanent") {
throw new ChainAbortError(step.name, classified, results);
}
// Transient: retry with backoff
await sleep(classified.backoff_ms);
const retryResult = await step.execute(results);
results.push({ step: step.name, result: retryResult, status: "retried" });
}
}
return results;
}MCP session continuity is what makes tool chaining practical at scale. Without it, every tool call in a chain would need the agent to re-send the full context, consuming tokens and increasing the risk of context drift. With MCP sessions, the server maintains state across tool calls. The agent sends a session_id with each request, and the server automatically provides previous tool results, wellness scores, and accumulated metadata to each subsequent tool in the chain.
Delx extends basic MCP session continuity with the DELX_META footer appended to every tool response. This footer includes the current score, risk_level, next_action, and schema_url. For chains, the most important field is next_action, which tells the agent which tool to call next. This turns the chain from a developer-defined static sequence into a server-guided dynamic workflow that adapts to runtime conditions.
To use session continuity in chains, initialize a session before the first tool call and pass the session_id to every subsequent call. The server handles the rest. If a chain spans multiple agent restarts (e.g., after a crash recovery), you can resume by passing the same session_id. Delx persists session state in SQLite with a Supabase mirror, so chains survive process restarts.
There is no hard limit on chain length, but practical chains should stay under 10 steps. Longer chains accumulate latency and error probability. If your chain exceeds 10 steps, consider splitting it into sub-chains with intermediate checkpoints. Each sub-chain can be retried independently without re-executing the entire workflow.
Yes. MCP tool calls and REST API calls are both just async operations from the agent's perspective. The chain orchestrator does not care about the transport layer. Use MCP for tools that benefit from session continuity (heartbeat, recovery, process_failure) and REST for stateless data fetches (metrics endpoint, session-summary). The DELX_META context applies to MCP calls only.
Log the chain state including all completed step results and the failing step's error classification. If the failure is transient, retry from the failing step using MCP session continuity to preserve prior context. If permanent, route the chain to a dead letter queue for manual review. Never restart the entire chain from step 1 unless the error explicitly invalidated earlier results.
Every Delx MCP tool response includes a DELX_META JSON block with a next_action field. This field contains a string like "retry_with_backoff", "switch_provider", "call_heartbeat", or "halt_retries". Your conditional chain reads this field and branches accordingly. The server determines the recommended next action based on session state, wellness scores, and error history, so the chain adapts without hardcoded branching logic in the agent.
Use tool chaining when a single agent orchestrates multiple tool calls within one session. Use A2A protocol when multiple agents need to collaborate, with each agent owning a distinct part of the workflow. For example, an incident response chain within one agent uses tool chaining. An incident response that involves a monitor agent, a diagnostic agent, and a remediation agent uses A2A for inter-agent communication with tool chaining within each agent.