- Distinguish a model call, a tool, MCP, RAG retrieval, and an agent loop.
- Observe when the model chooses and when application code remains in control.
- Implement the MCP lifecycle over stdio and stop repetition, excessive steps, and fabricated citations.
Verification contract
The laboratory was checked on July 27, 2026 with MCP 2025-11-25, Node.js 26.4.0, Ollama 0.32.1, and gemma3:4b. Its automated safety tests do not depend on a model; generative stages must be reassessed whenever the model or version changes.
Map the concepts before writing code
MODEL CALL: what text does the model generate from the supplied context? TOOL: which bounded function can it execute? MCP: how are capabilities discovered and invoked through a shared protocol? RAG: which evidence is retrieved before asking for an answer? AGENT: can the model choose the next step from an observation? SKILL: a reusable procedure for completing a task with defined criteria SUBAGENT: delegated work with separate context and tools
Add complexity only when you can name the new capability it provides. A local function may be enough without MCP, a well-contextualized call may be enough without a loop, and a fixed workflow is usually more predictable than an agent.
Use one case for all five stages
Tienda Brújula is fictional. Its synthetic policy states that online purchases may be returned within 30 calendar days of delivery. Reusing the same question prevents an easier example from masquerading as a better architecture.
GOAL What is the return period for an online purchase at Tienda Brújula? SYNTHETIC SOURCE [DEV-01] Online purchases may be returned within 30 calendar days after delivery. git clone https://github.com/aulafy/taller.git cd taller/cursos/agentes-automatizacion/laboratorios/de-chat-a-agente npm run verificar
The MIT-licensed laboratory uses no accounts or runtime dependencies and restricts Ollama to loopback. Five tests plus an audit cover retrieval, tool contracts, the MCP lifecycle, valid completion, repetition, fabricated citations, and maximum steps.
Stage 1: a model call does not have your private data
The model receives the question but not the fictional policy. In the verified run it answered 15 days and invented a URL. This does not prove every model always fails; it proves that a plausible sentence without evidence is not a business answer.
OLLAMA_MODEL=gemma3:4b npm run etapa:1 observed answer: 15 calendar days cited URL: fabricated evidence: [] status: do not use as fact
Stage 2: a tool is a function with a contract
buscar_politica accepts a short query and returns fragments with IDs. Application code calls it directly: there is no MCP and no model decision yet. Its narrow schema accepts neither paths, commands, nor arbitrary names, and the server validates the input again.
npm run etapa:2
input: buscar_politica("online purchase return period")
output:
DEV-01: 30-day online policy
DEV-02: 14-day physical-store policyStage 3: MCP standardizes the connection
A client now starts a local server as a subprocess and exchanges JSON-RPC over standard input and output. They negotiate protocol version and capabilities, send the initialized notification, list tools, and invoke the same bounded search. MCP does not decide when to act; a person, workflow, or model does.
npm run etapa:3 1. initialize (protocol 2025-11-25) 2. notifications/initialized 3. tools/list -> [buscar_politica] 4. tools/call -> DEV-01, DEV-02 5. close stdin and terminate the subprocess
Stage 4: RAG adds evidence before generation
Retrieval scores documents and selects fragments related to the question. The model receives those fragments and must answer only from the evidence while citing its IDs. RAG can still retrieve the wrong passage, omit a necessary one, or ingest hostile instructions, so evaluate retrieval and answer quality separately.
OLLAMA_MODEL=gemma3:4b npm run etapa:4 retrieved: [DEV-01, DEV-02] observed answer: "30 calendar days after delivery [DEV-01]."
Stage 5: the model chooses the next step
The model returns one structured decision: search or finish. The controller recognizes only those actions. After a search it appends the observation and asks again. The prompt proposes; code enforces the allowlist, read-only access, three-step maximum, duplicate-call stop, citation validation, and loopback-only Ollama endpoint.
OLLAMA_MODEL=gemma3:4b npm run etapa:5 step 1: buscar_politica -> [DEV-01, DEV-02] step 2: finish -> "30 calendar days after delivery"; citations: [DEV-01] status: completed steps: 2
Break the system deliberately
1. tools/list before initialization -> session not initialized 2. tool = leer_archivo -> tool not allowed 3. repeat an identical search -> loop stopped 4. finish with citation FAKE-99 -> missing or fabricated citation 5. continue after three steps -> maximum reached
Do not finish merely because the answer says 30 days. Explain which component supplied evidence, which standardized the tool, who selected each step, and which three rules prevented further execution. Save both the successful two-step trace and one deliberately rejected fabricated citation.
Know when to stop climbing
- Use one model call when you only need drafting or classification from available context.
- Use a workflow and deterministic gates when the path is fixed.
- Do not add an agent loop on top of RAG until you can evaluate retrieval.
- For consequential actions, require a preview and human approval before any write.
Primary sources
- MCP introduction, lifecycle, transports, and tool security: modelcontextprotocol.io/specification/2025-11-25
- Anthropic Engineering: Building effective agents
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks (arXiv:2005.11401)
- Ollama Generate API documentation: docs.ollama.com/api/generate