Serve Resources Well from an MCP Server on macOS

Resources are the read side of MCP: addressable, cacheable data a client fetches by URI, separate from the tools that take action. Serving them well means more than returning a string. A resource has a MIME type, metadata a client shows in a picker, a choice between a fixed URI and a parameterized template, a text-or-binary body, and, for data that changes, a way to push updates instead of making clients poll. ...

12 min

Design MCP Prompts: Arguments, Templates, and Embedded Resources on macOS

Tools let a model do things; prompts let a user start things. An MCP prompt is a named, parameterized message template a client surfaces as a slash command or a menu entry — the user picks it, fills in a couple of arguments, and the client drops a ready-made conversation into the model. Most tutorials define one prompt in passing and move on. This one treats prompts as the subject. ...

11 min

Add Argument Completions to an MCP Server on macOS

When a user fills in a prompt argument or a resource URI in an MCP client, the client can offer autocomplete, the same way a shell completes a path. That only works if the server answers a completion/complete request with suggestions scoped to what the user has typed. Without it, the user guesses at valid values and finds out they were wrong only when the call fails. This tutorial adds completions to a small documentation server built with FastMCP. One handler serves suggestions for a prompt’s arguments and a resource template’s parameters, filters by the typed prefix, reads from the same data the server actually serves, and narrows one argument based on another (topics depend on the chosen language). The stack is Mac-native: uv, make, and pytest. ...

12 min

Build a Dynamic MCP Server: Notifications and Resource Templates on macOS

Most MCP servers are static: a fixed set of tools and resources, decided at startup. Two features let a server change shape at runtime. Resource templates serve a whole family of resources from one parameterized URI, so book://1, book://2, and book://999 all resolve without registering a resource per book. list_changed notifications let the server tell a connected client that its tools, resources, or prompts have changed, so the client re-fetches instead of holding a stale list. ...

14 min

Design Great MCP Tools: Annotations and Semantics on macOS

A working MCP tool is not the same as a well-designed one. A model decides whether to call your tool, and a client decides whether to auto-run it or ask the user first, based entirely on what the tool says about itself: its name, its description, its parameters, and its annotations. Get those wrong and a read-only lookup gets a confirmation prompt, a destructive delete runs silently, or the model picks the wrong tool. ...

16 min

Return Structured Output from a FastMCP Server on macOS

A tool that returns only text makes every caller re-parse prose. The model reads "Denver is 21.5°C and clear" and has to extract the number again; a program has to write a regex. MCP’s structured output fixes this: a tool returns typed JSON in a structuredContent field, and advertises the shape up front as an output schema so callers know what to expect before they ever call it. This tutorial builds a small weather server with FastMCP whose tools return a Pydantic model, a nested collection, a bare primitive, and a hand-built result. You will see how FastMCP derives the output schema from a return-type annotation, fills in structuredContent automatically, validates every result against the schema, and how a client reads the typed value back. The stack is Mac-native: uv, make, and pytest. ...

16 min

Use Your MCP Server from VS Code, Cursor, and Zed on macOS

Register a FastMCP Server with Claude Desktop and Claude Code wired a server into the two Claude clients. The AI-assisted code editors speak MCP too — VS Code (Copilot agent mode), Cursor, and Zed — and each keeps its config in a different file, under a different key, in a slightly different shape. This article takes one stdio FastMCP server and connects it to all three. VS Code Cursor Zed File .vscode/mcp.json (or user config) .cursor/mcp.json (or ~/.cursor/mcp.json) ~/.config/zed/settings.json Top-level key servers mcpServers context_servers Entry shape type + command/args (or url) command/args (or url) command/args/env (or url/headers) Scope workspace and user project and global global only Two things are common to all three, and to the Claude clients before them: ...

10 min

Publish a FastMCP Server to PyPI and Run It Anywhere with uvx

Two earlier articles bookend this one. Package and Distribute a FastMCP Server as a uvx Tool gets you to uvx macmcp in your own terminal, and Register a FastMCP Server with Claude Desktop and Claude Code wires a server into clients, but launches it from a local path or git+https. This closes the loop: publish the package to PyPI once, and from then on anyone — and any MCP client — runs it with uvx <name>, no clone, no virtualenv, no path. ...

12 min

Build an MCP Server in Go with the Official SDK

This is the Go companion to Build an MCP Server in TypeScript with the Official SDK. It builds the same kind of server — two tools and a resource — with the official Go SDK (github.com/modelcontextprotocol/go-sdk), served over the stdio transport so a local client launches it as a subprocess. The result is a single compiled binary with no runtime beyond itself. The project uses the cmd/ + internal/ layout, a Makefile, and Go’s built-in testing. ...

13 min

Build an MCP Server in TypeScript with the Official SDK

The FastMCP tutorials in this series are Python, and FastMCP wraps the Model Context Protocol so you rarely touch it directly. This article drops down a level and builds the same kind of server with the official TypeScript SDK (@modelcontextprotocol/sdk) — the reference implementation Anthropic maintains. You register tools and resources on an McpServer, connect it to the stdio transport, and a local client launches it as a subprocess. The stack is Node, tsc, and vitest. ...

12 min