@ivotoby/openapi-mcp-server 1.5.1 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +192 -2
- package/bin/mcp-server.js +1 -1
- package/dist/bundle.js +81 -19
- package/dist/cli.js +24155 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -6,11 +6,186 @@ A Model Context Protocol (MCP) server that exposes OpenAPI endpoints as MCP reso
|
|
|
6
6
|
|
|
7
7
|
## Overview
|
|
8
8
|
|
|
9
|
-
This MCP server
|
|
9
|
+
This MCP server can be used in two ways:
|
|
10
|
+
|
|
11
|
+
1. **CLI Tool**: Use `npx @ivotoby/openapi-mcp-server` directly with command-line arguments for quick setup
|
|
12
|
+
2. **Library**: Import and use the `OpenAPIServer` class in your own Node.js applications for custom implementations
|
|
13
|
+
|
|
14
|
+
The server supports two transport methods:
|
|
10
15
|
|
|
11
16
|
1. **Stdio Transport** (default): For direct integration with AI systems like Claude Desktop that manage MCP connections through standard input/output.
|
|
12
17
|
2. **Streamable HTTP Transport**: For connecting to the server over HTTP, allowing web clients and other HTTP-capable systems to use the MCP protocol.
|
|
13
18
|
|
|
19
|
+
## 🚀 Using as a Library
|
|
20
|
+
|
|
21
|
+
Create dedicated MCP servers for specific APIs by importing and configuring the `OpenAPIServer` class. This approach is ideal for:
|
|
22
|
+
|
|
23
|
+
- **Custom Authentication**: Implement complex authentication patterns with the `AuthProvider` interface
|
|
24
|
+
- **API-Specific Optimizations**: Filter endpoints, customize error handling, and optimize for specific use cases
|
|
25
|
+
- **Distribution**: Package your server as a standalone npm module for easy sharing
|
|
26
|
+
- **Integration**: Embed the server in larger applications or add custom middleware
|
|
27
|
+
|
|
28
|
+
### Basic Library Usage
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { OpenAPIServer } from "@ivotoby/openapi-mcp-server"
|
|
32
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
33
|
+
|
|
34
|
+
const config = {
|
|
35
|
+
name: "my-api-server",
|
|
36
|
+
version: "1.0.0",
|
|
37
|
+
apiBaseUrl: "https://api.example.com",
|
|
38
|
+
openApiSpec: "https://api.example.com/openapi.json",
|
|
39
|
+
specInputMethod: "url" as const,
|
|
40
|
+
headers: {
|
|
41
|
+
Authorization: "Bearer your-token",
|
|
42
|
+
"X-API-Key": "your-api-key",
|
|
43
|
+
},
|
|
44
|
+
transportType: "stdio" as const,
|
|
45
|
+
toolsMode: "all" as const,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const server = new OpenAPIServer(config)
|
|
49
|
+
const transport = new StdioServerTransport()
|
|
50
|
+
await server.start(transport)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Advanced Authentication with AuthProvider
|
|
54
|
+
|
|
55
|
+
For APIs with token expiration, refresh requirements, or complex authentication:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { OpenAPIServer, AuthProvider } from "@ivotoby/openapi-mcp-server"
|
|
59
|
+
import { AxiosError } from "axios"
|
|
60
|
+
|
|
61
|
+
class MyAuthProvider implements AuthProvider {
|
|
62
|
+
async getAuthHeaders(): Promise<Record<string, string>> {
|
|
63
|
+
// Called before each request - return fresh headers
|
|
64
|
+
if (this.isTokenExpired()) {
|
|
65
|
+
await this.refreshToken()
|
|
66
|
+
}
|
|
67
|
+
return { Authorization: `Bearer ${this.token}` }
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async handleAuthError(error: AxiosError): Promise<boolean> {
|
|
71
|
+
// Called on 401/403 errors - return true to retry
|
|
72
|
+
if (error.response?.status === 401) {
|
|
73
|
+
await this.refreshToken()
|
|
74
|
+
return true // Retry the request
|
|
75
|
+
}
|
|
76
|
+
return false
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const authProvider = new MyAuthProvider()
|
|
81
|
+
const config = {
|
|
82
|
+
// ... other config
|
|
83
|
+
authProvider: authProvider, // Use AuthProvider instead of static headers
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**📁 See the [examples/](./examples/) directory for complete, runnable examples including:**
|
|
88
|
+
|
|
89
|
+
- Basic library usage with static authentication
|
|
90
|
+
- AuthProvider implementations for different scenarios
|
|
91
|
+
- Real-world Beatport API integration
|
|
92
|
+
- Production-ready packaging patterns
|
|
93
|
+
|
|
94
|
+
## 🔐 Dynamic Authentication with AuthProvider
|
|
95
|
+
|
|
96
|
+
The `AuthProvider` interface enables sophisticated authentication scenarios that static headers cannot handle:
|
|
97
|
+
|
|
98
|
+
### Key Features
|
|
99
|
+
|
|
100
|
+
- **Dynamic Headers**: Fresh authentication headers for each request
|
|
101
|
+
- **Token Expiration Handling**: Automatic detection and handling of expired tokens
|
|
102
|
+
- **Authentication Error Recovery**: Retry logic for recoverable authentication failures
|
|
103
|
+
- **Custom Error Messages**: Provide clear, actionable guidance to users
|
|
104
|
+
|
|
105
|
+
### AuthProvider Interface
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
interface AuthProvider {
|
|
109
|
+
/**
|
|
110
|
+
* Get authentication headers for the current request
|
|
111
|
+
* Called before each API request to get fresh headers
|
|
112
|
+
*/
|
|
113
|
+
getAuthHeaders(): Promise<Record<string, string>>
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Handle authentication errors from API responses
|
|
117
|
+
* Called when the API returns 401 or 403 errors
|
|
118
|
+
* Return true to retry the request, false otherwise
|
|
119
|
+
*/
|
|
120
|
+
handleAuthError(error: AxiosError): Promise<boolean>
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Common Patterns
|
|
125
|
+
|
|
126
|
+
#### Automatic Token Refresh
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
class RefreshableAuthProvider implements AuthProvider {
|
|
130
|
+
async getAuthHeaders(): Promise<Record<string, string>> {
|
|
131
|
+
if (this.isTokenExpired()) {
|
|
132
|
+
await this.refreshToken()
|
|
133
|
+
}
|
|
134
|
+
return { Authorization: `Bearer ${this.accessToken}` }
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async handleAuthError(error: AxiosError): Promise<boolean> {
|
|
138
|
+
if (error.response?.status === 401) {
|
|
139
|
+
await this.refreshToken()
|
|
140
|
+
return true // Retry with fresh token
|
|
141
|
+
}
|
|
142
|
+
return false
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
#### Manual Token Management (e.g., Beatport)
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
class ManualTokenAuthProvider implements AuthProvider {
|
|
151
|
+
async getAuthHeaders(): Promise<Record<string, string>> {
|
|
152
|
+
if (!this.token || this.isTokenExpired()) {
|
|
153
|
+
throw new Error(
|
|
154
|
+
"Token expired. Please get a new token from your browser:\n" +
|
|
155
|
+
"1. Go to the API website and log in\n" +
|
|
156
|
+
"2. Open browser dev tools (F12)\n" +
|
|
157
|
+
"3. Copy the Authorization header from any API request\n" +
|
|
158
|
+
"4. Update your token using updateToken()",
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
return { Authorization: `Bearer ${this.token}` }
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
updateToken(token: string): void {
|
|
165
|
+
this.token = token
|
|
166
|
+
this.tokenExpiry = new Date(Date.now() + 3600000) // 1 hour
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### API Key Authentication
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
class ApiKeyAuthProvider implements AuthProvider {
|
|
175
|
+
constructor(private apiKey: string) {}
|
|
176
|
+
|
|
177
|
+
async getAuthHeaders(): Promise<Record<string, string>> {
|
|
178
|
+
return { "X-API-Key": this.apiKey }
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async handleAuthError(error: AxiosError): Promise<boolean> {
|
|
182
|
+
throw new Error("API key authentication failed. Please check your key.")
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**📖 For detailed AuthProvider documentation and examples, see [docs/auth-provider-guide.md](./docs/auth-provider-guide.md)**
|
|
188
|
+
|
|
14
189
|
## Quick Start for Users
|
|
15
190
|
|
|
16
191
|
### Option 1: Using with Claude Desktop (Stdio Transport)
|
|
@@ -353,6 +528,18 @@ To see debug logs:
|
|
|
353
528
|
**Q: What is a "tool"?**
|
|
354
529
|
A: A tool corresponds to a single API endpoint derived from your OpenAPI specification, exposed as an MCP resource.
|
|
355
530
|
|
|
531
|
+
**Q: How can I use this package in my own project?**
|
|
532
|
+
A: You can import the `OpenAPIServer` class and use it as a library in your Node.js application. This allows you to create dedicated MCP servers for specific APIs with custom authentication, filtering, and error handling. See the [examples/](./examples/) directory for complete implementations.
|
|
533
|
+
|
|
534
|
+
**Q: What's the difference between using the CLI and using it as a library?**
|
|
535
|
+
A: The CLI is great for quick setup and testing, while the library approach allows you to create dedicated packages for specific APIs, implement custom authentication with `AuthProvider`, add custom logic, and distribute your server as a standalone npm module.
|
|
536
|
+
|
|
537
|
+
**Q: How do I handle APIs with expiring tokens?**
|
|
538
|
+
A: Use the `AuthProvider` interface instead of static headers. AuthProvider allows you to implement dynamic authentication with token refresh, expiration handling, and custom error recovery. See the AuthProvider examples for different patterns.
|
|
539
|
+
|
|
540
|
+
**Q: What is AuthProvider and when should I use it?**
|
|
541
|
+
A: `AuthProvider` is an interface for dynamic authentication that gets fresh headers before each request and handles authentication errors. Use it when your API has expiring tokens, requires token refresh, or needs complex authentication logic that static headers can't handle.
|
|
542
|
+
|
|
356
543
|
**Q: How do I filter which tools are loaded?**
|
|
357
544
|
A: Use the `--tool`, `--tag`, `--resource`, and `--operation` flags, or set `TOOLS_MODE=dynamic` for meta-tools only.
|
|
358
545
|
|
|
@@ -360,7 +547,7 @@ A: Use the `--tool`, `--tag`, `--resource`, and `--operation` flags, or set `TOO
|
|
|
360
547
|
A: Dynamic mode provides meta-tools (`list-api-endpoints`, `get-api-endpoint-schema`, `invoke-api-endpoint`) to inspect and interact with endpoints without preloading all operations, which is useful for large or changing APIs.
|
|
361
548
|
|
|
362
549
|
**Q: How do I specify custom headers for API requests?**
|
|
363
|
-
A: Use the `--headers` flag or `API_HEADERS` environment variable with `key:value` pairs separated by commas.
|
|
550
|
+
A: Use the `--headers` flag or `API_HEADERS` environment variable with `key:value` pairs separated by commas for CLI usage. For library usage, use the `headers` config option or implement an `AuthProvider` for dynamic headers.
|
|
364
551
|
|
|
365
552
|
**Q: Which transport methods are supported?**
|
|
366
553
|
A: The server supports stdio transport (default) for integration with AI systems and HTTP transport (with streaming via SSE) for web clients.
|
|
@@ -371,6 +558,9 @@ A: The server fully resolves `$ref` references in parameters and schemas, preser
|
|
|
371
558
|
**Q: What happens when parameter names conflict with request body properties?**
|
|
372
559
|
A: The server detects naming conflicts and automatically prefixes body property names with `body_` to avoid collisions, ensuring all properties are accessible.
|
|
373
560
|
|
|
561
|
+
**Q: Can I package my MCP server for distribution?**
|
|
562
|
+
A: Yes! When using the library approach, you can create a dedicated npm package for your API. See the Beatport example for a complete implementation that can be packaged and distributed as `npx your-api-mcp-server`.
|
|
563
|
+
|
|
374
564
|
**Q: Where can I find development and contribution guidelines?**
|
|
375
565
|
A: See the "For Developers" section above for commands (`npm run build`, `npm run dev`, etc) and pull request workflow.
|
|
376
566
|
|
package/bin/mcp-server.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "../dist/
|
|
2
|
+
import "../dist/cli.js"
|
package/dist/bundle.js
CHANGED
|
@@ -14286,7 +14286,7 @@ var js_yaml_default = jsYaml;
|
|
|
14286
14286
|
// src/openapi-loader.ts
|
|
14287
14287
|
import crypto from "crypto";
|
|
14288
14288
|
|
|
14289
|
-
// src/abbreviations.ts
|
|
14289
|
+
// src/utils/abbreviations.ts
|
|
14290
14290
|
var REVISED_COMMON_WORDS_TO_REMOVE = [
|
|
14291
14291
|
"controller",
|
|
14292
14292
|
"api",
|
|
@@ -14371,6 +14371,21 @@ var WORD_ABBREVIATIONS = {
|
|
|
14371
14371
|
query: "Qry"
|
|
14372
14372
|
};
|
|
14373
14373
|
|
|
14374
|
+
// src/utils/tool-id.ts
|
|
14375
|
+
function parseToolId(toolId) {
|
|
14376
|
+
const [method, pathPart] = toolId.split("::", 2);
|
|
14377
|
+
const path = pathPart ? "/" + pathPart.replace(/-/g, "/") : "";
|
|
14378
|
+
return { method, path };
|
|
14379
|
+
}
|
|
14380
|
+
function sanitizeForToolId(input) {
|
|
14381
|
+
return input.replace(/[^A-Za-z0-9_-]/g, "").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-");
|
|
14382
|
+
}
|
|
14383
|
+
function generateToolId(method, path) {
|
|
14384
|
+
const cleanPath = path.replace(/^\//, "").replace(/\{([^}]+)\}/g, "$1").replace(/\//g, "-");
|
|
14385
|
+
const sanitizedPath = sanitizeForToolId(cleanPath);
|
|
14386
|
+
return `${method.toUpperCase()}::${sanitizedPath}`;
|
|
14387
|
+
}
|
|
14388
|
+
|
|
14374
14389
|
// src/openapi-loader.ts
|
|
14375
14390
|
var OpenAPISpecLoader = class {
|
|
14376
14391
|
/**
|
|
@@ -14562,9 +14577,8 @@ var OpenAPISpecLoader = class {
|
|
|
14562
14577
|
continue;
|
|
14563
14578
|
}
|
|
14564
14579
|
const op = operation;
|
|
14565
|
-
const
|
|
14566
|
-
const
|
|
14567
|
-
let nameSource = op.operationId || op.summary || `${method.toUpperCase()} ${path}`;
|
|
14580
|
+
const toolId = generateToolId(method, path);
|
|
14581
|
+
const nameSource = op.operationId || op.summary || `${method.toUpperCase()} ${path}`;
|
|
14568
14582
|
const name = this.abbreviateOperationId(nameSource);
|
|
14569
14583
|
const tool = {
|
|
14570
14584
|
name,
|
|
@@ -14574,6 +14588,7 @@ var OpenAPISpecLoader = class {
|
|
|
14574
14588
|
properties: {}
|
|
14575
14589
|
}
|
|
14576
14590
|
};
|
|
14591
|
+
tool["x-original-path"] = path;
|
|
14577
14592
|
const requiredParams = [];
|
|
14578
14593
|
if (op.parameters) {
|
|
14579
14594
|
for (const param of op.parameters) {
|
|
@@ -14940,11 +14955,12 @@ var ToolsManager = class {
|
|
|
14940
14955
|
}
|
|
14941
14956
|
/**
|
|
14942
14957
|
* Get the path and method from a tool ID
|
|
14958
|
+
*
|
|
14959
|
+
* Note: This converts hyphens back to slashes to reconstruct the original API path.
|
|
14960
|
+
* This is consistent with ApiClient.parseToolId() which needs the actual path for HTTP requests.
|
|
14943
14961
|
*/
|
|
14944
14962
|
parseToolId(toolId) {
|
|
14945
|
-
|
|
14946
|
-
const path = "/" + pathParts.join("/").replace(/-/g, "/");
|
|
14947
|
-
return { method, path };
|
|
14963
|
+
return parseToolId(toolId);
|
|
14948
14964
|
}
|
|
14949
14965
|
};
|
|
14950
14966
|
|
|
@@ -18257,22 +18273,46 @@ var {
|
|
|
18257
18273
|
mergeConfig: mergeConfig2
|
|
18258
18274
|
} = axios_default;
|
|
18259
18275
|
|
|
18276
|
+
// src/auth-provider.ts
|
|
18277
|
+
function isAuthError(error) {
|
|
18278
|
+
return error.response?.status === 401 || error.response?.status === 403;
|
|
18279
|
+
}
|
|
18280
|
+
var StaticAuthProvider = class {
|
|
18281
|
+
constructor(headers = {}) {
|
|
18282
|
+
this.headers = headers;
|
|
18283
|
+
}
|
|
18284
|
+
async getAuthHeaders() {
|
|
18285
|
+
return { ...this.headers };
|
|
18286
|
+
}
|
|
18287
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
18288
|
+
async handleAuthError(_error) {
|
|
18289
|
+
return false;
|
|
18290
|
+
}
|
|
18291
|
+
};
|
|
18292
|
+
|
|
18260
18293
|
// src/api-client.ts
|
|
18261
18294
|
var ApiClient = class {
|
|
18295
|
+
axiosInstance;
|
|
18296
|
+
toolsMap = /* @__PURE__ */ new Map();
|
|
18297
|
+
authProvider;
|
|
18262
18298
|
/**
|
|
18263
18299
|
* Create a new API client
|
|
18264
18300
|
*
|
|
18265
18301
|
* @param baseUrl - Base URL for the API
|
|
18266
|
-
* @param
|
|
18302
|
+
* @param authProviderOrHeaders - AuthProvider instance or static headers for backward compatibility
|
|
18267
18303
|
*/
|
|
18268
|
-
constructor(baseUrl,
|
|
18269
|
-
this.headers = headers;
|
|
18304
|
+
constructor(baseUrl, authProviderOrHeaders) {
|
|
18270
18305
|
this.axiosInstance = axios_default.create({
|
|
18271
18306
|
baseURL: baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`
|
|
18272
18307
|
});
|
|
18308
|
+
if (!authProviderOrHeaders) {
|
|
18309
|
+
this.authProvider = new StaticAuthProvider();
|
|
18310
|
+
} else if (typeof authProviderOrHeaders === "object" && !("getAuthHeaders" in authProviderOrHeaders)) {
|
|
18311
|
+
this.authProvider = new StaticAuthProvider(authProviderOrHeaders);
|
|
18312
|
+
} else {
|
|
18313
|
+
this.authProvider = authProviderOrHeaders;
|
|
18314
|
+
}
|
|
18273
18315
|
}
|
|
18274
|
-
axiosInstance;
|
|
18275
|
-
toolsMap = /* @__PURE__ */ new Map();
|
|
18276
18316
|
/**
|
|
18277
18317
|
* Set the available tools for the client
|
|
18278
18318
|
*
|
|
@@ -18298,6 +18338,17 @@ var ApiClient = class {
|
|
|
18298
18338
|
* @returns The API response data
|
|
18299
18339
|
*/
|
|
18300
18340
|
async executeApiCall(toolId, params) {
|
|
18341
|
+
return this.executeApiCallWithRetry(toolId, params, false);
|
|
18342
|
+
}
|
|
18343
|
+
/**
|
|
18344
|
+
* Execute an API call with optional retry on auth error
|
|
18345
|
+
*
|
|
18346
|
+
* @param toolId - The tool ID in format METHOD-path-parts
|
|
18347
|
+
* @param params - Parameters for the API call
|
|
18348
|
+
* @param isRetry - Whether this is a retry attempt
|
|
18349
|
+
* @returns The API response data
|
|
18350
|
+
*/
|
|
18351
|
+
async executeApiCallWithRetry(toolId, params, isRetry) {
|
|
18301
18352
|
try {
|
|
18302
18353
|
const { method, path } = this.parseToolId(toolId);
|
|
18303
18354
|
const toolDef = this.getToolDefinition(toolId);
|
|
@@ -18342,10 +18393,11 @@ var ApiClient = class {
|
|
|
18342
18393
|
}
|
|
18343
18394
|
}
|
|
18344
18395
|
}
|
|
18396
|
+
const authHeaders = await this.authProvider.getAuthHeaders();
|
|
18345
18397
|
const config = {
|
|
18346
18398
|
method: method.toLowerCase(),
|
|
18347
18399
|
url: resolvedPath,
|
|
18348
|
-
headers:
|
|
18400
|
+
headers: authHeaders
|
|
18349
18401
|
};
|
|
18350
18402
|
if (["get", "delete", "head", "options"].includes(method.toLowerCase())) {
|
|
18351
18403
|
config.params = this.processQueryParams(paramsCopy);
|
|
@@ -18357,6 +18409,12 @@ var ApiClient = class {
|
|
|
18357
18409
|
} catch (error) {
|
|
18358
18410
|
if (axios_default.isAxiosError(error)) {
|
|
18359
18411
|
const axiosError = error;
|
|
18412
|
+
if (!isRetry && isAuthError(axiosError)) {
|
|
18413
|
+
const shouldRetry = await this.authProvider.handleAuthError(axiosError);
|
|
18414
|
+
if (shouldRetry) {
|
|
18415
|
+
return this.executeApiCallWithRetry(toolId, params, true);
|
|
18416
|
+
}
|
|
18417
|
+
}
|
|
18360
18418
|
throw new Error(
|
|
18361
18419
|
`API request failed: ${axiosError.message}${axiosError.response ? ` (${axiosError.response.status}: ${typeof axiosError.response.data === "object" ? JSON.stringify(axiosError.response.data) : axiosError.response.data})` : ""}`
|
|
18362
18420
|
);
|
|
@@ -18367,13 +18425,11 @@ var ApiClient = class {
|
|
|
18367
18425
|
/**
|
|
18368
18426
|
* Parse a tool ID into HTTP method and path
|
|
18369
18427
|
*
|
|
18370
|
-
* @param toolId - Tool ID in format METHOD
|
|
18428
|
+
* @param toolId - Tool ID in format METHOD::pathPart
|
|
18371
18429
|
* @returns Object containing method and path
|
|
18372
18430
|
*/
|
|
18373
18431
|
parseToolId(toolId) {
|
|
18374
|
-
|
|
18375
|
-
const path = "/" + pathParts.join("/").replace(/-/g, "/");
|
|
18376
|
-
return { method, path };
|
|
18432
|
+
return parseToolId(toolId);
|
|
18377
18433
|
}
|
|
18378
18434
|
/**
|
|
18379
18435
|
* Process query parameters for GET requests
|
|
@@ -18413,7 +18469,8 @@ var OpenAPIServer = class {
|
|
|
18413
18469
|
}
|
|
18414
18470
|
);
|
|
18415
18471
|
this.toolsManager = new ToolsManager(config);
|
|
18416
|
-
|
|
18472
|
+
const authProviderOrHeaders = config.authProvider || new StaticAuthProvider(config.headers);
|
|
18473
|
+
this.apiClient = new ApiClient(config.apiBaseUrl, authProviderOrHeaders);
|
|
18417
18474
|
this.initializeHandlers();
|
|
18418
18475
|
}
|
|
18419
18476
|
/**
|
|
@@ -24049,14 +24106,19 @@ async function main() {
|
|
|
24049
24106
|
process.exit(1);
|
|
24050
24107
|
}
|
|
24051
24108
|
}
|
|
24052
|
-
|
|
24109
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
24110
|
+
main();
|
|
24111
|
+
}
|
|
24053
24112
|
export {
|
|
24054
24113
|
ApiClient,
|
|
24055
24114
|
OpenAPIServer,
|
|
24056
24115
|
OpenAPISpecLoader,
|
|
24116
|
+
StaticAuthProvider,
|
|
24057
24117
|
StreamableHttpServerTransport,
|
|
24058
24118
|
ToolsManager,
|
|
24119
|
+
isAuthError,
|
|
24059
24120
|
loadConfig,
|
|
24121
|
+
main,
|
|
24060
24122
|
parseHeaders
|
|
24061
24123
|
};
|
|
24062
24124
|
/*! Bundled license information:
|