Skip to content

ampeco/public-api-mcp

Repository files navigation

Public API MCP Server

An MCP (Model Context Protocol) server that dynamically exposes a public API defined by an OpenAPI 3 specification.

Quick Start

Development (Stdio Mode)

# 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"

Production (via NPX)

# 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

HTTP Mode (Remote Server)

# 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.

Overview

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.

Usage

Running the Build Pipeline

# 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 dev

The build script:

  1. Parses the OpenAPI spec from the specified path
  2. Processes all endpoints through the optimization pipeline
  3. Generates Zod schemas for runtime validation
  4. 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 build and npm run dev

Development

# Type check without building
npm run type-check

# Run in development mode (build + start server)
npm run dev

Architecture

Build-Time Pipeline

OpenAPI 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)

MCP Server

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_request tool 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

Resource Modes

The server supports two modes for exposing API endpoints:

  1. 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)
  2. 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-tools flag

Running the Server

# Development mode (rebuild + start server)
npm run dev

# Production mode
npm run build  # First time only
npm start

# Custom port
PORT=3001 npm run dev

Server Endpoints

The server uses a hostname-based routing structure where the target API hostname is embedded in the URL path:

  • GET /health: Health check and server statistics
  • POST /{hostname}[/{protocol}]: MCP protocol endpoint with hostname routing
    • {hostname}: Target API hostname (e.g., api.example.com)
    • {protocol}: Optional protocol (http or https, defaults to https)

Examples:

  • POST /api.example.com → Routes to https://api.example.com
  • POST /api.example.com/https → Routes to https://api.example.com
  • POST /api.example.com/http → Routes to http://api.example.com
  • POST /internal.api.company.com/http → Routes to http://internal.api.company.com

Setting Up with Claude Desktop

IMPORTANT: Claude Desktop does not support native MCP resources. You MUST use the --emulate-resources-via-tools flag for Claude Desktop.

Installation via Desktop Extension (.mcpb)

The easiest way to install this MCP server in Claude Desktop is using the Desktop Extension bundle:

Option 1: From Official Directory (Recommended)

  1. Open Claude Desktop
  2. Go to Settings → Extensions
  3. Click "Browse extensions"
  4. Search for "AMPECO Public API"
  5. Click Install and follow the configuration prompts

Option 2: Manual Installation

  1. Download the latest .mcpb file from the releases page
  2. Open Claude Desktop
  3. Go to Settings → Extensions
  4. Click "Install Extension..."
  5. Select the downloaded .mcpb file
  6. Configure the required settings:
    • API Hostname: Your AMPECO API server (e.g., https://api.example.com)
    • Bearer Token: Your AMPECO API authentication token

The extension will automatically operate in resource emulation mode for Claude Desktop compatibility.

Manual Configuration (Advanced)

If you prefer manual configuration or want to customize the setup:

Claude Desktop Configuration

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

Configuration Example

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.com with your actual API hostname
  • your-token-here with your bearer token

After editing the file, restart Claude Desktop for changes to take effect

What is Tool Emulation Mode?

When --emulate-resources-via-tools is enabled, the server provides two additional tools:

  1. list_resources: Discover available API tags (e.g., Users, ChargingSessions)

    • No parameters required
    • Returns list of tags that group related endpoints
  2. read_resource: Read endpoint definitions by URI

    • Parameter: uri (e.g., tag://Users or api://GET/users/{id})
    • Returns full endpoint specification

These tools provide identical functionality to native MCP resources but work through the tools interface that Claude Desktop supports.

Tool Schemas (Emulation Mode)

When --emulate-resources-via-tools is enabled, the following tools are available:

list_resources Tool

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

read_resource Tool

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} or api://{METHOD}{path}
    • Examples: "tag://Users", "api://GET/users/{id}", "api://POST/charging-sessions"

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

When to Use Each Mode

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.

Setting Up with Claude Code

The MCP server supports two transport modes:

  1. Stdio Mode (Recommended): Direct process communication for local development and production
  2. HTTP Mode: Remote server access via HTTP transport

Stdio Mode (Local Development)

For development with hot reloading and build integration:

Option 1: One-Liner (Recommended)

# 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-mcp with your actual project path
  • your-token-here with your API token

Features:

  • Automatically creates .mcp.json configuration
  • Rebuilds on each start for hot reloading
  • All build output redirected to stderr (clean protocol)

Option 2: Manual Configuration

If you prefer to manually edit configuration files:

  1. Set environment variable (optional, for substitution):
export AMPECO_BEARER_TOKEN="your-token-here"
source ~/.bashrc  # or ~/.zshrc
  1. Create .mcp.json in 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}"}
    }
  }
}
  1. Reload: Claude Code will auto-detect the configuration

Stdio Mode (Production via NPX)

For production use without needing the source code:

Option 1: One-Liner (Recommended)

# 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-tools

Replace:

  • your-token-here with your API token
  • https://api.example.com with 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-tools for Claude Desktop compatibility

Option 2: Manual Configuration

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.

Stdio Mode (Production via Global Install)

For faster startup without NPX overhead:

1. Install Globally

npm install -g @ampeco/public-api-mcp

2. Add to Claude Code (One-Liner)

# 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-tools

Or 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"}
    }
  }
}

HTTP Mode (Remote Server)

For shared server access or when multiple clients need to connect:

1. Start the Server

# 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

2. Add to Claude Code (One-Liner)

# 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 /http or /https suffix controls target API protocol
  • Defaults to HTTPS if not specified

Comparison: Stdio vs HTTP Mode

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.

Troubleshooting

Stdio Mode Issues

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:stdio

Problem: Build output interfering with protocol

  • This is fixed in dev:stdio script which redirects build output to stderr
  • For production, run npm run build first, 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 ~/.zshrc

HTTP Mode Issues

Problem: 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:http

Problem: CORS errors

  • The server has CORS enabled for all origins
  • Check browser console for specific error messages

General Issues

Problem: Endpoints not loading

# Verify build artifacts exist
ls -la src/generated/

# Rebuild if needed
npm run build

Problem: Authentication errors

  • Verify your AMPECO_BEARER_TOKEN is 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

Building Desktop Extension (.mcpb)

To package this MCP server as a Desktop Extension for distribution:

# Build and package as .mcpb
npm run package:mcpb

This 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)

What's Included in the Bundle

The Desktop Extension bundle operates in resource emulation mode by default, which means:

  • Full compatibility with Claude Desktop (no native resource support needed)
  • list_resources and read_resource tools for endpoint discovery
  • api_request tool for making authenticated API calls
  • Automatic token management via environment variables

Users only need to provide two configuration values during installation:

  1. API Hostname: The AMPECO API server URL
  2. Bearer Token: Their authentication token

Technology Stack

Runtime

  • Language: TypeScript / Node.js (ES2022 modules)
  • Server: Express
  • MCP SDK: @modelcontextprotocol/sdk
  • HTTP Client: node-fetch
  • Validation: zod

Build-Time

  • OpenAPI Parser: @readme/openapi-parser
  • Build Tools: tsx, TypeScript compiler

Development

  • Type Checking: TypeScript (strict mode)
  • Testing: Vitest (planned)

License

MIT

About

MCP server for AMPECO Public API - http://developers.ampeco.com/

Resources

License

Stars

Watchers

Forks

Packages

No packages published