BusinessMCP

How to build an AI agent: a practical guide (2026)

13 min readLast updated September 7, 2026

A framework-honest guide to building AI agents — LangGraph, CrewAI, n8n or a plain API loop — with the agent loop in code, tool design principles, context strategy, evaluation, guardrails, cost control, and how BusinessMCP gives any framework unified business tools through one MCP endpoint.

What you will build

This guide walks through the anatomy of a working AI agent — one that can take a natural-language goal, plan, call tools, and return a result. We will keep the code illustrative and focus on the structure that matters, because the structure is what transfers between frameworks and models.

The four moving parts are always the same: a model to reason, a loop to drive it, a set of tools to act with, and safety controls around those tools. Everything else — memory, evaluation, cost management — is engineering around that core. If the concepts are new, ground them first with What are AI agents?.

Choosing a route: frameworks vs. plain loops

An honest map of the territory, because every option below is a legitimate way to ship an agent:

  • A plain API tool loop — call the model provider's SDK directly and write the loop yourself (the code below). A few dozen lines, no magic, total control. This is the best way to learn what agents are, and plenty of production agents never need more.
  • LangChain / LangGraph — the most established ecosystem. LangGraph models the agent as a graph with durable state, which buys you checkpoints, resumability, streaming, and first-class human-in-the-loop interrupts. Worth its learning curve when runs are long-lived or approval flows are core to the product.
  • CrewAI — role-based multi-agent teams ("researcher", "writer", "reviewer") with minimal ceremony. Fast for prototyping collaborative patterns; check that you actually need multiple agents before committing to the paradigm.
  • n8n — a visual workflow platform with agent nodes and MCP support. The right call when the people wiring business logic are not primarily developers, or the agent is one step inside a larger automation.

Two rules of thumb. First, start with the simplest thing that works — a direct loop — and adopt a framework when you feel the specific pain it solves (state persistence, interrupts, orchestration), not before; a framework you do not understand is a debugging tax. Second, whatever the orchestration layer, standardize the tool layer on MCP: every option above can consume MCP servers, so your data integrations survive a framework change.

The agent loop

At its heart an agent is a loop around a model call. In pseudocode:

loop:
  response = model(messages, tools)
  if response has no tool calls: return response   # final answer
  for each tool call: execute it, collect the result
  append the assistant turn and the tool results to messages

And as real TypeScript against the Anthropic SDK:

import Anthropic from '@anthropic-ai/sdk'

const client = new Anthropic()

async function runAgent(goal: string, tools: Tool[]) {
  const messages: Anthropic.MessageParam[] = [{ role: 'user', content: goal }]
  for (let turn = 0; turn < 20; turn++) {          // iteration cap
    const res = await client.messages.create({
      model: 'claude-opus-5',
      max_tokens: 4096,
      tools: tools.map((t) => t.schema),
      messages,
    })
    const toolUses = res.content.filter((c) => c.type === 'tool_use')
    if (toolUses.length === 0) return res           // final answer

    messages.push({ role: 'assistant', content: res.content })
    const results = []
    for (const call of toolUses) {
      results.push({
        type: 'tool_result',
        tool_use_id: call.id,
        content: await runTool(call.name, call.input),
      })
    }
    messages.push({ role: 'user', content: results }) // all results, one message
  }
  throw new Error('agent exceeded iteration budget')
}

That is the whole engine. Three details are load-bearing: the model may request several tools in one turn, and all their results must go back in a single user message; the loop needs an iteration cap so a confused agent terminates; and a failed tool should return an error message as its result — the model treats it as an observation and adapts — rather than crashing the loop. Provider SDKs now ship "tool runner" helpers that drive this loop for you; use them once you understand what they do.

Everything else — planning, memory, multi-agent coordination — is elaboration on this loop.

Tool design principles

A tool is a name, a description, a typed input schema, and a function that runs the work:

const sendEmail: Tool = {
  schema: {
    name: 'send_email',
    description:
      'Send an email to a recipient. Only use this after the user has approved the draft.',
    input_schema: {
      type: 'object',
      properties: {
        to: { type: 'string' },
        subject: { type: 'string' },
        body: { type: 'string' },
      },
      required: ['to', 'subject', 'body'],
    },
  },
  run: async ({ to, subject, body }) => {
    // ... integrate with your email provider
    return { sent: true }
  },
}

The principles that separate a tool set that works from one that confuses the model:

  • Few and sharp. Every tool description competes for the model's attention. Ten well-chosen tools beat forty overlapping ones; if two tools do nearly the same thing, merge them.
  • Described for decisions. The description is the model's only clue about when to use the tool, not just what it does. "Look up a contact by email. Use this before drafting any outreach" outperforms "Gets contact data."
  • Scoped. A tool should expose exactly the operation the agent needs — get_stock, not run_sql. Broad tools make gating, auditing and reasoning all harder.
  • Structured in and out. Typed schemas in, clean JSON out. The model supplies valid arguments without prior knowledge of your systems, and reasons far better over structured results than prose.
  • Honest about failure. Return machine-readable errors the model can act on ("no contact found for that email") instead of throwing.

This is also where MCP earns its place: define tools once behind a standard protocol and any agent — whatever the framework or model — discovers and calls them the same way. See How to build an MCP server for that path.

Context strategy

The model only knows what is in its context window, so what you put there — and keep out — determines both quality and cost. Three layers, in order:

The system prompt carries identity, capabilities, constraints, and durable business context: who the agent is, what tools it has, what it must never do, and the facts every task needs (what the company sells, who it sells to). Keep it stable — a fixed prefix caches across requests, which matters enormously for cost — and inject volatile data as messages, not by editing the prompt.

Retrieval brings in long-tail knowledge on demand. Rather than stuffing every document into every prompt, store knowledge in a searchable library and fetch what is relevant to the current task — via a search tool the agent calls, or a retrieval step before the loop starts. The agent that opens a conversation already holding a compact business snapshot, then pulls detail through tools, beats both the context-stuffed and the context-starved versions.

Compaction keeps long runs inside the window. When a thread grows past a threshold, summarize the older turns into a rolling digest and continue from that; oversized tool results deserve the same treatment (compress a 50KB API response to the fields that matter before it enters context). Without compaction, long-running agents drift, slow down, and eventually truncate.

Guardrails & safety controls

Before a tool runs, gate it. A small guard in front of runTool handles permissions, approvals and rate limits:

async function guard(action: { tool: string; input: unknown }) {
  if (!hasPermission(action.tool)) throw new Error('not permitted')
  if (needsApproval(action.tool)) await requestHumanApproval(action)
  if (isRateLimited(action.tool)) throw new Error('rate limited')
}

Layer the rest around it: an audit log of every call with inputs, outputs and caller; a per-run cost cap that aborts the loop at a ceiling; draft-then-approve for anything consequential (emails, spend, code — a pull request is a natural approval gate); and injection defense — treat everything the agent reads from the outside world (web pages, emails, tool results from third parties) as data, never as instructions. These are the same controls covered in depth in AI agent best practices.

Evaluating an agent

An agent without evals is vibes with an API bill. You cannot improve what you do not measure, and agents regress in non-obvious ways — a prompt tweak that fixes one behavior quietly breaks another.

The workable minimum: collect a small set of real tasks with checkable outcomes — twenty is enough to start. "Why did signups dip last week?" has a checkable outcome if you know the answer; "draft outreach for this prospect" has checkable properties (mentions something true about them, respects the banned-phrases list). Run the set on every prompt, tool or model change and track four numbers: task-completion rate, tool-call correctness (did it call the right tools with sane arguments?), cost per task, and latency.

For qualitative outputs, an LLM judge scoring against a rubric scales better than human review — but spot-check it, since judges share the model's blind spots. And in production, trace everything: every run should reconstruct into a readable sequence of model turns and tool calls, because "the agent gave a weird answer" is only debuggable when you can see which tool result sent it sideways.

Cost control

Agents multiply model calls, so cost discipline is architecture, not accounting:

  • Prompt caching. Keep the system prompt and tool definitions as a stable prefix; providers serve cached prefix tokens at a large discount. A volatile timestamp at the top of your prompt can silently double your bill.
  • Model routing. Not every step needs a frontier model. Route classification, extraction and compaction to a small fast model; save the big model for reasoning over the assembled evidence. The routing decision itself can be a cheap classifier.
  • Compression. Compact long threads; distil oversized tool results before they enter context. Tokens you never send are the cheapest tokens.
  • Budgets. An iteration cap and a per-run cost ceiling turn worst cases from an invoice into an error message. Meter per user or workspace so one heavy user cannot consume the pool.

This is, incidentally, most of what an agent platform does for you invisibly — BusinessMCP runs caching, routing, compaction and per-run cost caps on every Assistant run so the founder never thinks about them.

Where BusinessMCP fits

The loop above is the easy part. The hard part is the tools: securely connecting your CRM, analytics, ad platforms and Stripe revenue — and keeping tokens refreshed, permissions scoped, and calls logged — for every model you might use.

BusinessMCP is the data layer in that architecture, and because it speaks MCP, it slots under any of the frameworks in this guide. Connect your tools once and you get one hosted [MCP endpoint](/guides/expose-your-business-as-an-mcp-endpoint) that exposes them as clean, namespaced, permission-scoped tools — get_analytics, list_contacts, get_ads_stats, approval-gated send_email and the rest. A plain loop, a LangGraph node, a CrewAI agent or an n8n workflow all discover the same tools the same way: point at the endpoint with a Bearer mcph_* key. Scoping, audit logging and quotas apply at the endpoint, so the governance work travels with the data instead of being re-implemented per framework. See Expose your MCP endpoint and Connect Claude, GPT & Gemini.

If you do want to hand-build the server side, How to build an MCP server covers that path.

Next steps

You now have the shape of an agent: a loop, tools, context, guardrails, evals and a budget. From here, deepen it with real planning and memory — and read AI agent best practices before you put it in front of users. To ground the concepts, revisit What are AI agents? and What is MCP?.

Frequently asked questions

What is the difference between building an AI agent and an MCP server?

An MCP server exposes tools and data; an AI agent is the intelligent system that decides which tools to call to reach a goal. You often build both — but with BusinessMCP the server side is handled, so you can point an agent at a ready-made endpoint instead.

Which framework should I use to build an AI agent?

Start with a plain tool loop against a provider SDK — it is a few dozen lines and teaches you what the frameworks abstract. Reach for LangGraph when you need durable state, checkpoints and human-in-the-loop interrupts; CrewAI for quick role-based multi-agent setups; n8n when the builders are not primarily developers. All of them can consume MCP tools, so the data layer stays the same whichever you pick.

How do I make the agent safe and reliable?

Start with limited permissions, require human approval for consequential actions, log every tool call, and add rate limits and a cost cap. Expand what the agent can do only as it proves itself in lower-risk tasks.

How do I know if my agent actually works?

Build a small evaluation set of real tasks with checkable outcomes, run it on every prompt or tool change, and track task-completion rate, tool-call correctness, cost and latency. Trace every production run so failures are diagnosable. Without evals, every prompt tweak is a guess.

Keep going

Turn your company into one AI-ready data platform on a single hosted MCP endpoint.