turbomcp-openapi
OpenAPI to MCP conversion for TurboMCP. Expose REST APIs as MCP tools and resources.
Overview
This crate allows you to automatically convert an OpenAPI 3.0.x specification (via the openapiv3 crate) into MCP (Model Context Protocol) tools and resources. This enables AI agents to interact with REST APIs without writing custom handlers.
Default mapping:
GETendpoints → MCP Resources (readable content)POST,PUT,PATCH,DELETEendpoints → MCP Tools (callable operations)
Quick Start
use Path;
use Duration;
use ;
use ;
// Load from URL
let provider = from_url
.await?
.with_base_url?
.with_timeout; // Optional, 30s default
// Or load from file
let provider = from_file?
.with_base_url?;
// Or load from string
let provider = from_string?
.with_base_url?;
// Convert to an McpHandler and serve it with any transport
let handler: OpenApiHandler = provider.into_handler;
new
.transport
.serve
.await?;
Security Features
SSRF Protection
The provider includes built-in Server-Side Request Forgery (SSRF) protection that blocks requests to:
- Localhost/loopback:
127.0.0.0/8,::1,localhost - Private networks:
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 - Cloud metadata endpoints:
169.254.169.254and169.254.0.0/16 - Link-local addresses:
fe80::/10 - Other reserved ranges: Multicast, broadcast, etc.
This prevents malicious API specs from making requests to internal infrastructure.
Request Timeouts
All HTTP requests have a configurable timeout (default: 30 seconds) to prevent:
- Slowloris attacks
- Indefinite hangs on unresponsive servers
- Resource exhaustion
use Duration;
let provider = from_string?
.with_base_url?
.with_timeout; // 10 second timeout
// Check current timeout
println!;
Custom Route Mapping
You can customize how OpenAPI operations map to MCP types:
use ;
let mapping = new
// Default: GET -> Resource
.map_method
// Custom: All /admin/* paths are skipped
.map_pattern?
// Custom: Force specific paths to be tools
.map_rule?;
let provider = from_string?
.with_route_mapping
.with_base_url?;
Route Mapping Rules
Rules are evaluated in priority order (highest first):
use ;
// Create a rule matching POST/PUT to /users/* paths
let rule = new
.methods
.pattern?
.priority; // Higher priority = checked first
McpType Variants
McpType::Tool- Expose as MCP tool (callable operation)McpType::Resource- Expose as MCP resource (readable content)McpType::Skip- Don't expose via MCP
Features
- OpenAPI 3.0.x Support - Parse both JSON and YAML specifications (via
openapiv3) - Multiple Loading Methods - From URL, file path, or string
- Configurable Mapping - Customize how operations map to MCP types
- Regex Pattern Matching - Route rules support regex path patterns
- Parameter Handling - Path, query, header, and cookie parameters
- Request Body Support - JSON request bodies converted to tool inputs
- HTTP Client Integration - Built-in reqwest client for API calls
- Custom Client Support - Provide your own configured reqwest::Client
- SSRF Protection - Built-in protection against server-side request forgery
- Request Timeouts - Configurable timeouts (default: 30 seconds)
API Reference
OpenApiProvider
The main entry point for loading and configuring OpenAPI specs:
OpenApiHandler
Implements turbomcp_core::handler::McpHandler for use with TurboMCP servers.
The handler exposes:
server_info()— returns the spec'sinfo.title/info.versionlist_tools()— oneToolper non-GET operation (subject to route mapping);metaincludes the originalmethod,path, andoperationIdlist_resources()— oneResourceper GET operation (subject to route mapping);mime_typeisapplication/jsonlist_prompts()— always empty (OpenAPI has no prompt concept)call_tool(name, args, ctx)— dispatches an HTTP request for the matching tool, with SSRF validationread_resource(uri, ctx)— issues the GET for the matching resource URIget_prompt(...)— always returnsprompt_not_found
Tool names use operation_id when present, otherwise {method}_{path} with /
replaced by _ and {} stripped. Resource URIs are
openapi://{method}{path} (e.g. openapi://get/users/{id}).
Error Types
Example
Given this OpenAPI spec:
openapi: 3.0.0
info:
title: Pet Store
version: 1.0.0
paths:
/pets:
get:
operationId: listPets
summary: List all pets
post:
operationId: createPet
summary: Create a pet
/pets/{id}:
get:
operationId: getPet
summary: Get a pet by ID
delete:
operationId: deletePet
summary: Delete a pet
The handler exposes:
Resources:
openapi://get/pets(listPets)openapi://get/pets/{id}(getPet)
Tools:
createPet- Create a petdeletePet- Delete a pet
Running the Example
Schema Handling Notes
$refresolution: references intocomponents.schemasare resolved recursively and inlined into the emitted MCP tool/resource schemas, so consumers never see dangling pointers. Self-referential schemas are handled — the expander detects cycles and preserves the innermost$refunchanged so output stays finite.- Schema composition:
allOf,oneOf,anyOf,discriminator, andnullableround-trip throughserde_jsonas JSON Schema keywords, which downstream MCP clients that speak JSON Schema 2020-12 can consume directly. - Parameter
content: onlyschema-form parameters are extracted; the content-type variant form is not yet converted. - Security schemes: declared schemes are recognized but not automatically applied to outgoing requests; callers supply auth headers manually.
License
MIT