Deep dive
Build an MCP server three ways: local stdio, over HTTP, then with OAuth and per-user scopes
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.
"MCP Servers Explained & Built" by Tech With Tim — Watch on YouTube →
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
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
/mcppath. - 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. Adding tools to an agent: Hermes MCP tools.





