Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A Model Context Protocol (MCP) server that exposes OpenAPI schema information to

## Features

- Load any OpenAPI schema file (JSON or YAML) specified via command line argument
- Load OpenAPI schema from a **local file path** or **URL** (JSON or YAML) via command line argument
- Explore API paths, operations, parameters, and schemas
- View detailed request and response schemas
- Look up component definitions and examples
Expand All @@ -15,18 +15,20 @@ A Model Context Protocol (MCP) server that exposes OpenAPI schema information to

### Command Line

Run the MCP server with a specific schema file:
Run the MCP server with a local schema file or a remote URL:

```bash
# Use the default openapi.yaml in current directory
npx -y mcp-openapi-schema

# Use a specific schema file (relative path)
# Use a local schema file (relative or absolute path)
npx -y mcp-openapi-schema ../petstore.json

# Use a specific schema file (absolute path)
npx -y mcp-openapi-schema /absolute/path/to/api-spec.yaml

# Use a remote schema URL
npx -y mcp-openapi-schema https://example.com/openapi.yaml
npx -y mcp-openapi-schema https://petstore3.swagger.io/api/v3/openapi.json

# Show help
npx -y mcp-openapi-schema --help
```
Expand All @@ -41,6 +43,10 @@ To use this MCP server with Claude Desktop, edit your `claude_desktop_config.jso
"OpenAPI Schema": {
"command": "npx",
"args": ["-y", "mcp-openapi-schema", "/ABSOLUTE/PATH/TO/openapi.yaml"]
},
"Petstore API (URL)": {
"command": "npx",
"args": ["-y", "mcp-openapi-schema", "https://petstore3.swagger.io/api/v3/openapi.json"]
}
}
}
Expand All @@ -61,8 +67,11 @@ To use this MCP server with Claude Code CLI, follow these steps:
# Basic syntax
claude mcp add openapi-schema npx -y mcp-openapi-schema

# Example with specific schema
# Example with local schema file
claude mcp add petstore-api npx -y mcp-openapi-schema ~/Projects/petstore.yaml

# Example with remote schema URL
claude mcp add petstore-remote npx -y mcp-openapi-schema https://petstore3.swagger.io/api/v3/openapi.json
```

2. **Verify the MCP server is registered**
Expand Down
7 changes: 5 additions & 2 deletions example-usage.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,15 @@ import { fileURLToPath } from "url";

const __dirname = dirname(fileURLToPath(import.meta.url));

// Set up the MCP client to communicate with our server
// Set up the MCP client to communicate with our server.
// You can pass a local path (YAML/JSON) or a URL:
// args: [resolve(__dirname, "index.mjs"), resolve(__dirname, "./sample-petstore.yaml")]
// args: [resolve(__dirname, "index.mjs"), "https://petstore3.swagger.io/api/v3/openapi.json"]
const transport = new StdioClientTransport({
command: "node",
args: [
resolve(__dirname, "index.mjs"),
resolve(__dirname, "./sample-petstore.yaml")
resolve(__dirname, "./sample-petstore.yaml"),
],
});

Expand Down
43 changes: 30 additions & 13 deletions index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,36 @@ if (args.includes("--help") || args.includes("-h")) {
OpenAPI Schema Model Context Protocol Server

Usage:
node index.mjs [path/to/openapi.yaml]
node index.mjs [path-or-url]

Arguments:
path/to/openapi.yaml Path to the OpenAPI schema file (JSON or YAML) (optional)
If not provided, defaults to openapi.yaml
path-or-url Path to a local OpenAPI file (JSON or YAML), or URL to a remote schema (optional).
If not provided, defaults to openapi.yaml

Examples:
node index.mjs # Uses default openapi.yaml
node index.mjs ../petstore.json # Uses petstore OpenAPI spec
node index.mjs
node index.mjs ../petstore.json
node index.mjs /absolute/path/to/api-schema.yaml
node index.mjs https://example.com/openapi.yaml
node index.mjs https://petstore3.swagger.io/api/v3/openapi.json
`);
process.exit(0);
}

const schemaArg = args[0];

/** Returns true if the given string looks like an HTTP(S) URL. */
const isUrl = (s) => typeof s === "string" && /^https?:\/\//i.test(s.trim());

const loadSchema = async () => {
// Default to openapi.yaml if no argument provided
const schemaPath = resolve(schemaArg ?? "openapi.yaml");
const defaultPath = "openapi.yaml";
const schemaInput = schemaArg ?? defaultPath;

try {
// Parse and validate the OpenAPI document
if (isUrl(schemaInput)) {
return await SwaggerParser.validate(schemaInput.trim(), { validate: { schema: false } });
}
const schemaPath = resolve(schemaInput);
return await SwaggerParser.validate(schemaPath, { validate: { schema: false } });
} catch (error) {
console.error(`Error loading schema: ${error.message}`);
Expand All @@ -49,14 +57,23 @@ const loadSchema = async () => {

const openApiDoc = await loadSchema();

// Extract schema name from file path or from the OpenAPI info
// Extract schema name from OpenAPI info, or from path/URL (e.g. path/to/openapi.yaml or https://host/spec.json)
const schemaName =
openApiDoc.info?.title ||
(schemaArg
? schemaArg
.split("/")
.pop()
.replace(/\.(yaml|json)$/i, "")
? (() => {
const s = schemaArg.trim();
if (isUrl(s)) {
try {
const pathname = new URL(s).pathname;
const base = pathname.split("/").filter(Boolean).pop() || "openapi";
return base.replace(/\.(yaml|yml|json)$/i, "") || "openapi";
} catch {
return "openapi";
}
}
return s.split("/").pop().replace(/\.(yaml|yml|json)$/i, "") || "openapi";
})()
: "openapi");

const server = new McpServer({
Expand Down