MCP Servers — Real-World Examples
MCP (Model Context Protocol) gives Claude access to external systems. Without MCP, Claude can only use built-in tools. With MCP, Claude can create GitHub issues, run browser tests, query your database, send Slack messages, and more.
How MCP Works
Section titled “How MCP Works”Claude wants to create a GitHub issue │ ▼Claude calls: mcp__github__create_issue({ title: "...", body: "..." }) │ ▼MCP client sends request to GitHub MCP server │ ▼GitHub MCP server calls GitHub REST API │ ▼Returns: { issue_number: 247, url: "https://github.com/..." } │ ▼Claude sees the result and continuesYou configure the servers; Claude discovers what tools they provide automatically.
MCP Server 1: Playwright (Browser Automation)
Section titled “MCP Server 1: Playwright (Browser Automation)”Use case: Claude can take screenshots, fill forms, click buttons, scrape pages.
claude mcp add playwright -- npx -y @playwright/mcp@latestThis writes to .mcp.json:
{ "mcpServers": { "playwright": { "type": "stdio", "command": "npx", "args": ["-y", "@playwright/mcp@latest"] } }}Real Example 1: Test a UI flow
Section titled “Real Example 1: Test a UI flow”You say:
Test the login flow — go to localhost:3000, log in with test@example.com / password123,and verify the dashboard loads correctlyClaude does (using Playwright MCP tools):
mcp__playwright__navigate({ url: "http://localhost:3000" })mcp__playwright__screenshot({ name: "homepage" })mcp__playwright__fill({ selector: "#email", value: "test@example.com" })mcp__playwright__fill({ selector: "#password", value: "password123" })mcp__playwright__click({ selector: "[type=submit]" })mcp__playwright__screenshot({ name: "after-login" })mcp__playwright__assert({ selector: ".dashboard", state: "visible" })Reports back with screenshots and pass/fail status.
Real Example 2: Scrape competitor pricing
Section titled “Real Example 2: Scrape competitor pricing”You say:
Check the current pricing on our competitor's website and summarize itClaude does:
mcp__playwright__navigate({ url: "https://competitor.com/pricing" })mcp__playwright__get_text({ selector: ".pricing-table" })Real Example 3: Debug a visual regression
Section titled “Real Example 3: Debug a visual regression”You say:
The checkout button is invisible on mobile — screenshot it on a 375px viewportClaude does:
mcp__playwright__set_viewport({ width: 375, height: 812 })mcp__playwright__navigate({ url: "http://localhost:3000/checkout" })mcp__playwright__screenshot({ name: "mobile-checkout", fullPage: true })MCP Server 2: GitHub
Section titled “MCP Server 2: GitHub”Use case: Claude can read/create issues, review PRs, manage repos.
claude mcp add --transport http github https://api.github.com/mcpAuthenticate:
/mcp# Select "github" → Authenticate# Follow OAuth flow in browserReal Example 1: Create issues from code
Section titled “Real Example 1: Create issues from code”You say:
Find all TODO comments in the codebase and create GitHub issues for each oneClaude does:
Grep("TODO:", "src/**/*.ts")→ Finds: src/services/payment.ts:47: TODO: handle webhook retries src/api/users.ts:23: TODO: add rate limiting src/utils/email.ts:8: TODO: use queue instead of direct send
mcp__github__create_issue({ title: "Handle webhook retries in payment service", body: "Located in src/services/payment.ts:47\n\nNeed to implement retry logic...", labels: ["enhancement"]})# × 3 for each TODOReal Example 2: Review a PR before merging
Section titled “Real Example 2: Review a PR before merging”You say:
Review PR #247 — focus on security and missing testsClaude does:
mcp__github__get_pull_request({ pull_number: 247 })mcp__github__list_pull_request_files({ pull_number: 247 })mcp__github__get_pull_request_diff({ pull_number: 247 })Then reviews the diff and posts comments:
mcp__github__create_review({ pull_number: 247, event: "REQUEST_CHANGES", comments: [ { path: "src/auth.ts", line: 34, body: "Missing auth check — any user can access this endpoint" }, { path: "src/payment.ts", line: 78, body: "No test coverage for the refund path" } ]})Real Example 3: Automate release notes
Section titled “Real Example 3: Automate release notes”You say:
Generate release notes for the v2.1.0 release based on merged PRs since v2.0.0Claude does:
mcp__github__list_pull_requests({ state: "closed", base: "main" })# Filters by merged_at date since v2.0.0 tagmcp__github__get_pull_request({ pull_number: each })# Builds categorized changelog: features, fixes, breaking changesMCP Server 3: PostgreSQL / Databases
Section titled “MCP Server 3: PostgreSQL / Databases”Use case: Claude can query your database directly — analyze data, write migrations, debug queries.
claude mcp add pg -- npx -y @modelcontextprotocol/server-postgres \ postgresql://localhost/myappOr with credentials:
{ "mcpServers": { "db": { "type": "stdio", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://user:pass@localhost/myapp"] } }}Real Example 1: Debug a production data issue
Section titled “Real Example 1: Debug a production data issue”You say:
Users are complaining they can't see their recent orders. Debug the query.Claude does:
mcp__db__query({ sql: "SELECT * FROM orders WHERE user_id = 'test-uuid' ORDER BY created_at DESC LIMIT 10" })mcp__db__query({ sql: "EXPLAIN ANALYZE SELECT * FROM orders WHERE user_id = 'test-uuid'" })Finds: missing index on user_id causing full table scan. Suggests and generates the migration.
Real Example 2: Analyze data before a migration
Section titled “Real Example 2: Analyze data before a migration”You say:
I want to add a NOT NULL constraint to the email column — will it break anything?Claude does:
mcp__db__query({ sql: "SELECT COUNT(*) FROM users WHERE email IS NULL" })mcp__db__query({ sql: "SELECT id, created_at FROM users WHERE email IS NULL LIMIT 5" })Reports: “23 rows have NULL email. Here’s how to handle them before adding the constraint.”
Real Example 3: Generate TypeScript types from schema
Section titled “Real Example 3: Generate TypeScript types from schema”You say:
Generate TypeScript interfaces for all the database tablesClaude does:
mcp__db__query({ sql: "SELECT table_name, column_name, data_type, is_nullable FROM information_schema.columns WHERE table_schema = 'public' ORDER BY table_name, ordinal_position" })Generates complete TypeScript interfaces matching the actual DB schema.
MCP Server 4: Filesystem (Extended Access)
Section titled “MCP Server 4: Filesystem (Extended Access)”Use case: Grant Claude access to directories outside the current project.
claude mcp add fs -- npx -y @modelcontextprotocol/server-filesystem \ /Users/you/shared-lib \ /Users/you/design-tokensReal Example
Section titled “Real Example”You say:
Update our design tokens to match the shared design system in ~/design-tokensClaude does:
mcp__fs__read_file({ path: "/Users/you/design-tokens/colors.json" })mcp__fs__read_file({ path: "/Users/you/design-tokens/spacing.json" })Read("src/styles/tokens.css")Edit("src/styles/tokens.css", ...) ← updates to match shared tokensMCP Server 5: Slack
Section titled “MCP Server 5: Slack”Use case: Claude can send messages, search channels, notify the team.
claude mcp add --transport http slack https://slack.com/mcp# Authenticate via /mcp → AuthenticateReal Example 1: Notify on deploy
Section titled “Real Example 1: Notify on deploy”.claude/skills/deploy/SKILL.md with Slack:
# Deploy to $ARGUMENTS
...deploy steps...
## Notify teamAfter successful deployment:mcp__slack__post_message({ channel: "#deployments", text: "🚀 Deployed to $ARGUMENTS — commit $(git rev-parse --short HEAD) by $(git config user.name)"})Real Example 2: Alert on test failures
Section titled “Real Example 2: Alert on test failures”When tests fail in CI, search #alerts in Slack for any related recent issuesmcp__slack__search({ query: "payment test failure", count: 5 })MCP Server 6: Sentry (Error Tracking)
Section titled “MCP Server 6: Sentry (Error Tracking)”Use case: Claude can read production errors directly.
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp# Authenticate via /mcp → AuthenticateReal Example
Section titled “Real Example”You say:
What are the top 3 errors in production this week? Fix the most impactful one.Claude does:
mcp__sentry__list_issues({ environment: "production", limit: 10, sort: "events" })→ Returns: Error list with counts
mcp__sentry__get_issue({ issue_id: "PAYMENTS-4821" })→ Returns: Full stack trace, affected users, example events
Read("src/services/payment.ts") ← find the relevant codeEdit("src/services/payment.ts", ...) ← fix the bugBuilding Your Own MCP Server
Section titled “Building Your Own MCP Server”For internal tools, databases, or APIs without an existing server.
Minimal Node.js MCP server:
import { Server } from "@modelcontextprotocol/sdk/server/index.js";import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server({ name: "my-tools", version: "1.0.0" }, { capabilities: { tools: {} }});
server.setRequestHandler("tools/list", async () => ({ tools: [{ name: "get_feature_flags", description: "Get all feature flags and their current values", inputSchema: { type: "object", properties: {}, required: [] } }]}));
server.setRequestHandler("tools/call", async (request) => { if (request.params.name === "get_feature_flags") { const flags = await db.query("SELECT * FROM feature_flags"); return { content: [{ type: "text", text: JSON.stringify(flags) }] }; }});
const transport = new StdioServerTransport();await server.connect(transport);Register it:
{ "mcpServers": { "my-tools": { "type": "stdio", "command": "node", "args": ["my-mcp-server/index.js"] } }}Now Claude can call mcp__my-tools__get_feature_flags directly.
MCP Permission Rules
Section titled “MCP Permission Rules”Control exactly which MCP tools Claude can use:
{ "permissions": { "allow": [ "mcp__playwright__*", // all playwright tools "mcp__github__get_*", // github read-only "mcp__github__list_*", "mcp__db__query" // db queries only ], "deny": [ "mcp__github__delete_*", // no deleting "mcp__db__execute", // no writes to db "mcp__slack__*" // no slack in this project ] }}🧠 Quick Recall
Section titled “🧠 Quick Recall”- Trick: “Connect what the team already uses — value on day one.”
👨🏫 Teach It
Section titled “👨🏫 Teach It”- Do: wire up one server your team actually needs (DB, GitHub, Slack).
- They’ll trip on: hardcoding credentials — use env-var references in config.
Learning path: ⬅ 25-mcp-servers.md · Index · ➡ 27-plugins.md
Written by Fenil Patel