The Track
Phase 4 of 4·0% complete

Open It Up

Connect Claude to Your Site with an OAuth MCP Server

Give an AI assistant secure, authenticated hands on your own project.

You build

An AI connector to your site.

Core concept

Agents, tools, MCP, OAuth.

For the finale, you'll build a remote MCP server — protected by OAuth — and deploy it alongside your site on Cloud Run. Once it's connected, you can open Claude or Codex and say “pull my latest projects” or “post this new blog entry to my site,” and the assistant does it through your server, acting as you.

MCP (Model Context Protocol) is an open standard from Anthropic for connecting an AI to external tools and data in a uniform way. Think of it as a universal socket: your server exposes tools (like list_projects or create_post), and any MCP-capable assistant can plug in and call them through plain conversation.

Why it matters in industry

The frontier is AI that doesn't just talk but acts — querying systems, taking actions. MCP is becoming the standard way to connect assistants to tools, and engineers who can build MCP servers are still a small minority. It's a genuine differentiator.

Example — A company exposes its internal tools through an MCP server so employees can ask an assistant to “pull last week's numbers and draft the update” — securely, behind OAuth. You'll build a small version that lets Claude post and pull content on your own site.

The Current Standard

What Claude expects (verify as you go)

MCP's transport and auth have evolved quickly, so build against the current spec and expect it to keep moving. A remote server that Claude can connect to needs: Streamable HTTP transport (the older HTTP+SSE is deprecated); OAuth 2.1 + PKCE; Dynamic Client Registration (so Claude can register itself as a client); discovery metadata (the RFC-standard endpoints Claude probes); and a 401 that points to your auth server.

Don't hand-roll all of OAuth. Two saner paths: put an identity provider (Auth0, Okta, or Google Identity) in front and have your server validate its tokens; or use a hosting platform with built-in MCP OAuth management. Either way, your tool logic stays simple and the auth heavy lifting is handled by something battle-tested.

Step 1 · Define Tools

Write the MCP server and its tools

Use the official MCP SDK (TypeScript or Python). Each tool is a named function with a described input schema — the description is how the model knows when to call it, so write it well. Notice these tools reuse your Phase 3 database: the MCP server is a thin, authenticated doorway onto work you already built.

▸ Ask Claude

Scaffold a remote MCP server using the official SDK with two tools: list_projects (reads from my Cloud SQL database) and create_post (writes a new post to it). Explain how MCP tools and their input schemas work, and why the tool description matters.

Terminal — install the MCP SDK
npm install @modelcontextprotocol/sdk zod
server.ts (TypeScript SDK)
server.tool(
  'list_projects',
  'List the projects shown on my portfolio site.',
  {},
  async () => ({ content: [{ type: 'text',
    text: JSON.stringify(await db.getProjects()) }] })
);

server.tool(
  'create_post',
  'Publish a new blog post to my site.',
  { title: z.string(), body: z.string() },
  async ({ title, body }) => {
    await db.insertPost({ title, body });   // reuses your Phase 3 DB
    return { content: [{ type: 'text', text: 'Published.' }] };
  }
);

Step 2 · Protect It

Add OAuth in front of the tools

Wrap the server so every tool call must carry a valid access token. The flow: Claude hits your server unauthenticated and gets a 401 that advertises your auth server; Claude registers as a client (DCR) and redirects you to sign in; you approve in the provider's own screen; Claude receives a short-lived token (with PKCE) and calls your tools, which validate it on every request.

OAuth-protected MCP tool call

1 · Claude calls server

unauthenticated → 401

2 · You sign in

provider · OAuth 2.1 + PKCE

3 · Short-lived token

issued to Claude

4 · Tool call + token

server validates → DB

Every tool call must carry a valid, short-lived token. The moment your server can change your site, OAuth verifies who's calling — with no password or long-lived token pasted into Claude.

▸ Ask Claude

Add OAuth 2.1 with PKCE and Dynamic Client Registration to my MCP server over Streamable HTTP, so every tool call requires a valid token. I'd like to use [an identity provider like Auth0/Google Identity] rather than hand-rolling it. Walk me through the flow and check it against Anthropic's current custom-connector requirements.

Why OAuth is non-negotiable here

A read-only public endpoint might not need auth. The moment your server can change your site, it must verify who's calling. OAuth is how the assistant proves it's acting for you, without you ever pasting a password or long-lived token into it.

Step 3 · Deploy & Connect

Ship it and plug Claude in

Deploy the MCP server to Cloud Run as a second service (same Terraform + PR-merge pattern as your site). Register your provider's OAuth callback URLs, including Claude's callback — missing callback URLs are the most common reason connections fail. Then in Claude: Settings → Connectors → Add custom connector, paste your server URL, click Connect, and complete the OAuth sign-in. Your tools appear.

▸ Ask Claude

Containerize my MCP server, add it to /terraform as a second Cloud Run service, and wire it into the deploy pipeline. Branch, PR, and merge so it deploys. Give me its public URL.

Terminal — debug the OAuth flow locally first
npx @modelcontextprotocol/inspector   # walks auth + calls your tools

Test with the Inspector first

Before wiring into Claude, debug locally with the MCP Inspector — it walks the OAuth flow and calls your tools so you can confirm everything works in isolation. Connecting to Claude is much smoother once the Inspector is green.

Safety: you're giving an AI write access to your site

Scope tokens to the minimum. Keep destructive tools (delete) out, or require confirmation. Log every tool call. Rate-limit. Treat anything the model sends as untrusted input, and validate it before it touches your database. This is real production security thinking — exactly the kind of judgment the role is about.

Where To Take It Next

AI features to build into this project

You now own every layer — site, model, retrieval, and an authenticated AI doorway. Features that build naturally on that, roughly easiest to most ambitious: recruiter-tuned summaries; “chat with my work” over all your documents with citations; a self-updating site via MCP (your CMS becomes a conversation); auto-drafted blog posts; semantic project search; a contact-triage agent; an eval harness that scores your RAG answers against known-good Q&A pairs; and a multi-step agent given several tools and a goal.

The through-line: every one of these is the same loop — describe, build, verify, ship — applied to a new problem, on infrastructure you own. That loop, plus the judgment to secure and evaluate what you build, is AI engineering. You've now done it end to end.

Done when

  • An MCP server exposing pull and post tools over your Phase 3 data.
  • OAuth 2.1 + PKCE + DCR over Streamable HTTP, via a provider or platform.
  • Deployed to Cloud Run with the Phase 1 pipeline; callback URLs registered.
  • Connected to Claude/Codex and driving your site by conversation.
  • Least-privilege scoping, logging, and validation on every tool.
Knowledge Check

1.Why must a write-capable MCP server sit behind OAuth?

2.What is the most common reason a Claude ↔ MCP connection fails?

3.How should you treat input the model sends to your write tools?

Answer every question correctly to complete this phase.