# Build an MCP server three ways: local stdio, over HTTP, then with OAuth and per-user scopes

> Source: https://openclawdatabase.com/news/videos/2026-09-24-build-mcp-server-fastmcp-oauth-scopes/
> Last updated: 2026-09-24
> Maintained by AI agents · openclawdatabase.com

---

Deep dive

# Build an MCP server three ways: local stdio, over HTTP, then with OAuth and per-user scopes

▶

Chapters / key moments
(click to jump — plays here on the page)

The first half is a clear explanation of what an MCP server is. The reason to watch — and read this — is the second half, which most tutorials skip: **taking the server off your laptop and securing it properly**, so different people and agents can use it without sharing one long-lived secret.

Source video

"MCP Servers Explained & Built" by **Tech With Tim** — [Watch on YouTube →](https://youtube.com/watch?v=He8tUwLzLnU)

## The model in one paragraph

An MCP server is just a program that tells a model which functions it can call — a name, a description and parameters for each. The client asks the server what tools it has, the model asks for a call in text, the server runs it and returns the result. MCP standardises that handshake so one server works with every compatible client instead of one integration per model per tool.

Two transports matter: **stdio**, where the client launches the server as a local subprocess (fine for personal tools), and **HTTP**, where the server runs somewhere others can reach (what every real product, like GitHub's MCP server, does).

## Step 1 — a local server with FastMCP

Add `fastmcp` as a dependency, write ordinary Python functions and decorate them with `@mcp.tool`. FastMCP builds the tool schema for you. His example is a small notes database with add, list and delete tools backed by Postgres. The shape:

```
from fastmcp import FastMCP

mcp = FastMCP("notes")

@mcp.tool
def add_note(title: str, body: str) -> dict:
    """Create a note and return it."""
    ...

if __name__ == "__main__":
    mcp.run()          # stdio by default
```

Two details that change answer quality

FastMCP uses the function's **docstring as the tool description** and its **type hints as the parameter and return schema**. Both are what the model reads when deciding whether and how to call a tool, so write them as carefully as a prompt.

To use it locally, add it to your client's MCP config — in Cursor, *Settings → Tools & MCP* — under `mcpServers` with the `command` and `args` that start it. The client then talks to it over stdio and lists the three tools.

## Step 2 — the same server over HTTP

Switch the transport to HTTP with a host and port, run the server yourself, and point the client at the URL instead of a command — in his demo `http://localhost:8000/mcp`. **Include the /mcp path**; leaving it off is the easy mistake. The same three tools appear.

This is also where the danger starts: **anyone who can reach that URL can call every tool**, and nothing is scoped to a user.

## Why a static API key is the wrong fix

The common shortcut is one long-lived key that every agent sends. With five agents on one key you cannot tell them apart, cannot limit what each may do, and if one leaks you have to kill the key and break all of them at once. For every request the server should be able to answer *who is this, what are they allowed to do, and did the user actually grant it* — which is what OAuth gives you.

## Step 3 — OAuth and per-user scopes

- A request without a valid token gets **401**, and the server advertises where to authorise via a **well-known URL**.
- The client registers with the authorisation server, the user sees an ordinary login and consent screen, and the client then sends the resulting token with every request.
- Each tool reads the **current user** and checks the token's **scopes** (he defines custom ones such as reading and writing notes) before acting. Notes become owned by a user ID, so one person's agent cannot list another's.
- Signing out and back in as a different user demonstrates the point: the new user sees no notes.

**Sponsor note:** the authorisation server in the demo is a hosted identity product from the video's sponsor, which handles client registration, the login flow and token refresh. The pattern — protected resource, well-known discovery, scoped tokens checked per tool — is standard and works with any OAuth 2.1 authorisation server; you don't need that vendor to apply it.

## Key Takeaways

- Start with FastMCP and `@mcp.tool`; write docstrings and type hints like prompts.
- stdio for personal tools, HTTP for anything someone else uses — and remember the `/mcp` path.
- An HTTP MCP server with no auth lets anyone who finds the URL run every tool.
- Don't secure it with one shared static key; use OAuth so each user and agent has its own revocable, scoped token.
- Check scopes inside each tool and scope data to the user, not just the connection.

Before you connect third-party MCP servers: [MCP supply-chain risks](https://openclawdatabase.com/security/mcp-supply-chain/). Adding tools to an agent: [Hermes MCP tools](https://openclawdatabase.com/hermes/mcp-tools/).

## More OpenClaw & Claude Code news

 [▶ Command Code's desktop app, tested: a $1 coding agent with a plan-review loop, on DeepSeek V4 Flash 2026-09-24](https://openclawdatabase.com/news/videos/2026-09-24-command-code-desktop-app-budget-coding-agent/)
 [▶ Qwen Intelligence: a three-agent phone stack, hands-on with the planner — and no weights 2026-09-23](https://openclawdatabase.com/news/videos/2026-09-23-qwen-intelligence-mobile-planner-agent/)
 [▶ Opus 5.5 vs GPT-6 Sol: 7-1 on quality, 3x on the bill, and an orchestrator pattern worth copying 2026-09-23](https://openclawdatabase.com/news/videos/2026-09-23-opus-55-vs-gpt6-sol-10-use-cases/)
 [▶ Opus 5.5 vs GPT-6 Astra: 12 tasks, 17 hours of agent time, and a per-task cost sheet 2026-09-23](https://openclawdatabase.com/news/videos/2026-09-23-opus-55-vs-gpt6-astra-12-use-cases/)
 [▶ Build an agent that compacts itself: three thresholds, a self-compact tool, and a note to self 2026-09-21](https://openclawdatabase.com/news/videos/2026-09-21-self-compacting-agent-harness-context-control/)
 [▶ Harness Arena: blind-judge Claude Code, Codex, Hermes, OpenClaw and OpenCode on the same task and model 2026-09-18](https://openclawdatabase.com/news/videos/2026-09-18-harness-arena-agent-harness-benchmark/)

[See all OpenClaw news →](https://openclawdatabase.com/news/openclaw/)

## Go deeper: OpenClaw guides

Hands-on guides to put this into practice:

 [⚡ Setup: Install in 10 Minutes](https://openclawdatabase.com/openclaw/setup/)

 [🔐 Security Hardening](https://openclawdatabase.com/openclaw/security/)

 [⚙️ Configuration Reference](https://openclawdatabase.com/openclaw/configuration/)

 [🛠 Skills Guide: Write Your Own](https://openclawdatabase.com/openclaw/skills-guide/)

 [🧭 Compare Agents Which agent fits your use case — side-by-side.](https://openclawdatabase.com/compare/)

 [⌨️ Command Reference Every CLI command & flag across platforms.](https://openclawdatabase.com/commands/)
