MCP servers for a small business: give your assistant tools, not copy-paste

An MCP server gives an AI assistant named tools over your own systems. Why to start read-only, OAuth or bearer token, and the Sales Desk MCP server we run.

Published · 5 min read · By MCPAI agentstools

A dark pegboard with hand tools hung inside painted outlines; one pair of pliers is lifted out and its outline glows blue.
Illustration generated for this article (fal.ai, Nano Banana 2): every tool has its place, and you can see which one is in use.
In short
  • An MCP server turns your system into named tools an AI assistant can call, instead of you copying data in and out of the chat.
  • Start read-only. Add write tools one at a time, and never add a tool for an action that must stay human.
  • OAuth for assistants used by people, a bearer token for your own agents, and one permission check behind both.
  • One server per system, with the variable part, such as which mailbox, as a parameter, not a second server.

An MCP server is a small service that gives an AI assistant a set of named tools over one of your systems, such as list_cases, get_case or search_mail, so the assistant can look things up and act directly instead of you copying data into the chat and the answer back out. MCP, the Model Context Protocol, is the open standard that assistants such as Claude use to discover and call those tools. For a small business, the question is not whether MCP is interesting. It is which of your systems you keep copy-pasting between, and how little access you can give an assistant while still saving that work.

The copy-paste problem

Without tools, working with an assistant on your own data goes like this: open the admin, copy a table, paste it into the chat, ask a question, copy the answer, paste it back. You are the courier, and couriers make mistakes. They paste yesterday's export or half a table, and nobody records what was actually looked at.

With an MCP server, the assistant calls sales_cases_list(status: "in_review") itself and gets the current answer. The server decides what the call may return and logs that it happened. Our Academy lesson Tools, not copy-pasted JSON builds this step by step on Cloudflare.

Our example: the Sales Desk server

Our sales enquiries are tracked on a small board we call the Sales Desk: a Cloudflare Worker with a D1 database behind it. Several consumers needed the same data: an AI agent that writes operating standards, coding agents working on the board itself, and in future an agent that helps with sales. Wiring each of them to bespoke endpoints would have meant a different integration for each. So the board also answers as an MCP server, with JSON-RPC 2.0 over a single POST /mcp endpoint.

The first round exposed four tools, all read-only:

  • sales_stats: counts by status, so an agent can see the shape of the queue.
  • sales_cases_list: cases filtered by status.
  • sales_case_get: one case with its timeline of events.
  • sales_merge_preview: what merging two cases would produce. It changes nothing.

The mail tools came later: mail_search, mail_archive (reversible) and mail_draft (creates a draft in a thread). There is no tool to send, and the source code says in a comment that there must never be one. Sending and permanent deletion stay with a person in a logged-in session.

Why the first round is read-only

Read-only tools are useful from the first day: answering "what is waiting, and since when?" already saves real time. And they cannot do damage. A read-only round shows you how assistants actually use the tools: which ones they call, how often, with what arguments, and where the descriptions mislead them. That is the information you need before you design write tools.

When we did add actions, we added them in order of reversibility. Archiving a message is undoable. Writing a draft is undoable. Sending is not, so it is not a tool. The rule is the same one we apply to agents generally, described in What is an AI agent?: act freely on what can be undone, gate what cannot.

One server, the variable part as a parameter

When we added mail tools, the first idea was a server per mailbox. We chose one server with the mailbox as a parameter instead. A server per account means two tokens, two configurations, two sets of documentation and two places where things drift apart. An account is data, not architecture. If an agent asks for a mailbox the server does not know, the tool answers with the list of available ones instead of failing silently.

We also kept the runtime where the credentials are. The Gmail authorisation lives in n8n, and the Worker is only a front. The MCP server never holds a mail password or token, so leaking the server's code would leak nothing that opens a mailbox.

OAuth or a bearer token

There are two kinds of caller, and they deserve different doors:

  • Assistants used by people, such as a chat app connecting to your server on someone's behalf. Use OAuth: the person approves a scoped grant, and you can revoke it for that person alone without touching anyone else.
  • Your own agents and scripts. A static bearer token sent in the Authorization header is simpler and good enough, provided it is stored in a secrets vault, never in a repository, and can be rotated.

Our Sales Desk server uses a bearer token, because its consumers are our own agents. It is a machine credential, kept separate from the PIN login people use for the admin. Whatever the door, both should arrive at the same permission check, which is the point of the Academy lesson Two doors, one room.

Designing tools that assistants use well

  • Name tools by intent: sales_cases_list, not query. The assistant chooses tools by name and description.
  • Describe limits in the description: "reversible", "does not send", "returns at most 50".
  • Return facts, not conclusions. "Last mail sent to this customer at 14:02" is a fact. "Case answered" is an inference, and inferences belong to whoever acts on them.
  • Fail helpfully: an unknown mailbox returns the list of known ones, and a missing argument says which one is missing.
  • Redact by default. If a public endpoint must exist, it returns real but redacted data. The Academy lesson Functions as an API shows the public/private split.

Where to start

Pick the one internal system you copy from most often. Write three read-only tools for it. Connect your assistant and use them for two weeks before adding anything that writes. If that sounds like more than an afternoon's work, it is the kind of thing we build for clients, and if you would rather learn it, the Academy lessons above walk through the same steps.

Frequently asked questions

What is an MCP server?

A small service that exposes a list of named tools, each with a description and typed inputs, over the Model Context Protocol. An AI assistant that supports MCP can discover the tools and call them on your behalf.

Does a small business need its own MCP server?

Only if people keep copying data between an AI assistant and your own systems. For mainstream apps, ready-made connectors often exist. Your own server is worth it for your own database, board or internal tool.

Is it safe to connect an AI assistant to company data?

It can be, if the server decides what is possible. Start with read-only tools, give each consumer its own revocable credential, and never expose a tool for an action that must stay with a person, such as sending or deleting.

OAuth or an API token?

OAuth for third-party assistants used by people, because the grant is scoped and can be revoked per user. A static bearer token for your own agents and scripts, kept in a secrets store. Both should end at the same permission check.

Written from our own production systems. Drafted with AI assistance and reviewed by Kamil Hrbáček.

Want this running in your company?

Flowsmith designs and operates automations like this for small and mid-sized teams — with a person approving anything that leaves the building.

More from the blog