Skip to content

AshikNesin/learn-mcp-by-building

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

12 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Model Context Protocol (MCP) Implementation

This project implements the Model Context Protocol (MCP) for building AI tools. It provides a modular framework that can be used to create MCP-compatible servers and clients.


๐Ÿ” What is Model Context Protocol (MCP)?

The Model Context Protocol (MCP) is an open protocol that enables AI assistants to interact with external tools and data sources.

Key Features
  • List available tools and their capabilities
  • Call tools with parameters
  • Handle errors in a consistent way
  • Process tool results in a standardized format

๐Ÿ“š For a detailed overview, see MCP Notes.


โœจ Features

Category Features
Core โœ… JSON-RPC 2.0 message handling
โœ… Protocol initialization
โœ… Capability negotiation
Tools โœ… Tool registration with JSON Schema
โœ… Tool invocation and validation
โœ… Standardized error handling
Transport โœ… STDIO support
โœ… HTTP+SSE Support
Testing โœ… Test clients

๐Ÿ“ Project Structure

src/
โ”œโ”€โ”€ core/           # Core MCP server implementation
โ”œโ”€โ”€ transports/     # Transport layer implementations (stdio, HTTP+SSE)
โ”œโ”€โ”€ tools/          # Tool definitions and handlers
โ”œโ”€โ”€ examples/       # Example servers and clients
โ”‚   โ””โ”€โ”€ public/     # Static files for HTTP server
โ””โ”€โ”€ index.js        # Main entry point for the library

๐Ÿš€ Getting Started

Prerequisites

  • Node.js 20.x or later
  • npm or pnpm

Installation

# Clone the repository
git clone https://github.com/AshikNesin/learn-mcp-by-building
cd learn-mcp-by-building

# Install dependencies
npm install
# or
pnpm install

๐Ÿƒโ€โ™‚๏ธ Running the Examples

STDIO Server and Client

Run the STDIO server:

npm run server:stdio
# or
node src/examples/stdio-server.js

Test with the STDIO client:

npm run client:stdio
# or
node src/examples/stdio-client.js

Run both together to see a complete test:

npm run test:stdio
# or
node src/examples/stdio-client.js | node src/examples/stdio-server.js

HTTP+SSE Server and Client

Run the HTTP+SSE server:

npm run server:sse
# or
node src/examples/http-sse-server.js --port 5000

Available options:

  • --port: Port to listen on (default: 5000)
  • --host: Host to bind to (default: localhost)
  • --path: Endpoint path (default: /sse)
  • --cors: Enable CORS (default: true)
  • --serve-static: Serve static files from src/examples/public (default: true)

Test with the HTTP+SSE client:

npm run client:sse
# or
node src/examples/http-sse-client.js --server http://localhost:5000/sse

Once running, you can also access the web-based client interface in your browser at http://localhost:5000:

SSE Client Interface

The interface provides a user-friendly way to interact with the MCP server, with a side-by-side layout showing the calculator controls and real-time logs.

๐Ÿ” Using the MCP Inspector

You can use the official MCP Inspector to debug the server:

npm run debug

The MCP Inspector provides a visual interface for monitoring and debugging MCP servers:

MCP Inspector


๐Ÿงฎ Calculator Tool

Operations

  • โž• add
  • โž– subtract
  • โœ–๏ธ multiply
  • โž— divide

Parameters

  • operation - Operation type
  • a - First operand
  • b - Second operand

Error Handling

  • Division by zero
  • Invalid operations
  • Type validation
  • Missing parameters

๐Ÿง‘โ€๐Ÿ’ป Developing with the MCP Framework

Creating a New Server

import { McpServer } from '../core/index.js';
import { StdioTransport } from '../transports/index.js';
import { calculatorToolDefinition, handleCalculatorTool } from '../tools/index.js';

// Create server instance
const server = new McpServer(
  { name: 'my-server', version: '1.0.0' },
  { capabilities: { tools: { listChanged: true } } }
);

// Register tool handlers
server.setRequestHandler('tools/list', () => ({ tools: [calculatorToolDefinition] }));
server.setRequestHandler('tools/call', async (params) => {
  if (params.name === 'calculator') {
    return handleCalculatorTool(params.arguments);
  }
  throw new Error(`Tool ${params.name} not found`);
});

// Start the server
const transport = new StdioTransport();
server.connect(transport)
  .then(() => console.error('Server ready!'));

Creating a New Tool

  1. Create a new file in src/tools/:
// src/tools/my-tool.js
export const myToolDefinition = {
  name: 'my-tool',
  description: 'Description of my tool',
  inputSchema: {
    type: 'object',
    properties: {
      // Define parameters
    },
    required: []
  }
};

export async function handleMyTool(args) {
  // Implement tool logic
  return {
    content: [
      {
        type: 'text',
        text: 'Result from my tool'
      }
    ]
  };
}
  1. Export the tool in src/tools/index.js:
export * from './my-tool.js';

๐Ÿ› ๏ธ Protocol Features

  • โœ… Capability negotiation
  • โœ… Tool list change notifications
  • โœ… Standardized error handling
  • โœ… JSON Schema validation
  • โœ… Structured tool results
  • โœ… Transport layer abstraction

๐Ÿ“š External Resources


๐Ÿ“ License

MIT

About

Learn MCP by building from Scarch

Topics

Resources

License

Stars

Watchers

Forks

Contributors