Skip to main content
Glama
PowerDuckie

openapi-mcp-server

by PowerDuckie
README.md
# @powerduck/openapi-mcp-server

A production-oriented TypeScript library and runtime that converts OpenAPI documents into MCP (Model Context Protocol) services. Built on top of `@powerduck/openapi-parser` for robust OpenAPI validation and dereferencing.

## Features

- **Tools** generated from OpenAPI operations with full parameter serialization
- **Prompts** generated from API metadata and operations
- **Resources** generated from the OpenAPI catalog
- **HTTP (SSE)** and **STDIO** MCP transports
- **Admin Web UI** for managing specs and services
- **Persistent runtime state** with config storage
- **Strong validation** and safer request execution
- **Dual module support**: ESM and CommonJS
- **TypeScript-first** with full type definitions
- **91+ tests** covering core utilities, spec loading, and module exports

## Install

```bash
npm install @powerduck/openapi-mcp-server
```

## Quick Start

### CLI Usage

#### Web Mode (with Admin UI)

```bash
openapi-mcp serve \
  --transport web \
  --port 3000 \
  --host 127.0.0.1 \
  --api-key your-admin-key
```

#### STDIO Mode

```bash
openapi-mcp serve \
  --transport stdio \
  --spec ./openapi.yaml \
  --base-url https://api.example.com
```

### Programmatic API

#### Load and Validate an OpenAPI Document

```typescript
import { loadOpenApiSpec, parseSpecContent } from "@powerduck/openapi-mcp-server";

// Load from file (JSON or YAML)
const spec = await loadOpenApiSpec("./openapi.yaml");

// Parse from string content
const specFromText = await parseSpecContent(
  '{"openapi": "3.1.0", "info": {...}, "paths": {...}}',
  false, // isYaml
);
```

#### Generate MCP Tools

```typescript
import { generateTools, buildBindingIndex } from "@powerduck/openapi-mcp-server";

const tools = generateTools(spec);
const bindingIndex = buildBindingIndex(spec);

// tools is an array of MCP Tool definitions
// bindingIndex maps operationIds to tool names
```

#### Generate Prompts and Resources

```typescript
import { generatePrompts, generateResources } from "@powerduck/openapi-mcp-server";

const prompts = generatePrompts(spec);
const resources = generateResources(spec);
```

#### Build an MCP Server

```typescript
import { buildMcpServer, startStdioServer, attachSseRoutes } from "@powerduck/openapi-mcp-server";
import express from "express";

// Build a server with custom spec and context providers
const server = buildMcpServer({
  specProvider: async () => spec,
  contextProvider: async () => ({ baseUrl: "https://api.example.com" }),
});

// STDIO transport
await startStdioServer(server);

// HTTP/SSE transport
const app = express();
attachSseRoutes(app, server, { path: "/mcp" });
app.listen(3000);
```

#### Execute Tool Calls

```typescript
import { executeToolCall } from "@powerduck/openapi-mcp-server";

const result = await executeToolCall({
  toolName: "get_user",
  arguments: { id: "123" },
  spec,
  baseUrl: "https://api.example.com",
  headers: { Authorization: "Bearer token" },
});
```

#### Spec Utility Functions

```typescript
import {
  iterateOperations,
  findOperationById,
  findDuplicateOperationIds,
  assertUniqueOperationIds,
  extractPathTemplateVariables,
  synthesizeOperationId,
  ensureUniqueName,
  collectOperationParameters,
  effectiveStyle,
  effectiveExplode,
} from "@powerduck/openapi-mcp-server";

// Iterate all operations
for (const op of iterateOperations(spec)) {
  console.log(op.method, op.path, op.operation?.operationId);
}

// Find operation by ID
const operation = findOperationById(spec, "getUser");

// Check for duplicate operation IDs
const duplicates = findDuplicateOperationIds(spec);

// Extract path variables
const vars = extractPathTemplateVariables("/users/{userId}/posts/{postId}");
// => ["userId", "postId"]
```

#### Build HTTP Requests

```typescript
import { buildRequest } from "@powerduck/openapi-mcp-server";

const request = buildRequest({
  operation,
  pathItem,
  arguments: { id: "123", include: ["profile", "posts"] },
  baseUrl: "https://api.example.com",
});

// request contains: method, url, headers, body
```

#### Admin Server and Auth

```typescript
import { startAdminServer, createAuthMiddleware } from "@powerduck/openapi-mcp-server";

const app = await startAdminServer({
  port: 3000,
  host: "127.0.0.1",
  apiKey: "your-admin-key",
});

// Or use auth middleware in your own Express app
import express from "express";
const myApp = express();
myApp.use("/admin", createAuthMiddleware({ apiKey: "secret" }));
```

## Project Structure

```
src/
├── core/
│   ├── openapi-loader.ts    # Spec loading, validation, dereferencing
│   ├── spec-utils.ts        # Operation traversal, parameter normalization
│   ├── tool-generator.ts    # MCP tool generation from operations
│   ├── request-builder.ts   # HTTP request construction with serialization
│   ├── http-executor.ts     # Safe HTTP request execution
│   └── global-utils.ts      # Shared utilities (IDs, error detection)
├── mcp/
│   ├── create-server.ts     # MCP server construction
│   ├── transport-stdio.ts   # STDIO transport
│   └── transport-http.ts    # HTTP/SSE transport
├── registry/
│   ├── prompt-registry.ts   # Prompt generation and resolution
│   └── resource-registry.ts # Resource generation and reading
├── runtime/
│   └── service-registry.ts  # Runtime service management
├── server/
│   ├── admin-server.ts      # Admin HTTP server with Web UI
│   └── auth.ts              # Authentication middleware
├── config/
│   └── config-store.ts      # Persistent configuration storage
├── webui/
│   └── index.html           # Admin Web UI
├── types.ts                 # Shared TypeScript types
├── cli.ts                   # CLI entry point
└── index.ts                 # Library exports
```

## Web UI

The admin UI supports:

- Upload and paste OpenAPI documents (JSON or YAML)
- View generated tools, prompts, and resources
- Inspect running runtime services
- Stop services
- Basic MCP debugging hints
- SSE endpoint discovery
- STDIO configuration guidance

## Testing

```bash
# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage
```

Test coverage includes:

- **Global utilities**: ID generation, abort error detection
- **Spec utilities**: operation iteration, parameter normalization, name uniqueness
- **OpenAPI loader**: JSON/YAML parsing, validation, dereferencing, error handling
- **Module exports**: all public API surface verification

## Production Notes

This version is production-oriented. For full SaaS deployment, consider adding:

- Tenant isolation
- Database-backed project registry
- Rate limits
- Audit logs
- Role-based access control (RBAC)
- Secure secret storage
- Upstream host allowlists

## Dependencies

- `@powerduck/openapi-parser` — OpenAPI validation, dereferencing, and upgrade (replaces `@scalar/openapi-parser`)
- `@modelcontextprotocol/sdk` — MCP protocol implementation
- `express` — HTTP server for admin UI and SSE transport
- `axios` — HTTP client for tool execution
- `commander` — CLI framework
- `js-yaml` — YAML parsing
- `multer` — File upload handling
- `cors` — CORS middleware
- `terser` — Minification for embedded assets

## License

MIT © Powerduck limited

## Important Implementation Policy

All source comments are written in American English. No Chinese characters are permitted in the codebase.