@orchestraprime/rest-mcp-bridge
v1.0.0
Published
Generic YAML-configuration-driven framework that converts any REST API into an MCP server
Maintainers
Readme
@orchestraprime/rest-mcp-bridge
Convert any REST API into an MCP server with YAML configuration.
A generic framework that lets you expose REST APIs as Model Context Protocol servers for Claude, using declarative YAML configuration files and optional TypeScript escape hatches.
Features
- YAML-driven -- Define tools, resources, and API connections in YAML
- Zero boilerplate -- 4-line entry point boots a full MCP server
- 4-level escape hatch system -- Override any stage of the request pipeline with TypeScript
- Built-in caching -- TTL-based response caching with per-tool configuration
- Schema generation -- Auto-generates Zod + JSON Schema from YAML input definitions
- Response transforms -- JSONPath-lite expressions with pipe functions
- Template engine -- Mustache-like markdown formatting
- Retry with backoff -- Configurable exponential backoff for transient failures
- Structured logging -- SEC-2 compliant (no secrets logged)
- API key validation -- Pattern-based key validation at startup
Quick Start
import { loadConfig, createServer, connectStdio, loadEscapeHatches } from '@orchestraprime/rest-mcp-bridge';
const config = await loadConfig('./config');
await loadEscapeHatches(config);
const bridge = createServer(config);
await connectStdio(bridge);Configuration Structure
config/
server.yaml Server name, version, defaults
apis.yaml API connections (base_url, auth, retry)
tools/
my-tool.yaml One file per MCP tool
resources/
my-resource.yaml One file per MCP resourceserver.yaml
name: my-mcp-server
version: 1.0.0
description: My MCP server
defaults:
cache_ttl: 300
timeout: 25000
max_retries: 3apis.yaml
my_api:
base_url: https://api.example.com
timeout: 25000
auth:
type: api-key
header: x-api-key
env_var: MY_API_KEY
key_pattern: "^mk_[a-zA-Z0-9]{24,}$"Tool YAML
name: search_items
description: Search for items by query
api: my_api
endpoint:
method: POST
path: /v1/search
input:
properties:
query:
type: string
description: Search query
limit:
type: integer
description: Max results
optional: true
default: 10
min: 1
max: 50
required:
- query
response:
results: "$.results"
total: "$.metadata.total_count"
format:
empty: "No results found for your query."
header: "# Search Results ({{total}} found)\n\n"
item: "- **{{title}}** ({{source}})\n {{summary}}\n"
cache:
ttl: 300Escape Hatch System
When YAML configuration isn't enough, use TypeScript escape hatches:
| Level | Hook | Use Case |
|-------|------|----------|
| L1 | pre_request | Inject local data, skip API call |
| L2 | post_response | Transform complex nested responses |
| L3 | custom_formatter | Status-dependent output formatting |
| L4 | handler | Full custom logic, no API call |
Reference escape hatches in your tool YAML:
name: my_tool
pre_request: ./escape-hatches/my-tool-hook.ts
post_response: ./escape-hatches/my-tool-transform.ts
custom_formatter: ./escape-hatches/my-tool-format.ts
handler: ./escape-hatches/my-tool-handler.ts # L4: replaces entire pipelineEscape Hatch Signatures
import type {
PreRequestHook,
PostResponseTransform,
CustomFormatter,
FullHandler,
} from '@orchestraprime/rest-mcp-bridge';
// L1: Pre-request hook
export const preRequest: PreRequestHook = async (input, context) => {
return { skip: true, localData: { /* ... */ } };
};
// L2: Post-response transform
export const postResponse: PostResponseTransform = async (raw) => {
return { /* normalized data */ };
};
// L3: Custom formatter
export const customFormatter: CustomFormatter = async (data) => {
return '# Formatted output\n...';
};
// L4: Full handler
export const handler: FullHandler = async (input, context) => {
return { content: [{ type: 'text', text: '...' }] };
};Pipe Functions
Transform response values with built-in pipe functions:
response:
name: "$.name | uppercase"
date: "$.created_at | date_format"
count: "$.total | default:0"
items: "$.results | take:5"
source: "$.authority | lowercase"Available pipes: uppercase, lowercase, trim, truncate:N, default:value, date_format, round:N, take:N, join:separator, count, first, last, flatten, sort, unique, and more.
API
Exports
// Core
export { loadConfig } from './config-loader';
export { createServer, connectStdio } from './server-factory';
export { loadEscapeHatches } from './escape-hatch-loader';
// Types (for escape hatches)
export type {
PreRequestHook, PostResponseTransform,
CustomFormatter, FullHandler,
ToolContext, McpToolResult,
BridgeConfig, ToolConfig, ResourceConfig,
} from './types';
// Utilities (for escape hatches)
export { CacheManager } from './cache-manager';
export { withRetry } from './retry';
export { logger } from './logger';
export { BridgeError, ValidationError, /* ... */ } from './error-formatter';Testing
npm test # 168 tests
npm test -- --coverage # 97.5% statement coverageLicense
MIT -- see LICENSE for details.
