Engineer
35 minutes
linux
macos
windows

MCP + Skills Architecture and Local Demo

Understand Model Context Protocol (MCP) and implement local tool integrations for AI assistants.

What you'll accomplish

Understand MCP architecture and create a simple local MCP server.

Prerequisites

  • Completed lessons 1-3
  • Node.js 18+ installed
  • Understanding of REST APIs

What is MCP?

Model Context Protocol (MCP) is an open protocol that lets AI assistants connect to external tools and data sources through a standardized interface.

Think of it like:

  • USB for AI - A standard way to plug in capabilities
  • APIs for LLMs - Structured access to external systems
Note

MCP is developed by Anthropic but is an open standard. It's supported by Claude and increasingly by other AI tools.

MCP Architecture

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   AI Host   │────▶│ MCP Server  │────▶│  Resource   │
│  (Claude)   │◀────│  (Bridge)   │◀────│ (Database)  │
└─────────────┘     └─────────────┘     └─────────────┘
       │                   │
       │     Protocol      │     Native
       └───────────────────┘     Access

Components

  • Host: The AI application (Claude Desktop, IDE extension)
  • Server: Middleware that exposes capabilities to the host
  • Resources: External systems (databases, APIs, files)

MCP Capabilities

MCP servers can expose three types of capabilities:

1. Resources

Read-only data that the AI can access:

typescript
{
  uri: "file:///path/to/document.md",
  name: "Project README",
  mimeType: "text/markdown"
}

2. Tools

Functions the AI can call:

typescript
{
  name: "query_database",
  description: "Query the project database",
  inputSchema: {
    type: "object",
    properties: {
      sql: { type: "string" }
    }
  }
}

3. Prompts

Pre-built prompt templates:

typescript
{
  name: "explain_code",
  description: "Explain what this code does",
  arguments: [
    { name: "code", required: true }
  ]
}

Building a Simple MCP Server

Let's build a minimal MCP server that provides project information:

Step 1: Set Up Project

Step 2: Create the Server

typescript
// server.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
  CallToolRequestSchema,
  ListResourcesRequestSchema,
  ListToolsRequestSchema,
  ReadResourceRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";

// Create server instance
const server = new Server(
  { name: "project-info", version: "1.0.0" },
  { capabilities: { resources: {}, tools: {} } }
);

// Define a resource: project info
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
  resources: [
    {
      uri: "project://info",
      name: "Project Information",
      mimeType: "application/json",
    },
  ],
}));

server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  if (request.params.uri === "project://info") {
    return {
      contents: [
        {
          uri: "project://info",
          mimeType: "application/json",
          text: JSON.stringify({
            name: "My Project",
            version: "1.0.0",
            description: "A demo project",
          }),
        },
      ],
    };
  }
  throw new Error("Resource not found");
});

// Define a tool: get current time
server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "get_current_time",
      description: "Get the current server time",
      inputSchema: {
        type: "object",
        properties: {},
        required: [],
      },
    },
  ],
}));

server.setRequestHandler(CallToolRequestSchema, async (request) => {
  if (request.params.name === "get_current_time") {
    return {
      content: [
        {
          type: "text",
          text: new Date().toISOString(),
        },
      ],
    };
  }
  throw new Error("Tool not found");
});

// Start the server
const transport = new StdioServerTransport();
await server.connect(transport);

Step 3: Configure for Claude Desktop

Add to your Claude Desktop config:

Skills Architecture

"Skills" are pre-packaged capabilities that AI tools can invoke. They're similar to MCP but often tool-specific.

Claude Code Skills

Claude Code supports custom skills via hooks and slash commands:

json
// .claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "script": "echo 'Running command'"
      }
    ]
  }
}

Common Skill Patterns

  1. Database Query Skill

    • Connects to DB
    • Validates queries
    • Returns formatted results
  2. Documentation Skill

    • Indexes project docs
    • Provides context to AI
    • Updates automatically
  3. Test Runner Skill

    • Runs tests on demand
    • Reports failures clearly
    • Suggests fixes

Security Considerations

Danger

MCP servers have access to whatever resources you give them. Be careful what you expose.

Safety Checklist

  • No direct database write access
  • Read-only file system access
  • No credential exposure
  • Rate limiting on tools
  • Audit logging enabled

When to Use MCP vs Direct Prompts

Use CaseApproach
Static contextInclude in prompt
Dynamic dataMCP resource
One-off actionsDirect instructions
Repeatable actionsMCP tool
Complex workflowsMCP + skills

Verify

You understand MCP if you can:

  • Explain the host/server/resource architecture
  • Describe the difference between resources, tools, and prompts
  • Create a minimal MCP server
  • Configure Claude Desktop to use it

Congratulations! You've completed the Engineer track. Explore Patterns for best practices or Deployment to ship your projects.