Module 4: Tools: The Agent That Acts on Real Systems

1. Introduction: the agent that acts

Description

By the end of this lesson you'll be able to explain the difference between an agent that only informs and one that executes, identify what changes — in terms of risk and real outcome — when you connect the agent a tool that writes instead of one that only reads, and you'll have the complete map of the eight lessons that make up this module.

This matters because it's exactly where an interesting experiment splits from a system a company puts into production. An agent that answers well-worded questions about an order's status saves the support team a few inquiries. An agent that can also create the replacement, update the record in the database, and trigger the confirmation email — with nobody on your team touching a keyboard — is the one that justifies the whole project. The difference between the two isn't in the model or the prompt: it's in what tools it has connected.

Connection to the module: in lesson 5 of Module 1 you already connected a tool to your agent — get_order_status, an HTTP Request Tool in read-only mode — and you saw how its description told the model when to use it. This lesson revisits that same tool, but to show something that wasn't the point back then: reading a piece of data and acting on a system are two categorically different things, even though both connect to the same ai_tool port on the AI Agent node. It also closes a thread left open in Module 3's introduction: there you saw that memory stores what was said, not the system's real state, and that the boundary between "what's remembered" and "what's verified" sharpens when memory and tools work together. This lesson is where that "together" starts. A scope note: this module doesn't cover how an agent reads your own documents or searches a knowledge base (embeddings, PDFs, invoices) — that belongs to another guide. Here the agent acts on systems with tools and memory, it doesn't retrieve information from its own documents.

Seeing the problem isn't the same as solving it

Think of two people staffing the same technical support desk. Both have, in front of them, the same screen with the customer's complete history: their purchases, their open tickets, the exact status of every order. Ask either one "where's my order?" and both are going to answer well, with the same data, in the same friendly tone. But only one of the two also has the button to process a refund, generate a return label, or trigger an apology email with a coupon. The other, even though they see exactly the same problem on the same screen, can only say: "I'm so sorry, I'm going to escalate your case to someone who can actually resolve it" — and that's where their turn ends, even though they understood the problem perfectly.

That difference — seeing a problem versus being able to solve it — is the same one that separates what you built in Modules 1 through 3 from what you're going to build in this module. Up to now your agent understood the message (the model), knew what tone to use (the prompt), remembered what had already been discussed (memory), and could check an external piece of data before responding (get_order_status, a read-only tool). But it was still, at bottom, a very well-informed narrator: all it could do was describe the state of the world, never change it. This module gives the agent the button — tools that don't just read, but act: send a real email, write a new row into a spreadsheet, create a record in a database, or trigger a complete sub-workflow that executes a sequence of steps against a system in production.

n8n draws this exact same line, though with different vocabulary, when it distinguishes an agent from a chain: a chain follows a fixed sequence of calls you defined in advance, while an agent uses the language model to decide what action to take at each moment. The word that matters there is action, not response. And n8n's documentation describes tools, in that same sense, as the add-ons that give the agent access to additional context or resources — a deliberately broad definition, because it doesn't distinguish between an add-on that lets you look and one that lets you act. That distinction is yours to draw, and it's the thread running through this entire module.

Before continuing, one important clarification: exactly how the model decides which tool to call when it has several connected, and with what data it builds that call, isn't this lesson's topic — it's the next one's full topic. What matters here is simpler and more urgent: understanding that your agent's capability doesn't depend on how smart the model is, it depends entirely on which tools you decided to connect it.

Worked example: the same question, two agents with different capability

Go back to the TuTienda support agent you already know, with its usual System Message and its connected memory. Let's run the same customer message against two configurations that differ in only one thing: which tool is connected to the ai_tool port.

# CONFIGURATION A — only a read tool (from Module 1)
tool.name          = "get_order_status"
tool.method         = GET
tool.description    = "Use this to check an order's status and delivery
                       date given its number."
tool.url            = "https://api.tutienda.com/orders/{order_id}/status"

Customer's message: "My order #4521 arrived damaged. I need you to send me a new one, please."

What to expect — Configuration A. The agent has a single tool available, and it's read-only. It uses it, confirms order 4521 was indeed delivered, and that's as far as it can go. There's no tool letting it create a replacement or mark the order as damaged, so the only honest response it can give is something like: "I'm so sorry for the inconvenience. I've confirmed your order was delivered — I'm going to escalate your case to someone on our team who can handle the replacement." Nothing changed on TuTienda's side: no new record, no email triggered. The agent understood the problem perfectly and still couldn't solve it — it was missing the button, not the judgment.

# CONFIGURATION B — a second tool is added, this time an action one
tool.name          = "create_replacement_order"
tool.method         = POST
tool.description    = "Use this when the customer reports a damaged,
                       incomplete, or lost order and you already have
                       the confirmed order number. Creates a free
                       replacement order and triggers the confirmation
                       email to the customer. Do not use it for orders
                       that are simply running late within the normal
                       window — get_order_status is enough to inform
                       about the status for that."
tool.url            = "https://api.tutienda.com/orders/{order_id}/replacement"

Same customer message, agent with both tools connected.

What to expect — Configuration B. The agent now has two tools and chooses between them — the exact mechanism of that choice is what you're going to see in the next lesson; what matters here is the observable result. It calls create_replacement_order with order_id = 4521, gets a confirmation, and responds: "I've already generated a replacement for your order #4521, at no cost. You're going to get a confirmation email in the next few minutes with the new tracking number." This time something did happen on TuTienda's side: a new row in the replacements table, and a real email TuTienda's system triggered to the customer. If you check order 4521 again a minute later with get_order_status, the status changed — there's a replacement on the way — because the agent didn't describe the world: it modified it.

Notice the only thing that changed between the two configurations: the model is the same, the System Message is the same, the memory is the same. The only difference is which tool you had connected to the ai_tool port. That's this entire module's lesson in one sentence: an agent's capability — what problems it can solve, not just explain — is determined entirely by the catalog of tools you give it, and by how well each one communicates when to use it.

This module's map

The rest of this module is seven concrete pieces about how to give an agent tools with judgment, not blindly:

LessonWhat it resolves
2The tool calling mechanism: how the model decides which tool to invoke, what data it builds the call with, and what it does with the result before responding
3n8n's catalog of native tools for searching, creating, and sending, without leaving n8n itself
4How to connect tools against your company's real systems: Gmail, Google Sheets, a database, and any API via HTTP
5Tool contracts and trust boundaries: how to decide how much autonomy to give a tool that acts, and how to design safeguards before something goes wrong
6How to encapsulate reusable logic in a complete sub-workflow and expose it to the agent as a single tool
7MCP in n8n: how to consume tools from an external MCP server, and how to expose your own n8n instance's tools to other agents via the instance MCP server
8Mini-project: an agent that executes three different actions against real systems, start to finish

Notice the order: first the generic mechanism of how an agent picks and uses a tool (lesson 2) — because you need to understand that before lesson 3's catalog makes sense — then the catalog itself split into two layers: what's native to n8n (lesson 3) and what requires credentials from an external system (lesson 4). With that catalog already in hand, lesson 5 resolves the question this module has been raising all along: if a tool can act, how much freedom do you give it? Lessons 6 and 7 are two more advanced ways of packaging tools — your own logic in a sub-workflow, or someone else's logic via a standard protocol — before assembling it all in lesson 8's mini-project.

About MCP specifically: lesson 7 covers it in the right proportion for this guide — the concept of connecting an n8n agent to external tools through a standard protocol, and the node that exposes your own instance as a server — not a full course on the protocol. And about what this module deliberately doesn't touch: none of what's coming is going to teach you to have the agent read your own documents, PDFs, or invoices, or to build a knowledge base with embeddings. That's a different problem — retrieving your own information, not acting on systems — and belongs to a whole other guide.

Common mistakes

The agent that says it acted without having acted (conceptual). What happens: you ask the agent to cancel a subscription, and it responds confidently — "Done, I cancelled your subscription, you won't be charged next month" — but in the real system the subscription is still active. Why it happens: a language model generates, by default, the most plausible text given the context — and a success confirmation is exactly the kind of plausible text it would produce if it had actually acted. If there's no cancellation tool connected, or if the tool exists but the call failed silently, nothing in the model stops it from writing the response anyway as if the action had happened. How to spot it: never trust the response text as proof something happened — check n8n's execution log, step by step; if there's no tool call node logged for that specific action, it didn't happen, no matter how convincing the response sounds. How to fix it: first verify a real tool exists connected for every action you expect the agent to be able to execute, and in production, design the System Message so the agent only confirms a result after receiving the tool's response — never before, and never by inference.

Treating every tool at the same risk level (conceptual). What happens: you connect get_order_status (read) and create_replacement_order (action) with the same lack of concern, without thinking that one fails differently than the other. If get_order_status fails or responds badly, the worst case is the agent states an incorrect fact — annoying, but reversible with a correction message. If create_replacement_order gets called with the wrong order_id, or gets called twice by mistake, you've already generated a real replacement, spent real money, and maybe confused a customer who never reported any damage. Why it happens: on n8n's canvas, both tools look identical — the same node type, the same dotted line toward ai_tool — so nothing in the interface reminds you one is reversible and the other isn't. How to spot it: for every tool you connect, ask yourself what happens if the agent calls it with incorrect data or at the wrong moment; if the answer involves money, a deleted record, or a message sent to the wrong person, it's a high-risk tool. How to fix it: this lesson doesn't fully solve the problem — that's exactly lesson 5's job, tool contracts and trust boundaries — but the first step is simply naming each tool's risk before connecting it, not after an incident.

Confusing having credentials connected with having a tool connected. What happens: you set up a Gmail credential in n8n so the agent can, in theory, send emails — but the agent never does, not even when the situation clearly calls for it. Why it happens: the credential authenticates n8n against the external service (lets it operate as your Gmail account), but that's independent of whether that capability is exposed to the agent. Only what's connected to the AI Agent node's ai_tool port is part of the set of actions the model can choose to invoke; a credential configured on a node that isn't connected there simply doesn't exist for the agent. How to spot it: if the agent never tries to use an action it "should be able to do," first check whether that tool's node is physically connected — with the corresponding dotted line — to the ai_tool port, and not just present somewhere on the canvas. How to fix it: visually verify every connection before assuming a problem is about the model's judgment; often it's simply, more plainly, a missing wire.

Exercises

Exercise 1 — Classify the risk. You have these four candidate tools for a support agent: get_customer_email (looks up a customer's email by their ID), list_open_tickets (lists a customer's open tickets), delete_customer_account (deletes a customer's account entirely), charge_credit_card (charges an amount to the customer's saved card). Classify each one as "read" or "action," and flag which ones would already, intuitively, need more caution before connecting them to an agent.

See solution

Read: get_customer_email and list_open_tickets — both query data with no modification; the worst case of misuse is an incorrect fact in the response. Action: delete_customer_account and charge_credit_card — both change a real system's state, and both are also hard or impossible to reverse: a deleted account doesn't come back on its own, and an incorrect charge requires a manual refund. These last two are the ones that need the most caution, precisely because the cost of an error isn't "a weird response," but a real consequence outside the conversation.

Why it works: the criterion isn't how "important" the tool's name sounds, but whether executing it changes an external system's state and how reversible that change is — the same question you're going to apply systematically in lesson 5.

Exercise 2 — Did it act, or just talk? A customer asks your agent to cancel their subscription. The agent responds: "Done, I cancelled your subscription — you won't be charged next month." You check that workflow's execution log in n8n and see only two nodes executed: the Chat Trigger and the AI Agent node. No tool node appears in the log. Did the cancellation actually happen? How would you confirm it with certainty?

See solution

There's no evidence the cancellation happened. If the agent had called a tool, that call would show up as another step in the execution log — n8n logs every tool call as part of the workflow's trace. The log showing only the Chat Trigger and the Agent suggests either there's no cancellation tool connected to the ai_tool port, or there is one but the agent never invoked it, and either way the response text is a fabricated confirmation, not a report of something that happened. To confirm with certainty: first check the canvas and verify whether a cancellation tool is connected; then, verify directly in the real system (the subscriptions panel, not what the chat said) whether the customer's status changed.

Why it works: the execution log is the only source of truth about what actions actually happened — the model's response text is, at best, a summary of that, and at worst, a hallucination with the same shape as an honest summary.

Exercise 3 — The map without looking at it. Without looking at the previous section's table again, write from memory what problem each of the seven remaining lessons in this module (2 through 8) solves, one sentence each.

See solution

(2) How the model decides which tool to invoke, with what data, and what it does with the result. (3) n8n's catalog of native tools for searching, creating, and sending. (4) How to connect tools against real systems: Gmail, Sheets, a database, any API via HTTP. (5) How to decide how much autonomy to give a tool that acts, and how to put up safeguards. (6) How to package your own logic in a sub-workflow and expose it as a single tool. (7) How to consume external tools via MCP, and how to expose your own with the instance MCP server. (8) The mini-project: an agent that executes three real actions start to finish.

Why it works: if you could reconstruct the order without looking, you already have this module's progression internalized — from "how does it pick a tool?" to "what catalog do I have available?" to "how much do I trust each one?" to "how do I package more complex logic?"

Summary and next step

In this lesson you saw that the difference between an agent that only informs and one that resolves isn't in the model or the prompt, but entirely in what tools it has connected — and, specifically, in whether those tools only read or also act on a real system. The #4521 order example showed the same model, prompt, and memory configuration producing two completely different outcomes based on a single variable: the presence of an action tool. You also saw the complete map of the seven lessons ahead, and two explicit boundaries for this module: MCP gets covered in the right proportion in lesson 7, and reading your own documents (PDFs, invoices, knowledge bases) is not part of this guide.

Before moving on to lesson 2 you should be able to: explain in one sentence the difference between a read tool and an action tool, citing the order-replacement example; tell apart, given an execution log, whether an action the agent said it did actually happened; and name, without looking at the table, at least four of the seven lessons ahead and what each one resolves.

What you haven't seen yet — on purpose — is exactly how the model decides which of several connected tools to invoke, what data it builds that call with, and what it does with the result before generating its response. That mechanism, tool calling, is the next lesson's full topic.

Resources