An MCP (Model Context Protocol) server that dynamically exposes a public API defined by an OpenAPI 3 specification.
# One-liner to add dev server (with hot reload)
claude mcp add --transport stdio ampeco-api-dev \
--env AMPECO_BEARER_TOKEN=your-token-here \
-- bash -c "cd /absolute/path/to/public-api-mcp && npm run dev:stdio"# One-liner to add production server
claude mcp add --transport stdio ampeco-api \
--env AMPECO_BEARER_TOKEN=your-token-here \
-- npx -y @ampeco/public-api-mcp --stdio --hostname https://api.example.com# Start the server first
PORT=3001 npm run dev:http
# Then add to Claude Code
claude mcp add --transport http ampeco-api \
http://localhost:3001/api.example.com \
--header "Authorization: Bearer your-token-here"See Setting Up with Claude Code for detailed instructions and troubleshooting.
This project transforms OpenAPI specifications into optimized, self-contained API definitions that can be served through the Model Context Protocol. It features a sophisticated build pipeline that processes OpenAPI specs at build time to minimize runtime overhead and reduce token usage.
# Install dependencies
npm install
# Run the build pipeline with default path
npm run build
# Run the build pipeline with custom OpenAPI spec path
OPENAPI_SPEC_PATH=/path/to/your/openapi.yaml npm run build
# Or set it as an environment variable for multiple commands
export OPENAPI_SPEC_PATH=/path/to/your/openapi.yaml
npm run build
npm run devThe build script:
- Parses the OpenAPI spec from the specified path
- Processes all endpoints through the optimization pipeline
- Generates Zod schemas for runtime validation
- Outputs optimized artifacts to
src/generated/
Configuration Options:
OPENAPI_SPEC_PATH: Path to the OpenAPI YAML/JSON file (relative or absolute)- Can be set as an environment variable or passed directly to npm commands
- Used by both
npm run buildandnpm run dev
# Type check without building
npm run type-check
# Run in development mode (build + start server)
npm run devOpenAPI Spec
↓
[Parser] Bundle & Resolve References
↓
[Extractor] Extract Endpoints & Security
↓
[Flattener] Flatten Schemas (allOf, nested objects)
↓
[Optimizer] Minify & Optimize
↓
[Zod Generator] Generate Validation Schemas
↓
Generated Artifacts (endpoints.json, schemas.ts)
The server provides a complete MCP implementation for accessing your OpenAPI-defined API:
- Dual Transport Support: Both Stdio (local) and HTTP (remote) transports
- Flexible Resource Mode: Native MCP resources OR tool-based emulation for Claude Desktop compatibility
- Dynamic Resources: All API endpoints exposed as MCP resources with full schema details
- API Request Tool: Fully typed
api_requesttool with automatic authentication and parameter validation - Stateless Architecture: No session state required - all parameters provided per request
- Zero Configuration: Pre-processed data loads instantly, no config files needed
- MCP Protocol Compliance: Full implementation of MCP Streamable HTTP transport specification
The server supports two modes for exposing API endpoints:
-
Native Resources Mode (Default): Uses native MCP resources for endpoint discovery
- Best for: MCP clients that fully support the resources capability
- Features: Hierarchical 3-tier navigation (tags → endpoints → details)
-
Tool Emulation Mode: Exposes resources through tools (
list_resources,read_resource)- Required for Claude Desktop (does not support native MCP resources)
- Provides identical functionality through tool-based interface
- Enable with
--emulate-resources-via-toolsflag
# Development mode (rebuild + start server)
npm run dev
# Production mode
npm run build # First time only
npm start
# Custom port
PORT=3001 npm run devThe server uses a hostname-based routing structure where the target API hostname is embedded in the URL path:
GET /health: Health check and server statisticsPOST /{hostname}[/{protocol}]: MCP protocol endpoint with hostname routing{hostname}: Target API hostname (e.g.,api.example.com){protocol}: Optional protocol (httporhttps, defaults tohttps)
Examples:
POST /api.example.com→ Routes tohttps://api.example.comPOST /api.example.com/https→ Routes tohttps://api.example.comPOST /api.example.com/http→ Routes tohttp://api.example.comPOST /internal.api.company.com/http→ Routes tohttp://internal.api.company.com
IMPORTANT: Claude Desktop does not support native MCP resources. You MUST use the --emulate-resources-via-tools flag for Claude Desktop.
The easiest way to install this MCP server in Claude Desktop is using the Desktop Extension bundle:
- Open Claude Desktop
- Go to Settings → Extensions
- Click "Browse extensions"
- Search for "AMPECO Public API"
- Click Install and follow the configuration prompts
- Download the latest
.mcpbfile from the releases page - Open Claude Desktop
- Go to Settings → Extensions
- Click "Install Extension..."
- Select the downloaded
.mcpbfile - Configure the required settings:
- API Hostname: Your AMPECO API server (e.g.,
https://api.example.com) - Bearer Token: Your AMPECO API authentication token
- API Hostname: Your AMPECO API server (e.g.,
The extension will automatically operate in resource emulation mode for Claude Desktop compatibility.
If you prefer manual configuration or want to customize the setup:
Claude Desktop uses a configuration file called claude_desktop_config.json located at:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
You can also access this file through Claude Desktop: Settings → Developer → Edit Config
Add this to your claude_desktop_config.json:
{
"mcpServers": {
"ampeco-api": {
"command": "npx",
"args": [
"-y",
"@ampeco/public-api-mcp",
"--stdio",
"--hostname",
"https://api.example.com",
"--emulate-resources-via-tools"
],
"env": {
"AMPECO_BEARER_TOKEN": "your-token-here"
}
}
}
}Replace:
https://api.example.comwith your actual API hostnameyour-token-herewith your bearer token
After editing the file, restart Claude Desktop for changes to take effect
When --emulate-resources-via-tools is enabled, the server provides two additional tools:
-
list_resources: Discover available API tags (e.g., Users, ChargingSessions)- No parameters required
- Returns list of tags that group related endpoints
-
read_resource: Read endpoint definitions by URI- Parameter:
uri(e.g.,tag://Usersorapi://GET/users/{id}) - Returns full endpoint specification
- Parameter:
These tools provide identical functionality to native MCP resources but work through the tools interface that Claude Desktop supports.
When --emulate-resources-via-tools is enabled, the following tools are available:
Description: List all available API tags. This emulates the native MCP resources/list functionality. Returns a list of tags that group related endpoints together (e.g., Users, ChargingSessions, Connectors). Each tag can then be read using the read_resource tool with tag:// URIs.
Parameters: None
Returns: JSON object with resources array containing:
{
"resources": [
{
"uri": "tag://Users",
"name": "Users",
"description": "15 endpoints tagged with 'Users'",
"mimeType": "application/json"
},
{
"uri": "tag://ChargingSessions",
"name": "ChargingSessions",
"description": "8 endpoints tagged with 'ChargingSessions'",
"mimeType": "application/json"
}
]
}Example Usage:
Call list_resources tool → Get list of all API tags
Description: Read a specific resource by URI. This emulates the native MCP resources/read functionality. Supports two URI formats: tag://{TagName} to read all endpoints within a tag, and api://{METHOD}{path} to read detailed endpoint specifications. You MUST use this tool to read endpoint definitions before calling api_request.
Parameters:
uri(string, required): The resource URI to read- Format:
tag://{TagName}orapi://{METHOD}{path} - Examples:
"tag://Users","api://GET/users/{id}","api://POST/charging-sessions"
- Format:
Returns (for tag URIs):
{
"tag": "Users",
"count": 15,
"endpoints": [
{
"uri": "api://GET/users/{id}",
"method": "GET",
"path": "/users/{id}",
"summary": "Get user by ID",
"operationId": "getUser"
}
]
}Returns (for api URIs):
{
"path": "/users/{id}",
"method": "GET",
"operationId": "getUser",
"summary": "Get user by ID",
"description": "Retrieves detailed information about a specific user",
"parameters": [...],
"requestBody": {...},
"responses": {...},
"security": "Include token in Authorization header as: Authorization: Bearer <token>"
}Example Usage:
1. Call read_resource with uri="tag://Users" → Get all endpoints in Users tag
2. Call read_resource with uri="api://GET/users/{id}" → Get full endpoint specification
3. Call api_request with correct parameters → Make the actual API call
| Mode | Use For | Clients |
|---|---|---|
| Native Resources (default) | MCP clients that fully support resources | Claude Code, MCP Inspector |
Tool Emulation (--emulate-resources-via-tools) |
Clients without resource support | Claude Desktop |
Important Distinction:
- Claude Code (the CLI tool): Supports native MCP resources - use default mode
- Claude Desktop (the desktop app): Does NOT support resources - use
--emulate-resources-via-tools
Rule of thumb: If you're using Claude Desktop, always add --emulate-resources-via-tools. If using Claude Code, use default mode.
The MCP server supports two transport modes:
- Stdio Mode (Recommended): Direct process communication for local development and production
- HTTP Mode: Remote server access via HTTP transport
For development with hot reloading and build integration:
# Add dev server with a single command
claude mcp add --transport stdio ampeco-api-dev \
--env AMPECO_BEARER_TOKEN=your-token-here \
-- bash -c "cd /absolute/path/to/public-api-mcp && npm run dev:stdio"Replace:
/absolute/path/to/public-api-mcpwith your actual project pathyour-token-herewith your API token
Features:
- Automatically creates
.mcp.jsonconfiguration - Rebuilds on each start for hot reloading
- All build output redirected to stderr (clean protocol)
If you prefer to manually edit configuration files:
- Set environment variable (optional, for substitution):
export AMPECO_BEARER_TOKEN="your-token-here"
source ~/.bashrc # or ~/.zshrc- Create
.mcp.jsonin project root:
{
"mcpServers": {
"ampeco-api-dev": {
"type": "stdio",
"command": "bash",
"args": ["-c", "cd /absolute/path/to/public-api-mcp && npm run dev:stdio"],
"env": {"AMPECO_BEARER_TOKEN": "${AMPECO_BEARER_TOKEN}"}
}
}
}- Reload: Claude Code will auto-detect the configuration
For production use without needing the source code:
# Add production server with a single command (native resources)
claude mcp add --transport stdio ampeco-api \
--env AMPECO_BEARER_TOKEN=your-token-here \
-- npx -y @ampeco/public-api-mcp --stdio --hostname https://api.example.com
# With tool emulation mode (if client doesn't support resources)
claude mcp add --transport stdio ampeco-api \
--env AMPECO_BEARER_TOKEN=your-token-here \
-- npx -y @ampeco/public-api-mcp --stdio --hostname https://api.example.com --emulate-resources-via-toolsReplace:
your-token-herewith your API tokenhttps://api.example.comwith your target API hostname
Features:
- NPX downloads and caches the package automatically
- No source code or build required
- Works from any directory
- Add
--emulate-resources-via-toolsfor Claude Desktop compatibility
Create .mcp.json in your project or home directory:
Native Resources Mode:
{
"mcpServers": {
"ampeco-api": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@ampeco/public-api-mcp",
"--stdio",
"--hostname",
"https://api.example.com"
],
"env": {
"AMPECO_BEARER_TOKEN": "your-token-here"
}
}
}
}Tool Emulation Mode (for Claude Desktop):
{
"mcpServers": {
"ampeco-api": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@ampeco/public-api-mcp",
"--stdio",
"--hostname",
"https://api.example.com",
"--emulate-resources-via-tools"
],
"env": {
"AMPECO_BEARER_TOKEN": "your-token-here"
}
}
}
}Using environment variables (more secure):
export AMPECO_BEARER_TOKEN="your-token-here"Then use "${AMPECO_BEARER_TOKEN}" in the JSON config.
For faster startup without NPX overhead:
npm install -g @ampeco/public-api-mcp# Add globally installed server (native resources)
claude mcp add --transport stdio ampeco-api \
--env AMPECO_BEARER_TOKEN=your-token-here \
-- ampeco-api-mcp --stdio --hostname https://api.example.com
# With tool emulation mode (for Claude Desktop)
claude mcp add --transport stdio ampeco-api \
--env AMPECO_BEARER_TOKEN=your-token-here \
-- ampeco-api-mcp --stdio --hostname https://api.example.com --emulate-resources-via-toolsOr manual configuration in .mcp.json:
Native Resources Mode:
{
"mcpServers": {
"ampeco-api": {
"type": "stdio",
"command": "ampeco-api-mcp",
"args": ["--stdio", "--hostname", "https://api.example.com"],
"env": {"AMPECO_BEARER_TOKEN": "your-token-here"}
}
}
}Tool Emulation Mode (for Claude Desktop):
{
"mcpServers": {
"ampeco-api": {
"type": "stdio",
"command": "ampeco-api-mcp",
"args": [
"--stdio",
"--hostname",
"https://api.example.com",
"--emulate-resources-via-tools"
],
"env": {"AMPECO_BEARER_TOKEN": "your-token-here"}
}
}
}For shared server access or when multiple clients need to connect:
# Development mode (native resources)
PORT=3001 npm run dev:http
# Development mode (tool emulation)
PORT=3001 npm start -- --http --port 3001 --emulate-resources-via-tools
# Production mode (native resources)
npm run build # First time only
PORT=3001 npm start -- --http --port 3001
# Production mode (tool emulation)
npm run build # First time only
PORT=3001 npm start -- --http --port 3001 --emulate-resources-via-tools# Add HTTP server with a single command
claude mcp add --transport http ampeco-api \
http://localhost:3001/api.example.com \
--header "Authorization: Bearer your-token-here"With protocol override (use HTTP for target API instead of HTTPS):
claude mcp add --transport http ampeco-api \
http://localhost:3001/api.example.com/http \
--header "Authorization: Bearer your-token-here"Or manual configuration in .mcp.json:
{
"mcpServers": {
"ampeco-api-http": {
"type": "http",
"url": "http://localhost:3001/api.example.com",
"headers": {"Authorization": "Bearer your-token-here"}
}
}
}Notes:
- Server must be running before connecting
- Target API hostname is in the URL path
- Optional
/httpor/httpssuffix controls target API protocol - Defaults to HTTPS if not specified
| Feature | Stdio Mode | HTTP Mode |
|---|---|---|
| Use Case | Local development, single user | Remote access, multiple clients |
| Setup Complexity | Simple (just config file) | Requires running server |
| Performance | Faster (no HTTP overhead) | Slightly slower (HTTP latency) |
| Security | More secure (local only) | Network exposure (use HTTPS in prod) |
| Hot Reload | Yes (dev mode) | Requires server restart |
| Multi-Client | No (one client at a time) | Yes (concurrent clients) |
| Memory Usage | Lower (~30MB per instance) | Higher (~50MB + per-request) |
Recommendation: Use stdio mode for development and single-user production. Use HTTP mode for shared servers or when multiple clients need concurrent access.
Problem: Server not starting or connection fails
# List configured MCP servers
claude mcp list
# Check status
claude mcp status ampeco-api-dev
# Remove and re-add the server
claude mcp remove ampeco-api-dev
claude mcp add --transport stdio ampeco-api-dev \
--env AMPECO_BEARER_TOKEN=your-token \
-- bash -c "cd /path/to/public-api-mcp && npm run dev:stdio"
# Verify the command works standalone
cd /path/to/public-api-mcp
AMPECO_BEARER_TOKEN=your-token npm run dev:stdioProblem: Build output interfering with protocol
- This is fixed in
dev:stdioscript which redirects build output to stderr - For production, run
npm run buildfirst, then use the compiled CLI
Problem: Environment variables not loading
# Verify environment variable is set
echo $AMPECO_BEARER_TOKEN
# Reload shell configuration
source ~/.bashrc # or ~/.zshrcProblem: Server not accessible
# Test server health
curl http://localhost:3001/health
# Check if port is in use
lsof -i :3001
# Try a different port
PORT=3002 npm run dev:httpProblem: CORS errors
- The server has CORS enabled for all origins
- Check browser console for specific error messages
Problem: Endpoints not loading
# Verify build artifacts exist
ls -la src/generated/
# Rebuild if needed
npm run buildProblem: Authentication errors
- Verify your
AMPECO_BEARER_TOKENis correct - Check the token has proper permissions for the API
- Test the token directly with the API:
curl -H "Authorization: Bearer your-token" \ https://api.example.com/health
To package this MCP server as a Desktop Extension for distribution:
# Build and package as .mcpb
npm run package:mcpbThis creates a .mcpb file (e.g., ampeco-api-mcp-0.3.0.mcpb) that can be:
- Distributed to users for manual installation
- Submitted to the official Claude Desktop extensions directory
- Shared within your organization
The .mcpb file is a self-contained bundle including:
- Compiled server code (
dist/) - All dependencies (via
package.json) - Extension metadata (
manifest.json) - Documentation (
README.md)
The Desktop Extension bundle operates in resource emulation mode by default, which means:
- Full compatibility with Claude Desktop (no native resource support needed)
list_resourcesandread_resourcetools for endpoint discoveryapi_requesttool for making authenticated API calls- Automatic token management via environment variables
Users only need to provide two configuration values during installation:
- API Hostname: The AMPECO API server URL
- Bearer Token: Their authentication token
- Language: TypeScript / Node.js (ES2022 modules)
- Server: Express
- MCP SDK:
@modelcontextprotocol/sdk - HTTP Client:
node-fetch - Validation:
zod
- OpenAPI Parser:
@readme/openapi-parser - Build Tools: tsx, TypeScript compiler
- Type Checking: TypeScript (strict mode)
- Testing: Vitest (planned)
MIT