Running an MCP Server at the Edge with FastEdge

The Model Context Protocol (MCP) is an open protocol that standardizes how applications provide context and tools to LLMs. Think of it as a USB-C for AI — a universal interface that lets any LLM client talk to any tool server without custom integrations.

In this post, we build and deploy a full MCP server — entirely on Gcore FastEdge. No containers, no VMs, no infrastructure. Just Rust compiled to WebAssembly, running on 160+ edge PoPs worldwide.

What is MCP?

MCP defines how clients (like Claude Desktop, VS Code extensions, or custom AI apps) discover and invoke tools on a server. The protocol uses JSON-RPC over HTTP with two transport modes:

The Streamable HTTP transport is a great fit for edge compute because:

The Architecture

Our MCP server exposes a single endpoint (/mcp) that accepts both GET and POST:

MethodPathPurpose
GET/mcpSSE stream (server events / handshake)
POST/mcpJSON-RPC message handler

For this example, we implement three MCP tools:

Implementation in Rust

The full source is about 200 lines. Here's the core structure:

use fastedge::{
    body::Body,
    http::{Error, Request, Response, StatusCode},
};
use serde_json;

#[fastedge::http]
fn main(req: Request<Body>) -> Result<Response<Body>, Error> {
    let method = req.method().clone();
    let path = req.uri().path().to_string();

    match (method.as_str(), path.as_str()) {
        ("GET", "/mcp") => {
            // SSE endpoint — sends an "endpoint" event so the client
            // knows where to send JSON-RPC messages
            sse_reply("event: endpoint\ndata: /\n\n")
        }
        ("POST", "/mcp") => {
            // Parse JSON-RPC, dispatch to handler, return response
            let body_str = String::from_utf8_lossy(req.body().as_ref());
            let response = dispatch_jsonrpc(&body_str);
            json_reply(StatusCode::OK, &response)
        }
        _ => not_found(),
    }
}

The JSON-RPC dispatching follows the MCP spec exactly:

fn dispatch_jsonrpc(body_str: &str) -> String {
    let msg: serde_json::Value = serde_json::from_str(body_str).unwrap_or_default();
    let method = msg.get("method").and_then(|v| v.as_str()).unwrap_or("");

    match method {
        "initialize" => handle_initialize(msg.get("id")),
        "tools/list" => handle_tools_list(msg.get("id")),
        "tools/call" => handle_tools_call(
            msg.get("id"),
            msg.pointer("/params/name"),
            msg.pointer("/params/arguments"),
        ),
        "notifications/initialized" => String::new(), // 202 Accepted
        _ => method_not_found(msg.get("id"), method),
    }
}

Deploying to FastEdge

Deployment is a two-step process: upload the Wasm binary, then update the app.

# Build
cargo build --target wasm32-wasip1 --release

# Upload binary
curl -X POST https://api.gcore.com/fastedge/v1/binaries/raw \
  -H "Authorization: APIKey YOUR_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @target/wasm32-wasip1/release/mcp_server.wasm

# Create app
curl -X POST https://api.gcore.com/fastedge/v1/apps \
  -H "Authorization: APIKey YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"binary": BINARY_ID, "name": "fastedge-mcp", "status": 1}'

Once the app is created, it's immediately live at https://fastedge-mcp-NNNN.fastedge.app. The MCP server is now running on 160+ edge PoPs worldwide.

Testing the MCP Server

Any MCP-compatible client can connect. You can also test with curl:

# Initialize session
curl -X POST https://fastedge-mcp-1476.fastedge.app/mcp \
  -H "content-type: application/json" \
  -H "accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize",
       "params":{"protocolVersion":"2025-06-18","capabilities":{}}}'

# List available tools
curl -X POST https://fastedge-mcp-1476.fastedge.app/mcp \
  -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

# Call the hello tool
curl -X POST https://fastedge-mcp-1476.fastedge.app/mcp \
  -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call",
       "params":{"name":"hello","arguments":{"name":"FastEdge"}}}'
Live demo: The MCP server described in this post is running right now at fastedge-mcp-1476.fastedge.app. Try it with any MCP client!

Performance

The Wasm binary is ~254KB (mostly serde_json for JSON-RPC parsing). FastEdge cold starts in under 1ms, so even infrequent MCP tool invocations see no startup penalty. A simple tool call completes in under 10ms including network transit from the nearest edge PoP.

For comparison, running the same server on a container platform would add 200-800ms of cold start latency per invocation. The edge eliminates that entirely.

What's Next?

This is a minimal example, but it demonstrates the core idea: MCP servers don't need to run on traditional infrastructure. The edge is a natural home for tool servers because:

Ready to build on this? Add more tools, connect to databases via HTTP client, or integrate with the FastEdge KV store for stateful operations. The edge is your platform.