Merge aaec9c77ee4ce24c4a7cccffa0ace2ba4f286194 into 8ee9fc383dedff93043ed8a67107ee6691f19642
This commit is contained in:
commit
e4b8fe59c7
49
README.md
49
README.md
@ -20,6 +20,7 @@ This CLI tool automates the generation of MCP-compatible servers that proxy requ
|
||||
- 🔌 **Multiple Transports**: Communicate over stdio, SSE via Hono, or StreamableHTTP.
|
||||
- 🧰 **Project Scaffold**: Generates a complete Node.js project with `tsconfig.json`, `package.json`, and entry point.
|
||||
- 🧪 **Built-in HTML Test Clients**: Test API interactions visually in your browser (for web-based transports).
|
||||
- 📊 **Analytics & Telemetry**: Optional MCPcat analytics and OpenTelemetry support for monitoring and debugging.
|
||||
|
||||
---
|
||||
|
||||
@ -44,6 +45,15 @@ openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir -
|
||||
|
||||
# Generate an MCP StreamableHTTP server
|
||||
openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir --transport=streamable-http --port=3000
|
||||
|
||||
# Generate with MCPcat analytics enabled
|
||||
openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir --with-mcpcat
|
||||
|
||||
# Generate with OpenTelemetry tracing enabled
|
||||
openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir --with-otel
|
||||
|
||||
# Generate with both MCPcat analytics and OpenTelemetry
|
||||
openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir --with-mcpcat --with-otel
|
||||
```
|
||||
|
||||
### CLI Options
|
||||
@ -58,6 +68,8 @@ openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir -
|
||||
| `--transport` | `-t` | Transport mode: `"stdio"` (default), `"web"`, or `"streamable-http"` | `"stdio"` |
|
||||
| `--port` | `-p` | Port for web-based transports | `3000` |
|
||||
| `--default-include` | | Default behavior for x-mcp filtering. Accepts `true` or `false` (case-insensitive). `true` = include by default, `false` = exclude by default. | `true` |
|
||||
| `--with-mcpcat` | | Enable MCPcat product analytics for usage insights and debugging | `false` |
|
||||
| `--with-otel` | | Enable OpenTelemetry (OTLP) exporters for distributed tracing and logging | `false` |
|
||||
| `--force` | | Overwrite existing files in the output directory without confirmation | `false` |
|
||||
|
||||
## 📦 Programmatic API
|
||||
@ -168,6 +180,43 @@ Configure auth credentials in your environment:
|
||||
|
||||
---
|
||||
|
||||
## 📊 Analytics & Telemetry
|
||||
|
||||
### MCPcat Analytics
|
||||
[MCPcat](https://mcpcat.io) provides product analytics and live debugging tools specifically designed for MCP servers. When enabled with `--with-mcpcat`, your generated server will include:
|
||||
|
||||
- Usage tracking and analytics
|
||||
- Tool call monitoring
|
||||
- Error detection and reporting
|
||||
- Performance insights
|
||||
|
||||
To use MCPcat:
|
||||
1. Sign up for free at [mcpcat.io](https://mcpcat.io)
|
||||
2. Get your project ID
|
||||
3. Set the `MCPCAT_PROJECT_ID` environment variable
|
||||
|
||||
### OpenTelemetry Support
|
||||
Enable distributed tracing and logging with `--with-otel` to integrate with your existing observability stack:
|
||||
|
||||
- OTLP trace exporters
|
||||
- Distributed request tracing
|
||||
- Performance metrics
|
||||
- Integration with popular observability platforms (Datadog, New Relic, Grafana, etc.)
|
||||
|
||||
Configure the OTLP endpoint with the `OTLP_ENDPOINT` environment variable.
|
||||
|
||||
### Combined Usage
|
||||
Use both flags together (`--with-mcpcat --with-otel`) to get the benefits of both MCPcat's MCP-specific analytics and OpenTelemetry's broader observability ecosystem.
|
||||
|
||||
#### Environment Variables
|
||||
Configure analytics and telemetry:
|
||||
|
||||
| Variable | Description | Required When |
|
||||
| -------------------- | -------------------------------------------------------- | ------------------ |
|
||||
| `MCPCAT_PROJECT_ID` | Your MCPcat project ID from [mcpcat.io](https://mcpcat.io) | `--with-mcpcat` |
|
||||
| `OTLP_ENDPOINT` | OpenTelemetry collector endpoint URL | `--with-otel` |
|
||||
|
||||
|
||||
## 🔎 Filtering Endpoints with OpenAPI Extensions
|
||||
|
||||
You can control which operations are exposed as MCP tools using a vendor extension flag `x-mcp`. This extension is supported at the root, path, and operation levels. By default, endpoints are included unless explicitly excluded.
|
||||
|
||||
@ -3,15 +3,18 @@
|
||||
*/
|
||||
import { OpenAPIV3 } from 'openapi-types';
|
||||
import { getEnvVarName } from '../utils/security.js';
|
||||
import { CliOptions } from '../types/index.js';
|
||||
|
||||
/**
|
||||
* Generates the content of .env.example file for the MCP server
|
||||
*
|
||||
* @param securitySchemes Security schemes from the OpenAPI spec
|
||||
* @param options CLI options
|
||||
* @returns Content for .env.example file
|
||||
*/
|
||||
export function generateEnvExample(
|
||||
securitySchemes?: OpenAPIV3.ComponentsObject['securitySchemes']
|
||||
securitySchemes?: OpenAPIV3.ComponentsObject['securitySchemes'],
|
||||
options?: CliOptions
|
||||
): string {
|
||||
let content = `# MCP Server Environment Variables
|
||||
# Copy this file to .env and fill in the values
|
||||
@ -57,6 +60,19 @@ LOG_LEVEL=info
|
||||
content += `# No API authentication required\n`;
|
||||
}
|
||||
|
||||
// Add MCPcat environment variables if enabled
|
||||
if (options?.withMcpcat) {
|
||||
content += `\n# MCPcat -- MCP product analytics and live debugging tools`;
|
||||
content += `\n# Sign up and get your project ID for free at https://mcpcat.io\n`;
|
||||
content += `MCPCAT_PROJECT_ID=proj_0000000 # Replace with your MCPcat project ID\n`;
|
||||
}
|
||||
|
||||
// Add OpenTelemetry environment variables if enabled
|
||||
if (options?.withOtel) {
|
||||
content += `\n# OpenTelemetry Configuration for logging and traces\n`;
|
||||
content += `OTLP_ENDPOINT=http://localhost:4318/v1/traces # OTLP collector endpoint\n`;
|
||||
}
|
||||
|
||||
content += `\n# Add any other environment variables your API might need\n`;
|
||||
|
||||
return content;
|
||||
|
||||
@ -1,17 +1,21 @@
|
||||
import { CliOptions } from '../types/index.js';
|
||||
|
||||
/**
|
||||
* Generates the content of package.json for the MCP server
|
||||
*
|
||||
* @param serverName Server name
|
||||
* @param serverVersion Server version
|
||||
* @param transportType Type of transport to use (stdio, web, or streamable-http)
|
||||
* @param options CLI options
|
||||
* @returns JSON string for package.json
|
||||
*/
|
||||
export function generatePackageJson(
|
||||
serverName: string,
|
||||
serverVersion: string,
|
||||
transportType: string = 'stdio'
|
||||
options: CliOptions
|
||||
): string {
|
||||
const transportType = options.transport || 'stdio';
|
||||
const includeWebDeps = transportType === 'web' || transportType === 'streamable-http';
|
||||
const includeMcpcat = options.withMcpcat || options.withOtel;
|
||||
|
||||
const packageData: any = {
|
||||
name: serverName,
|
||||
@ -36,6 +40,7 @@ export function generatePackageJson(
|
||||
dotenv: '^16.4.5',
|
||||
zod: '^3.24.3',
|
||||
'json-schema-to-zod': '^2.6.1',
|
||||
...(includeMcpcat ? { mcpcat: '^0.1.5' } : {}),
|
||||
},
|
||||
devDependencies: {
|
||||
'@types/node': '^22.15.2',
|
||||
|
||||
@ -9,6 +9,46 @@ import {
|
||||
} from '../utils/code-gen.js';
|
||||
import { generateExecuteApiToolFunction } from '../utils/security.js';
|
||||
|
||||
/**
|
||||
* Generates MCPcat tracking code based on options
|
||||
*/
|
||||
function generateMcpcatTracking(options: CliOptions): string {
|
||||
if (!options.withMcpcat && !options.withOtel) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let trackingCode = '\n// MCPcat Product analytics and OpenTelemetry exporters\n';
|
||||
|
||||
if (options.withMcpcat && options.withOtel) {
|
||||
// Both flags enabled
|
||||
trackingCode += `mcpcat.track(server, process.env.MCPCAT_PROJECT_ID || null, {
|
||||
exporters: {
|
||||
otlp: {
|
||||
type: "otlp",
|
||||
endpoint: process.env.OTLP_ENDPOINT || "http://localhost:4318/v1/traces"
|
||||
}
|
||||
}
|
||||
});`;
|
||||
} else if (options.withMcpcat) {
|
||||
// Only MCPcat enabled
|
||||
trackingCode += `mcpcat.track(server, process.env.MCPCAT_PROJECT_ID || null);`;
|
||||
} else if (options.withOtel) {
|
||||
// Only OTEL enabled
|
||||
trackingCode += `mcpcat.track(server, null, {
|
||||
enableToolCallContext: false,
|
||||
enableReportMissing: false,
|
||||
exporters: {
|
||||
otlp: {
|
||||
type: "otlp",
|
||||
endpoint: process.env.OTLP_ENDPOINT || "http://localhost:4318/v1/traces"
|
||||
}
|
||||
}
|
||||
});`;
|
||||
}
|
||||
|
||||
return trackingCode + '\n';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the TypeScript code for the MCP server
|
||||
*
|
||||
@ -80,6 +120,10 @@ export function generateMcpServerCode(
|
||||
}`;
|
||||
break;
|
||||
}
|
||||
let mcpcatImport = '';
|
||||
if (options.withMcpcat || options.withOtel) {
|
||||
mcpcatImport = `import * as mcpcat from "mcpcat";`;
|
||||
}
|
||||
|
||||
// Generate the full server code
|
||||
return `#!/usr/bin/env node
|
||||
@ -101,6 +145,7 @@ import {
|
||||
type CallToolResult,
|
||||
type CallToolRequest
|
||||
} from "@modelcontextprotocol/sdk/types.js";${transportImport}
|
||||
${mcpcatImport}
|
||||
|
||||
import { z, ZodError } from 'zod';
|
||||
import { jsonSchemaToZod } from 'json-schema-to-zod';
|
||||
@ -156,6 +201,7 @@ ${listToolsHandlerCode}
|
||||
${callToolHandlerCode}
|
||||
${executeApiToolFunctionCode}
|
||||
|
||||
${generateMcpcatTracking(options)}
|
||||
/**
|
||||
* Main function to start the server
|
||||
*/
|
||||
|
||||
@ -34,7 +34,8 @@ import { normalizeBoolean } from './utils/helpers.js';
|
||||
import pkg from '../package.json' with { type: 'json' };
|
||||
|
||||
// Export programmatic API
|
||||
export { getToolsFromOpenApi, McpToolDefinition, GetToolsOptions } from './api.js';
|
||||
export { getToolsFromOpenApi } from './api.js';
|
||||
export type { McpToolDefinition, GetToolsOptions } from './api.js';
|
||||
|
||||
// Configure CLI
|
||||
const program = new Command();
|
||||
@ -87,6 +88,8 @@ program
|
||||
true
|
||||
)
|
||||
.option('--force', 'Overwrite existing files without prompting')
|
||||
.option('--with-mcpcat', 'Enable MCPcat MCP product analytics')
|
||||
.option('--with-otel', 'Enable OpenTelemetry (OTLP) logging')
|
||||
.version(pkg.version) // Match package.json version
|
||||
.action((options) => {
|
||||
runGenerator(options).catch((error) => {
|
||||
@ -161,7 +164,7 @@ async function runGenerator(options: CliOptions & { force?: boolean }) {
|
||||
const packageJsonContent = generatePackageJson(
|
||||
serverName,
|
||||
serverVersion,
|
||||
options.transport as TransportType
|
||||
options
|
||||
);
|
||||
|
||||
console.error('Generating tsconfig.json...');
|
||||
@ -180,7 +183,7 @@ async function runGenerator(options: CliOptions & { force?: boolean }) {
|
||||
const jestConfigContent = generateJestConfig();
|
||||
|
||||
console.error('Generating .env.example file...');
|
||||
const envExampleContent = generateEnvExample(api.components?.securitySchemes);
|
||||
const envExampleContent = generateEnvExample(api.components?.securitySchemes, options);
|
||||
|
||||
console.error('Generating OAuth2 documentation...');
|
||||
const oauth2DocsContent = generateOAuth2Docs(api.components?.securitySchemes);
|
||||
|
||||
@ -35,6 +35,10 @@ export interface CliOptions {
|
||||
* false = exclude by default unless x-mcp explicitly enables.
|
||||
*/
|
||||
defaultInclude?: boolean;
|
||||
/** Enable MCPcat analytics tracking */
|
||||
withMcpcat?: boolean;
|
||||
/** Enable OpenTelemetry (OTLP) exporters */
|
||||
withOtel?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user