How to build an MCP server
A small typed server that exposes tools your assistants may call. Official SDK shape, then the policy that keeps production data out of the prompt.

Direct answer
What an MCP server is
Model Context Protocol is the socket between an AI host (Claude, Cursor, ChatGPT-compatible clients, or your own agent) and tools you control. The server exposes tools, resources, and prompts. The host calls those tools. Credentials stay on the server. The model sees names and sanitized results, not raw keys.
Written by Zack Shields. Last updated .
Key facts
- MCP servers expose tools, resources, and prompts to a host
- Official TypeScript package in current docs: @modelcontextprotocol/server plus zod
- STDIO servers must not write logs to stdout. Use stderr
- Start with a few job-shaped tools, not a dump of your whole API
- Hire a developer when auth, writes, or an audit log are in scope
Architecture in one pass
A host starts your server (often over STDIO for desktop, or HTTP for remote). The server advertises tools. The model picks a tool. Your handler runs, talks to your system, and returns text or structured data.
Three capability types, from the official docs: tools (functions the model may call), resources (readable data), and prompts (templates). First servers are almost all tools.
Steps
- 1. Name the jobsList the questions staff already paste into chat. Those names become tools: lookup_account, list_open_tickets, draft_from_sop.
- 2. Install the official SDKCurrent TypeScript tutorial installs @modelcontextprotocol/server and zod, Node 20 or newer. Python tutorial uses the official Python MCP SDK.
- 3. Register tools with a schemaEach tool gets a description and an input schema. Keep tools read-only until you have a confirmation path for writes.
- 4. Keep secrets on the serverThe handler calls your API with a key from your secret store. The model never sees the key.
- 5. Connect a hostClaude Desktop and Cursor read a config that launches the server. Restart the host after you change the config.
- 6. Log on stderr, test a real lookupOn STDIO, console.log breaks the protocol. Use console.error. Then call the tool from the host and read the log.
Short TypeScript example
Shape taken from the official "Build an MCP server" TypeScript tutorial (McpServer, registerTool, serveStdio). lookupAccount is your function. Do not copy a weather demo into production and point it at a CRM.
import { McpServer } from "@modelcontextprotocol/server";
import { serveStdio } from "@modelcontextprotocol/server/stdio";
import { z } from "zod";
function createServer() {
const server = new McpServer({
name: "account-lookup",
version: "1.0.0",
});
server.registerTool(
"lookup_account",
{
description: "Look up one account by id. Read only.",
inputSchema: z.object({
accountId: z.string().describe("Account id in your CRM"),
}),
},
async ({ accountId }) => {
const account = await lookupAccount(accountId);
return {
content: [{ type: "text", text: JSON.stringify(account) }],
};
},
);
return server;
}
await serveStdio(createServer);Based on the official TypeScript tutorial at modelcontextprotocol.io. The tutorial uses a factory because serveStdio may construct more than one instance.
Workflow review
A weekend weather demo is not a production MCP server.
Auth, scopes, and a log you can read. Book a consult and list the lookups staff already paste into chat.
Security considerations
- Least privilegeOne tool, one job. lookup_account is safer than query_anything.
- No secrets in the promptKeys, tokens, and connection strings stay in the server environment.
- Validate inputsTrust the schema, then check ids against your own allow-list before you hit production.
- Writes need a fenceConfirm, allow-list fields, or require a human. Assistants are eager.
- Log principal, tool, arguments, redacted resultIf a write goes wrong, you need the run, not a chat scrollback.
- STDIO hygieneNever print to stdout on a STDIO server. Official docs are explicit on this.
When to hire a developer
- You need SSO, per-user scopes, or a remote HTTP transport instead of a laptop STDIO process.
- Write tools will touch customers, money, or tickets.
- Several hosts (Claude, Cursor, a night agent) must share one contract.
Production MCP with auth, scopes, and an audit log is the MCP servers engagement.

FAQ
Frequently asked questions
Short, direct answers. Ask me anything else on the call.
What is an MCP server?
A process that exposes tools, resources, and prompts to an AI host over Model Context Protocol. The host is Claude, Cursor, or your own agent. The server holds credentials and runs the calls.Should I use TypeScript or Python?
Use the language your team already ships. Official docs cover both. The TypeScript tutorial currently installs @modelcontextprotocol/server. The Python tutorial installs the official Python MCP SDK. The protocol is the same.Why do people hire an MCP developer instead of following the tutorial?
The protocol is straightforward. Production risk is not. Auth, narrow writes, host install, and a log you can query are the consulting job. A weekend demo pointed at production is worse than no MCP.Does this replace n8n or Zapier?
No. MCP is how assistants call tools during a chat or an agent turn. n8n and Zapier still run the deterministic pipes. Many teams use both.
Book a consult
Book a consult
Tell me which lookups staff still paste into chat. I reply within one business day.
- Quote
- Written
- Length
- 30 min
- Pressure
- None
