Flask MCP Server Implementation Guide

Flask MCP Server Implementation Guide

A Flask-based reference implementation demonstrating how to build an MCP server with stateless HTTP transport, including example tools for generating random numbers and sentences.

Category
Visit Server

README

MCP Server Implementation Guide

A Flask-based implementation of the Model Context Protocol (MCP) server.

What is MCP?

MCP (Model Context Protocol) is an open-source standard for connecting AI applications to external systems. Think of it like a USB-C port for AI applications — it provides a standardized way to connect AI applications (like Cursor, Claude, or ChatGPT) to data sources, tools, and workflows.

┌─────────────────┐         ┌─────────────────┐
│                 │         │                 │
│   AI Client     │◄───────►│   MCP Server    │
│   (Cursor)      │  MCP    │   (Flask App)   │
│                 │         │                 │
└─────────────────┘         └─────────────────┘

Reference: What is MCP? - modelcontextprotocol.io


JSON-RPC 2.0 Protocol

MCP uses JSON-RPC 2.0 for all communication. There are three message types:

Request

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "method_name",
  "params": { ... }
}

Response (Success)

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": { ... }
}

Response (Error)

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32600,
    "message": "Invalid Request"
  }
}

Notification (No Response Expected)

{
  "jsonrpc": "2.0",
  "method": "notifications/initialized"
}

Reference: Messages - MCP Specification


Required JSON-RPC Methods

An MCP server must implement the following methods:

Method Type Description
initialize Request Handshake and capability negotiation
notifications/initialized Notification Client confirms initialization complete
tools/list Request List available tools
tools/call Request Execute a tool
resources/list Request List available resources
resources/read Request Read a resource
prompts/list Request List available prompts
prompts/get Request Get a prompt template

Reference: MCP Specification


Method Details

1. initialize

Establishes connection and negotiates capabilities.

Request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": {},
    "clientInfo": {
      "name": "Cursor",
      "version": "2.1.32"
    }
  }
}

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "tools": { "listChanged": false },
      "prompts": {},
      "resources": {}
    },
    "serverInfo": {
      "name": "mcp-random-tools",
      "version": "1.0.0"
    }
  }
}

2. notifications/initialized

Client notifies server that initialization is complete. No response required (return HTTP 204).

{
  "jsonrpc": "2.0",
  "method": "notifications/initialized"
}

3. tools/list

Returns available tools with their schemas.

Request:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/list"
}

Response:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "random_number",
        "description": "Generate a random integer between min and max",
        "inputSchema": {
          "type": "object",
          "properties": {
            "min": { "type": "integer", "description": "Minimum value" },
            "max": { "type": "integer", "description": "Maximum value" }
          },
          "required": ["min", "max"]
        }
      }
    ]
  }
}

4. tools/call

Executes a tool and returns the result.

Request:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "random_number",
    "arguments": {
      "min": 1,
      "max": 100
    }
  }
}

Response: ⚠️ Important: Results must be in content array format with isError field!

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "42"
      }
    ],
    "isError": false
  }
}

The content array can contain multiple items with different types:

  • text — Plain text result
  • image — Base64 encoded image with mimeType
  • resource — Reference to a resource URI

The isError field indicates whether the tool execution failed. Even if the HTTP request succeeds (200), the tool itself may have encountered an error.

Reference: MCP Specification 2025-06-18

5. resources/list & prompts/list

Return empty arrays if not implemented:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "resources": []
  }
}
{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "prompts": []
  }
}

Reference: Tools - MCP Specification


Cursor Integration Flow

Configuration File

Add your MCP server to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "Local Flask MCP Server": {
      "headers": {},
      "url": "http://127.0.0.1:5050/"
    }
  }
}

Communication Flow

┌──────────────────────────────────────────────────────────────────────────────┐
│                        CURSOR ←→ MCP SERVER FLOW                             │
└──────────────────────────────────────────────────────────────────────────────┘

    CURSOR                                              MCP SERVER
       │                                                     │
       │  ┌─────────────────────────────────────────────┐   │
       │  │ PHASE 1: INITIALIZATION                     │   │
       │  └─────────────────────────────────────────────┘   │
       │                                                     │
       │──── POST initialize ──────────────────────────────►│
       │     { protocolVersion, clientInfo, capabilities }   │
       │                                                     │
       │◄─── 200 OK ───────────────────────────────────────│
       │     { protocolVersion, serverInfo, capabilities }   │
       │                                                     │
       │──── POST notifications/initialized ───────────────►│
       │                                                     │
       │◄─── 204 No Content ────────────────────────────────│
       │                                                     │
       │  ┌─────────────────────────────────────────────┐   │
       │  │ PHASE 2: DISCOVERY                          │   │
       │  └─────────────────────────────────────────────┘   │
       │                                                     │
       │──── POST tools/list ──────────────────────────────►│
       │◄─── 200 OK { tools: [...] } ───────────────────────│
       │                                                     │
       │──── POST resources/list ──────────────────────────►│
       │◄─── 200 OK { resources: [] } ──────────────────────│
       │                                                     │
       │──── POST prompts/list ────────────────────────────►│
       │◄─── 200 OK { prompts: [] } ────────────────────────│
       │                                                     │
       │  ┌─────────────────────────────────────────────┐   │
       │  │ PHASE 3: TOOL EXECUTION (on demand)         │   │
       │  └─────────────────────────────────────────────┘   │
       │                                                     │
       │──── POST tools/call ──────────────────────────────►│
       │     { name: "random_number", arguments: {...} }     │
       │                                                     │
       │◄─── 200 OK ────────────────────────────────────────│
       │     { content: [...], isError: false }              │
       │                                                     │

What Happens When Cursor Starts

  1. Cursor reads ~/.cursor/mcp.json to discover configured MCP servers
  2. Sends initialize request to each server to establish connection
  3. Server responds with its capabilities (tools, resources, prompts)
  4. Cursor sends notifications/initialized to confirm handshake complete
  5. Cursor queries metadata via tools/list, resources/list, prompts/list
  6. Tools become available for the AI model to invoke during conversations

Transport: Stateless HTTP

This Flask implementation uses Stateless HTTP transport (simple POST requests). This is suitable for:

  • Simple tool servers
  • Dockerized or remote deployments
  • Servers that don't need bidirectional communication

Limitations of Stateless HTTP:

  • ❌ No server-initiated notifications (logging, progress updates)
  • ❌ No sampling (server asking the AI for information)
  • ❌ No real-time bidirectional communication

For full bidirectional features, you would need SSE (Server-Sent Events) or WebSocket transport.

Reference: MCP Transports


Server Architecture

┌─────────────────────────────────────────────────────────────┐
│                      MCP SERVER                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐    │
│   │   Tools     │    │  Resources  │    │   Prompts   │    │
│   │             │    │             │    │             │    │
│   │ • random_   │    │ • files     │    │ • templates │    │
│   │   number    │    │ • databases │    │ • workflows │    │
│   │ • random_   │    │ • APIs      │    │             │    │
│   │   sentence  │    │             │    │             │    │
│   └─────────────┘    └─────────────┘    └─────────────┘    │
│          │                  │                  │            │
│          └──────────────────┴──────────────────┘            │
│                             │                               │
│                    ┌────────▼────────┐                      │
│                    │  JSON-RPC 2.0   │                      │
│                    │    Handler      │                      │
│                    └────────┬────────┘                      │
│                             │                               │
│                    ┌────────▼────────┐                      │
│                    │   HTTP/Flask    │                      │
│                    │   POST /        │                      │
│                    └─────────────────┘                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Running the Server

# Install dependencies
pip install flask

# Run the server
flask run --port 5050

# Or with debug mode
FLASK_DEBUG=1 flask run --port 5050

Error Handling

Return proper JSON-RPC error responses:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32601,
    "message": "Method not found"
  }
}

Standard error codes:

Code Message
-32700 Parse error
-32600 Invalid Request
-32601 Method not found
-32602 Invalid params
-32603 Internal error

References

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured