Radixia

Blog

The Model Context Protocol (MCP): Bridging AI Models with the Digital World - Part 2

Implementation and Usage of MCP Protocol

The Model Context Protocol (MCP): Bridging AI Models with the Digital World - Part 2

After understanding the technical foundations of the Model Context Protocol in part 1 of this article, the next logical step is to explore how it can be implemented and used in real-world scenarios. This section provides practical guidance on setting up MCP servers, integrating clients, and leveraging the protocol's capabilities to enhance AI-powered applications.

Setting Up MCP Servers

Implementing an MCP server involves several key steps, regardless of the specific platform or environment you choose:

1. Defining Server Capabilities

The first step in creating an MCP server is defining the capabilities it will expose. This typically involves:

  • Identifying relevant data sources: Determine which files, databases, or services the server will provide access to.
  • Defining available tools: Specify the functions or operations that can be performed through the server.
  • Establishing resource hierarchies: Organize resources in a logical structure for easy discovery and access.

2. Implementing Protocol Handlers

Once capabilities are defined, you'll need to implement the handlers that process protocol messages:

// Example of a basic MCP server implementation
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new Server({ name: "example-server", version: "1.0.0" }, {
  capabilities: { resources: {} }
});

// Implement resource listing
server.setRequestHandler(ListResourcesRequestSchema, async (request) => {
  // Logic to list available resources
  return {
    resources: [
      { uri: "file:///example.txt", metadata: { name: "Example Document" } },
      // Additional resources...
    ]
  };
});

// Implement resource reading
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  // Logic to read resource content
  return {
    content: "This is the content of the requested resource."
  };
});

// Start the server with stdio transport
const transport = new StdioServerTransport();
server.listen(transport);

3. Handling Authentication and Authorization

For servers that access sensitive data, implementing proper authentication and authorization is crucial:

// Example of adding authentication to an MCP server
server.setRequestHandler(AuthenticateRequestSchema, async (request) => {
  // Validate credentials
  const isValid = validateCredentials(request.credentials);
  
  if (!isValid) {
    throw new Error("Authentication failed");
  }
  
  // Generate session token
  const token = generateSessionToken(request.credentials.username);
  
  return {
    token: token,
    expiration: new Date(Date.now() + 3600000) // 1 hour expiration
  };
});

// Add authorization check to protected handlers
server.setRequestHandler(ReadResourceRequestSchema, async (request, context) => {
  // Check if user is authorized to access this resource
  if (!isAuthorized(context.session, request.uri)) {
    throw new Error("Unauthorized access");
  }
  
  // Proceed with resource reading
  return {
    content: readResource(request.uri)
  };
});

4. Deploying the Server

MCP servers can be deployed in various environments:

  • Local deployment: Running on the user's machine for accessing local resources
  • Cloud deployment: Hosting on cloud platforms for remote access
  • Containerized deployment: Using Docker or similar technologies for consistent environments
  • Serverless deployment: Leveraging platforms like Cloudflare Workers for scalable, maintenance-free operation

Client Integration Process

Integrating MCP clients into applications involves these key steps:

1. Discovering Available Servers

Clients need mechanisms to discover available MCP servers:

// Example of server discovery in a client application
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { HttpClientTransport } from "@modelcontextprotocol/sdk/client/http.js";

// Discover local servers
const localServers = await discoverLocalServers();

// Connect to a specific server
const transport = new HttpClientTransport("http://localhost:8080/mcp");
const client = new Client({ name: "example-client", version: "1.0.0" });
await client.connect(transport);

2. Establishing Connections

Once servers are discovered, clients establish connections and negotiate capabilities:

// Example of capability negotiation
const capabilities = await client.getCapabilities();

if (capabilities.resources) {
  // Server supports resource capabilities
  const resources = await client.listResources();
  console.log("Available resources:", resources);
}

if (capabilities.tools) {
  // Server supports tool capabilities
  const tools = await client.listTools();
  console.log("Available tools:", tools);
}

3. Integrating with AI Models

The most powerful aspect of MCP is its integration with AI models. Here's a simplified example of how an AI application might use MCP:

// Example of AI model integration with MCP
async function processUserQuery(query, aiModel, mcpClient) {
  // Determine if the query requires external data
  const needsExternalData = aiModel.analyzeQueryForExternalDataNeeds(query);
  
  if (needsExternalData) {
    // Use MCP to retrieve relevant resources
    const relevantResources = await mcpClient.findRelevantResources(query);
    
    // Read resource content
    const resourceContents = await Promise.all(
      relevantResources.map(resource => mcpClient.readResource(resource.uri))
    );
    
    // Augment AI context with retrieved data
    aiModel.addContext(resourceContents);
  }
  
  // Generate response with augmented context
  return aiModel.generateResponse(query);
}

Real-World Example: Document Management System

Let's explore a concrete example of using MCP to enhance an AI assistant's capabilities when working with a document management system:

Scenario

A legal firm wants to enable their AI assistant to access and reference their document repository when answering questions about case law and precedents.

Implementation Approach

  1. Create an MCP server for the document repository:
// Document repository MCP server
const server = new Server({ name: "legal-docs-server", version: "1.0.0" }, {
  capabilities: { resources: {}, search: {} }
});

// Implement document search
server.setRequestHandler(SearchResourcesRequestSchema, async (request) => {
  const query = request.query;
  const results = searchDocuments(query);
  
  return {
    resources: results.map(doc => ({
      uri: `document://${doc.id}`,
      metadata: {
        name: doc.title,
        type: doc.type,
        date: doc.date,
        tags: doc.tags
      }
    }))
  };
});

// Implement document reading
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
  const docId = extractDocIdFromUri(request.uri);
  const content = getDocumentContent(docId);
  
  return {
    content: content
  };
});
  1. Integrate with the AI assistant:
// AI assistant integration
async function answerLegalQuestion(question) {
  // Connect to document repository
  const repoClient = await connectToMcpServer("legal-docs-server");
  
  // Search for relevant documents
  const searchResults = await repoClient.searchResources(question);
  
  // Read the most relevant documents
  const relevantDocs = await Promise.all(
    searchResults.resources.slice(0, 5).map(doc => 
      repoClient.readResource(doc.uri)
    )
  );
  
  // Provide documents as context to the AI model
  const response = await claudeModel.generateResponse({
    prompt: question,
    context: relevantDocs.map(doc => doc.content).join("\n\n")
  });
  
  return response;
}

Benefits

This implementation provides several advantages:

  1. Dynamic access to up-to-date information: The AI assistant can access the latest documents without retraining.
  2. Contextual relevance: Only documents relevant to the specific question are retrieved and provided as context.
  3. Secure access control: The MCP server enforces access permissions based on the user's credentials.
  4. Transparent citations: The AI can reference specific documents used to formulate its response.

Example: Code Generation and Deployment

Another powerful use case for MCP is enhancing AI-assisted software development:

Scenario

A development team wants to use Claude to generate and deploy simple web applications based on natural language descriptions.

Implementation Approach

  1. Create an MCP server for code generation and deployment:
// Code deployment MCP server
const server = new Server({ name: "code-deploy-server", version: "1.0.0" }, {
  capabilities: { tools: {} }
});

// Implement code generation tool
server.registerTool({
  name: "generateWebApp",
  description: "Generate a web application based on a description",
  parameters: {
    description: { type: "string", description: "Description of the desired web application" }
  },
  handler: async (params) => {
    // Generate application code based on description
    const code = await generateApplicationCode(params.description);
    
    return {
      files: code.files,
      structure: code.structure
    };
  }
});

// Implement deployment tool
server.registerTool({
  name: "deployWebApp",
  description: "Deploy a web application to production",
  parameters: {
    files: { type: "object", description: "Files to deploy" },
    name: { type: "string", description: "Application name" }
  },
  handler: async (params) => {
    // Deploy the application
    const deploymentResult = await deployApplication(params.files, params.name);
    
    return {
      url: deploymentResult.url,
      status: deploymentResult.status
    };
  }
});
  1. Integrate with Claude:

When a user asks Claude to create and deploy a web application, the AI can use the MCP server to:

  • Generate the application code based on the user's description
  • Deploy the generated code to a production environment
  • Provide the user with the deployment URL and status

This enables a workflow where users can go from idea to deployed application through natural language interaction, with Claude handling the technical details through MCP.

SDKs and Development Tools

To simplify MCP implementation, several SDKs are available:

Official SDKs

  • Python SDK: Ideal for data science and backend applications
  • TypeScript SDK: Well-suited for web applications and Node.js environments
  • Java SDK: Designed for enterprise applications and Android development
  • Kotlin SDK: Optimized for modern Android applications
  • C# SDK: Targeted at .NET applications and Unity development

Development Tools

Several tools can assist in MCP development:

  • MCP Inspector: A debugging tool for monitoring and troubleshooting MCP communications
  • MCP Playground: An interactive environment for testing MCP servers
  • MCP CLI: Command-line tools for working with MCP servers and clients

Debugging and Troubleshooting

Effective debugging is essential when working with MCP. Common approaches include:

Logging and Monitoring

Implementing comprehensive logging at both client and server levels:

// Example of adding logging to an MCP server
import { createLogger } from "./logging.js";

const logger = createLogger("mcp-server");

server.on("request", (request) => {
  logger.info("Received request", { type: request.type, id: request.id });
});

server.on("response", (response) => {
  logger.info("Sent response", { type: response.type, id: response.id });
});

server.on("error", (error) => {
  logger.error("Server error", { message: error.message, stack: error.stack });
});

Common Issues and Solutions

Issue Possible Causes Solutions
Connection failures Network issues, server unavailability Check network connectivity, verify server is running, check firewall settings
Authentication errors Invalid credentials, expired tokens Verify credentials, refresh tokens, check authentication configuration
Permission denied Insufficient access rights Review authorization rules, check user permissions, verify resource access controls
Protocol version mismatch Incompatible client and server versions Update client or server to compatible versions, check protocol version negotiation
Performance issues Slow resource access, network latency Implement caching, optimize resource access, consider connection pooling

By following these implementation guidelines and learning from real-world examples, organizations can effectively leverage MCP to enhance their AI applications with secure, standardized access to external data sources and tools. The next section will explore Cloudflare's specific implementation of MCP support, which offers a streamlined approach to deploying and managing MCP servers.

Cloudflare's MCP Support: Revolutionizing AI Integration

In March 2025, Cloudflare significantly advanced the Model Context Protocol ecosystem by introducing comprehensive support for building and deploying MCP servers on their global network. This development represents a pivotal moment in MCP's evolution, transforming what was primarily a local protocol into a globally accessible standard with enterprise-grade security and scalability.

The Evolution from Local to Remote MCP

Until Cloudflare's implementation, MCP had been largely limited to local deployments—servers running on a user's machine to provide AI assistants with access to local resources. While powerful for developer workflows, this approach had several limitations:

  1. Limited accessibility: Local MCP servers were only available on the machine where they were installed
  2. No standardized authentication: Each implementation handled user authentication differently
  3. Installation barriers: Users needed to install and configure servers locally
  4. Limited scalability: Local servers couldn't easily scale to handle increased load

Cloudflare's support for remote MCP connections fundamentally changes this paradigm. As their blog explains: "Remote MCP support is like the transition from desktop software to web-based software. People expect to continue tasks across devices and to login and have things just work. Local MCP is great for developers, but remote MCP connections are the missing piece to reach everyone on the Internet."

This shift from local-only to remote-capable MCP implementations opens the protocol to a much wider audience, including everyday users who wouldn't typically install and run local servers.

Cloudflare's Four Key Components

Cloudflare's MCP implementation consists of four primary components that work together to simplify the development and deployment of remote MCP servers:

1. workers-oauth-provider

Authentication and authorization are critical challenges for remote MCP servers. Cloudflare addresses this with workers-oauth-provider, an OAuth 2.1 Provider library specifically designed for Cloudflare Workers.

This component:

  • Adds authorization to API endpoints, including MCP server endpoints
  • Handles the complete OAuth flow, making the MCP server act as both an OAuth client to upstream services and an OAuth server to MCP clients
  • Supports Dynamic Client Registration (RFC 7591) and Authorization Server Metadata (RFC 8414)
  • Securely manages tokens, storing encrypted access tokens in Workers KV

The implementation follows best security practices by issuing its own tokens rather than passing upstream tokens directly to clients. This approach provides several advantages:

// Example of OAuth provider implementation in a Cloudflare Worker
import OAuthProvider from "@cloudflare/workers-oauth-provider";
import MyMCPServer from "./my-mcp-server";
import MyAuthHandler from "./auth-handler";

export default new OAuthProvider({
  apiRoute: "/sse", // MCP clients connect to your server at this route
  apiHandler: MyMCPServer.mount('/sse'), // Your MCP Server implementation
  defaultHandler: MyAuthHandler, // Your authentication implementation
  authorizeEndpoint: "/authorize",
  tokenEndpoint: "/token",
  clientRegistrationEndpoint: "/register",
});

This abstraction allows developers to easily plug in their own authentication mechanisms, whether using third-party providers like Google or GitHub, or implementing custom authentication flows.

2. McpAgent Class in Cloudflare Agents SDK

The McpAgent class, built into the Cloudflare Agents SDK, handles the remote transport layer for MCP communications. This component:

  • Manages the transition from stdio-based local communication to HTTP-based remote communication
  • Handles connection establishment and maintenance
  • Implements the Server-Sent Events (SSE) protocol for streaming responses
  • Provides error handling and reconnection logic

This class simplifies the development of remote MCP servers by abstracting away the complexities of the transport layer, allowing developers to focus on implementing the actual functionality of their servers.

3. mcp-remote Adapter

To ensure compatibility with existing MCP clients that only support local connections, Cloudflare introduced the mcp-remote adapter. This component:

  • Allows MCP clients designed for local connections to work with remote MCP servers
  • Translates between local and remote communication protocols
  • Handles authentication flows for remote servers
  • Maintains backward compatibility with existing implementations

This adapter is crucial for the adoption of remote MCP servers, as it allows users to leverage existing MCP clients while benefiting from the advantages of remote deployment.

4. AI Playground as a Remote MCP Client

To demonstrate the capabilities of remote MCP servers, Cloudflare provides an AI playground that functions as a remote MCP client. This playground:

  • Offers a chat interface for interacting with AI assistants
  • Supports connection to remote MCP servers
  • Includes built-in authentication checks
  • Provides a user-friendly way to test and demonstrate MCP functionality

This component serves as both a reference implementation and a practical tool for developers building and testing remote MCP servers.

Building MCP Servers on Cloudflare Workers

One of the most significant advantages of Cloudflare's implementation is the simplicity of building and deploying MCP servers using Cloudflare Workers. The process has been streamlined to require minimal code while providing maximum functionality.

Basic Implementation

A basic MCP server implementation on Cloudflare Workers can be as simple as:

import { WorkerEntrypoint } from 'cloudflare:workers'
import { ProxyToSelf } from 'workers-mcp'

export default class MyWorker extends WorkerEntrypoint<Env> {
  /**
   * A warm, friendly greeting from your new Workers MCP server.
   * @param name {string} the name of the person we are greeting.
   * @return {string} the contents of our greeting.
   */
  sayHello(name: string) {
    return `Hello from an MCP Worker, ${name}!`
  }
  
  /**
   * @ignore
   **/
  async fetch(request: Request): Promise<Response> {
    return new ProxyToSelf(this).fetch(request)
  }
}

This minimal implementation:

  • Defines a simple tool (sayHello) that an AI assistant can invoke
  • Uses JSDoc comments to document the tool's purpose, parameters, and return values
  • Leverages the ProxyToSelf logic to handle MCP server routing automatically

Advanced Capabilities

Beyond basic functionality, Cloudflare Workers enables more sophisticated MCP servers that can:

1. Generate Images with Workers AI

async generateImage(prompt: string, steps: number): Promise<string> {
  const response = await this.env.AI.run('@cf/black-forest-labs/flux-1-schnell', {
    prompt,
    steps,
  });
  
  // Convert from base64 string
  const binaryString = atob(response.image);
  // Create byte representation
  const img = Uint8Array.from(binaryString, (m) => m.codePointAt(0)!);
  
  return new Response(img, {
    headers: {
      'Content-Type': 'image/jpeg',
    },
  });
}

This example demonstrates how Claude can generate images through an MCP server that leverages Cloudflare's AI capabilities.

2. Access Databases and Storage

/**
 * Store a note in the database.
 * @param title {string} The title of the note.
 * @param content {string} The content of the note.
 * @return {object} The created note with its ID.
 */
async createNote(title: string, content: string) {
  const id = crypto.randomUUID();
  await this.env.DB.prepare(
    `INSERT INTO notes (id, title, content) VALUES (?, ?, ?)`
  ).bind(id, title, content).run();
  
  return { id, title, content };
}

/**
 * Retrieve a note by its ID.
 * @param id {string} The ID of the note to retrieve.
 * @return {object} The retrieved note.
 */
async getNote(id: string) {
  const note = await this.env.DB.prepare(
    `SELECT id, title, content FROM notes WHERE id = ?`
  ).bind(id).first();
  
  if (!note) {
    throw new Error(`Note with ID ${id} not found`);
  }
  
  return note;
}

This example shows how an MCP server can provide AI assistants with access to structured data stored in Cloudflare D1 databases.

3. Interact with External APIs

/**
 * Get weather information for a location.
 * @param location {string} The location to get weather for.
 * @return {object} Current weather information.
 */
async getWeather(location: string) {
  const response = await fetch(
    `https://api.weatherapi.com/v1/current.json?key=${this.env.WEATHER_API_KEY}&q=${encodeURIComponent(location)}`
  );
  
  if (!response.ok) {
    throw new Error(`Failed to get weather: ${response.statusText}`);
  }
  
  const data = await response.json();
  return {
    location: data.location.name,
    country: data.location.country,
    temperature: data.current.temp_c,
    condition: data.current.condition.text,
    humidity: data.current.humidity,
    windSpeed: data.current.wind_kph,
  };
}

This example demonstrates how MCP servers can act as secure intermediaries for external API access, allowing AI assistants to retrieve real-time data.

Deployment and Authentication Flow

Deploying an MCP server to Cloudflare is remarkably straightforward. Developers can use the Cloudflare dashboard or CLI to deploy their Worker code, with the entire process taking just a few minutes.

The complete MCP OAuth flow in a Cloudflare deployment follows this pattern:

  1. User initiates connection: The user asks their AI assistant to connect to a specific MCP server
  2. Authorization request: The MCP client redirects to the server's authorization endpoint
  3. User authentication: The user authenticates with the server (e.g., via GitHub, Google, or custom auth)
  4. Permission grant: The user grants the MCP client permission to access specific resources or tools
  5. Token issuance: The server issues a token to the MCP client
  6. Connection establishment: The MCP client establishes a connection to the server using the token
  7. Tool/resource discovery: The client discovers available tools and resources
  8. Interaction: The AI assistant can now use the server's capabilities through the MCP client

This flow ensures secure, user-controlled access to remote resources while maintaining a seamless user experience.

Remote vs. Local MCP: Strategic Considerations

For technical leaders evaluating MCP implementation options, understanding the tradeoffs between remote and local approaches is crucial:

Aspect Local MCP Remote MCP (Cloudflare)
Accessibility Limited to local machine Available anywhere with internet access
Authentication Typically minimal or OS-based Full OAuth support with flexible providers
Deployment Requires local installation Serverless deployment on global network
Scalability Limited by local resources Automatically scales with demand
Maintenance User responsible for updates Managed by Cloudflare
Security Relies on local system security Enterprise-grade security with token encryption
Use cases Developer workflows, local data access Enterprise applications, consumer services
Implementation complexity Higher (requires local setup) Lower (serverless deployment)

Remote MCP servers on Cloudflare are particularly well-suited for:

  • Enterprise applications requiring secure access to corporate data
  • Consumer-facing AI assistants that need to work across devices
  • Applications requiring high availability and global distribution
  • Services that need to scale dynamically based on demand

Early Adoption and Real-World Applications

Cloudflare's MCP implementation is already seeing adoption across various industries and use cases:

Enterprise Data Access

Organizations are using remote MCP servers to provide AI assistants with secure access to internal knowledge bases, document repositories, and business applications. This enables more contextual and accurate responses while maintaining strict access controls.

Development Workflow Enhancement

Development teams are leveraging MCP servers on Cloudflare to create AI-powered coding assistants that can access codebases, run tests, and even deploy applications. The serverless nature of Workers makes this particularly efficient for CI/CD integration.

Consumer Applications

Consumer-facing applications are using remote MCP servers to enhance AI capabilities with personalized data access and service integrations. The authentication flow ensures users maintain control over what data their AI assistants can access.

Performance and Reliability Considerations

You're halfway in — the full article lives on our blog.

Continue reading on blog.radixia.ai →

Free to read. Subscribe there to get new posts by email.