๐ŸŒMCP Server - Model Context Protocol Server

The BoxLang AI Module provides a complete MCP (Model Context Protocol) server implementation that allows you to expose tools, resources, and prompts to AI clients.

๐Ÿ“‹ Table of Contents

๐ŸŽฏ What is an MCP Server?

An MCP Server is a service that exposes capabilities to AI clients using the standardized Model Context Protocol. It enables:

  • ๐Ÿ”ง Expose Tools: Register functions that AI clients can invoke

  • ๐Ÿ“š Serve Resources: Provide documents and data to AI clients

  • ๐Ÿ’ฌ Offer Prompts: Define reusable prompt templates

  • ๐ŸŒ HTTP & STDIO Transports: Expose your MCP server via web or command-line

๐Ÿ—๏ธ MCP Architecture

๐Ÿš€ Transport Types

BoxLang AI provides two transport mechanisms for MCP servers:

๐Ÿ”„ Transport Flow Comparison

๐ŸŒ HTTP Transport (Web)

Best for: Web applications, REST APIs, browser-based clients

Entry Point: Automatic via convention or manual endpoint creation

Automatic (Convention):

Manual (Custom Endpoint):

Features:

  • โœ… CORS support with wildcard patterns

  • โœ… Body size limits

  • โœ… API key authentication

  • โœ… HTTP Basic Auth

  • โœ… Security headers

  • โœ… Server-Sent Events (SSE) streaming

  • โœ… Discovery endpoint (GET)

๐Ÿ–ฅ๏ธ STDIO Transport (Command-Line)

Best for: Desktop applications, CLI tools, IDE integrations, local AI assistants

Entry Point: Create a script entry point

Example Script (mcp-stdio.bxs):

Run:

Features:

  • โœ… JSON-RPC over STDIN/STDOUT

  • โœ… Line-based protocol

  • โœ… Graceful shutdown signal

  • โœ… Process lifecycle management

  • โŒ No HTTP headers/CORS (not needed)

  • โŒ No status codes (JSON-RPC error codes used)

Communication:

๐Ÿ“– Complete Example: See examples/mcp/09-mcp-stdio.bxs for a full working STDIO entry point with argument parsing.

๐ŸŽฏ Choosing a Transport

Scenario
Recommended Transport

Web application with browser clients

HTTP

REST API for external services

HTTP

Desktop AI assistant (Claude Desktop, etc.)

STDIO

VS Code extension / IDE integration

STDIO

Command-line tool

STDIO

Docker container as MCP service

Both (HTTP for API, STDIO for container tools)

Testing/Development

HTTP (easier to test with curl)

Quick Start

1. Register Tools

Register tools at application startup (e.g., in Application.bx):

2. Access the MCP Endpoint

The module provides a built-in endpoint at public/mcp.bxm:

Specify a server using either a query parameter or URL segment:

Custom URL Entry Points

You can create your own MCP server endpoints at any URL by importing and rendering the MCPRequestProcessor:

This creates a fully functional MCP endpoint at your custom location:

Use Cases:

  • Custom routing: Place MCP endpoints under your API structure (/api/v1/mcp, /admin/mcp, etc.)

  • Security: Put endpoints behind authentication middleware or custom security rules

  • Multiple entry points: Create different endpoints for different purposes (public API, admin tools, etc.)

  • Framework integration: Integrate MCP servers into existing URL routing schemes

Example - Secured Admin Endpoint:

Example - API Versioned Endpoint:

The processor automatically:

  • โœ… Extracts server name from query parameter (?server=name) or URL segment

  • โœ… Handles JSON-RPC 2.0 request parsing

  • โœ… Routes to the correct MCP server instance

  • โœ… Returns properly formatted JSON-RPC responses

  • โœ… Fires all MCP events (onMCPRequest, onMCPResponse, onMCPError)

Server Configuration

Creating a Server

Configure Description and Version

Get Server Info

Basic Authentication ๐Ÿ”’

Protect your MCP server with HTTP Basic Authentication:

How it works:

  • Credentials are verified before any request processing

  • Returns 401 Unauthorized with WWW-Authenticate header if credentials are invalid

  • Uses standard HTTP Basic Authentication (base64-encoded username:password)

  • Zero performance overhead when not configured

  • Fluent API for easy configuration

Example - Secured Admin Server:

Making authenticated requests:

Check if authentication is enabled:

Security Best Practices:

  • โœ… Always use HTTPS in production to prevent credential interception

  • โœ… Store passwords in environment variables or encrypted configuration

  • โœ… Use strong, unique passwords for each server

  • โœ… Combine with CORS settings for additional security

  • โœ… Consider rotating credentials periodically

  • โœ… Log authentication failures for security monitoring

Example with environment variables:

CORS Configuration ๐ŸŒ

Configure Cross-Origin Resource Sharing (CORS) to control which origins can access your MCP server:

Wildcard Pattern Matching:

The CORS implementation supports wildcard patterns for flexible domain matching:

  • *.example.com - Matches any subdomain: app.example.com, api.example.com, admin.example.com

  • * - Matches all origins (returns the requesting origin in Access-Control-Allow-Origin)

  • Exact matches: https://example.com - Only matches exactly this origin

Dynamic CORS Management:

How CORS Works:

When a browser makes a cross-origin request:

  1. Browser sends Origin header with the request

  2. Server checks if origin matches allowed patterns

  3. If allowed, server responds with Access-Control-Allow-Origin header

  4. Server also includes CORS headers in OPTIONS preflight responses

CORS Headers Set by Server:

  • Access-Control-Allow-Origin - Allowed origin (dynamic or *)

  • Access-Control-Allow-Methods - GET, POST, OPTIONS

  • Access-Control-Allow-Headers - Content-Type, Authorization, X-API-Key

  • Access-Control-Max-Age - 86400 (24 hours)

Security Best Practices:

  • โœ… Avoid * in production - Specify exact origins or wildcard patterns

  • โœ… Use HTTPS origins - Always prefer secure origins

  • โœ… Combine with authentication - CORS doesn't replace authentication

  • โœ… Review periodically - Remove unused origins

  • โœ… Test preflight requests - Verify OPTIONS requests work correctly

Example - Multi-Environment Setup:

Request Body Size Limits ๐Ÿ“

Protect your server from large payloads by setting request body size limits:

How it works:

  • Server checks len(requestBody) before processing

  • If body exceeds limit, returns 413 Payload Too Large error

  • Default is 0 (unlimited)

  • Limit applies to entire JSON-RPC request body

Error Response (413):

Get current limit:

Use Cases:

  • Public APIs - Prevent abuse from extremely large payloads

  • Resource constraints - Match server memory/processing limits

  • Tool-specific limits - Different servers can have different limits

  • DoS prevention - Basic protection against payload attacks

Example - Tiered Limits:

Custom API Key Validation ๐Ÿ”‘

Implement custom API key authentication logic with provider callbacks:

Provider Function Signature:

Request Data Struct:

The requestData argument contains:

  • method - MCP method being called (e.g., "tools/list")

  • serverName - Name of the MCP server

  • body - Full request body as string

  • Any other request metadata

API Key Extraction:

The server automatically extracts API keys from:

  1. X-API-Key header

  2. Authorization: Bearer <token> header

How it works:

  1. Server checks for API key in headers

  2. If found, calls your provider function with key and request data

  3. If provider returns false or throws, returns 401 Unauthorized

  4. If provider returns true, request proceeds normally

Error Response (401):

Check if provider is configured:

Making authenticated requests:

Advanced Example - Multi-Tenant with Usage Tracking:

Combining Security Features:

You can use multiple security features together:

Security Priority:

  1. Body size check - Happens first (reject oversized payloads immediately)

  2. CORS validation - Checks Origin header against allowed patterns

  3. Basic authentication - HTTP Basic Auth credentials check

  4. API key validation - Custom provider callback execution

  5. Request processing - Only if all checks pass

Security Headers ๐Ÿ›ก๏ธ

The MCP server automatically includes industry-standard security headers in all responses:

Headers Included:

  • X-Content-Type-Options: nosniff - Prevents MIME type sniffing

  • X-Frame-Options: DENY - Prevents clickjacking attacks

  • X-XSS-Protection: 1; mode=block - Enables XSS filtering

  • Referrer-Policy: strict-origin-when-cross-origin - Controls referrer information

  • Content-Security-Policy: default-src 'none'; frame-ancestors 'none' - Restricts resource loading

  • Strict-Transport-Security: max-age=31536000; includeSubDomains - Forces HTTPS (when applicable)

  • Permissions-Policy: geolocation=(), microphone=(), camera=() - Disables sensitive browser features

Automatic Application:

Security headers are added to:

  • โœ… Successful responses (200 OK)

  • โœ… Error responses (400, 401, 404, 413, 500)

  • โœ… CORS preflight responses (OPTIONS)

No configuration needed - these headers are applied automatically to enhance security posture.

Tool Registration

Register a Single Tool

Register Multiple Tools

Check and Retrieve Tools

List Tools (MCP Format)

Unregister Tools

Annotation-Based Discovery

The MCP server can automatically discover and register tools, resources, and prompts from annotated methods using the scan() method.

Scan for Annotations

@mcpTool Annotation

Register methods as MCP tools:

Annotation formats:

  • @mcpTool - Name from method name, description from function hint, version defaults to 1.0.0

  • @mcpTool( "Description" ) - Name from method name, custom description

  • @mcpTool( { name: "...", description: "...", version: "..." } ) - All custom values

@mcpResource Annotation

Register methods as MCP resources:

Annotation formats:

  • @mcpResource - URI and name from method name, description from function hint

  • @mcpResource( "Description" ) - URI and name from method name, custom description

  • @mcpResource( { uri: "...", name: "...", description: "...", mimeType: "..." } ) - All custom values

@mcpPrompt Annotation

Register methods as MCP prompts:

Annotation formats:

  • @mcpPrompt - Name from method name, description from function hint

  • @mcpPrompt( "Description" ) - Name from method name, custom description

  • @mcpPrompt( { name: "...", description: "...", arguments: [...] } ) - All custom values

Resource Registration

Resources provide access to documents and data:

Register a Resource

Register Dynamic Resources

List and Read Resources

Manage Resources

Prompt Registration

Prompts provide reusable prompt templates:

Register a Prompt

List and Get Prompts

Handling MCP Requests

Direct Request Handling

Handle JSON String

Supported Methods

Method
Description

initialize

Get server capabilities and info

tools/list

List available tools

tools/call

Invoke a tool

resources/list

List available resources

resources/read

Read a resource

prompts/list

List available prompts

prompts/get

Get a prompt with arguments

ping

Health check

HTTP Endpoint (mcp.bxm)

The module includes a pre-built HTTP endpoint at public/mcp.bxm:

Discovery (GET)

Returns server capabilities:

JSON-RPC Requests (POST)

Multiple Servers

Specify the server using either a query parameter or URL segment:

CORS Support

The endpoint includes CORS headers for cross-origin requests.

Static Server Management

Check Server Existence

Get All Server Names

Remove a Server

Clear All Servers

Complete Example

Application Setup

Connecting from AI Client

Events & Interception ๐ŸŽฏ

The MCP Server fires custom events during its lifecycle, allowing you to add custom logging, monitoring, alerting, and integration with other systems.

๐Ÿ“ก Transport Agnostic: All MCP events work identically for both HTTP and STDIO transports. The same event handlers will be called regardless of how clients connect to your MCP server.

Available Events

onMCPServerCreate

Fired when a new MCP server instance is created.

onMCPServerRemove

Fired when an MCP server instance is removed from the registry.

onMCPRequest

Fired before processing an incoming MCP request.

onMCPResponse

Fired after processing an MCP request and before returning the response.

onMCPError โš ๏ธ

Fired when an exception occurs during MCP server operations.

Registering Event Listeners

For BoxLang Module Registration

In your module's ModuleConfig.bx:

For Application/Script Registration

Use BoxRegisterInterceptor() to register listeners:

Event Use Cases

Custom Logging

Metrics & Monitoring

Rate Limiting

Error Alerting

Statistics & Monitoring ๐Ÿ“Š

The MCP server automatically tracks performance and usage metrics for real-time monitoring and analytics.

Enabling Statistics

Statistics are enabled by default when creating an MCP server:

Retrieving Statistics

Get Summary Statistics

Quick overview of key metrics (lightweight):

Summary includes:

  • uptime - Server uptime in milliseconds

  • totalRequests - Total requests processed

  • successRate - Success rate as percentage

  • avgResponseTime - Average response time in milliseconds

  • totalToolInvocations - Total tool calls

  • totalResourceReads - Total resource reads

  • totalPromptGenerations - Total prompt generations

  • totalErrors - Total errors encountered

  • lastRequestAt - Timestamp of last request (empty if no requests)

Get Detailed Statistics

Complete stats with breakdowns:

Detailed stats include:

  • Requests: total, successful, failed, byMethod (map), response times (array), avg/min/max times, lastRequestAt

  • Tools: totalInvocations, byTool (map with count/totalTime/avgTime per tool), execution times (array), avg/min/max times

  • Resources: totalReads, byUri (map of read counts)

  • Prompts: totalGenerations, byName (map of generation counts)

  • Errors: total, byCode (map of error counts), lastError (code/message/timestamp)

Managing Statistics

Check if Stats are Enabled

Enable/Disable Tracking

Reset Statistics

Clear all statistics back to zero:

Dashboard Example

Create a real-time monitoring dashboard:

Using Stats with Events

Combine statistics with event interception for custom monitoring:

Performance Notes

  • Zero Overhead When Disabled: When statsEnabled: false, no performance impact

  • Memory Efficient: Only last 1000 timing samples retained per metric

  • Thread Safe: Uses atomic operations for concurrent request handling

  • Real-Time: Stats updated immediately on each operation

  • Lightweight Summary: getStatsSummary() is optimized for frequent polling

API Integration Example

Expose stats via REST API:

Best Practices

1. Use Descriptive Names

2. Register at Application Start

3. Clean Up on Shutdown

4. Use Separate Servers for Different Purposes

5. Secure Sensitive Servers

Security Checklist:

  • โœ… Use .withBasicAuth() for sensitive operations

  • โœ… Configure CORS with .setCors() to restrict origins

  • โœ… Store credentials in environment variables

  • โœ… Use HTTPS in production

  • โœ… Monitor authentication failures via onMCPError events

  • โœ… Implement rate limiting if needed

6. Document Your Tools

7. Monitor Performance with Statistics

External Resources

Last updated