@mcp-consultant-tools/rest-api 22.0.0-beta.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 +128 -0
- package/build/RestApiService.d.ts +125 -0
- package/build/RestApiService.d.ts.map +1 -0
- package/build/RestApiService.js +300 -0
- package/build/RestApiService.js.map +1 -0
- package/build/index.d.ts +27 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +462 -0
- package/build/index.js.map +1 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# @mcp-consultant-tools/rest-api
|
|
2
|
+
|
|
3
|
+
MCP server for REST API testing with OAuth2 client credentials support. Enables AI assistants to test HTTP endpoints with automatic JWT token generation.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **HTTP Methods**: GET, POST, PUT, DELETE, PATCH
|
|
8
|
+
- **OAuth2 Client Credentials**: Automatic JWT token acquisition and caching
|
|
9
|
+
- **Multiple Auth Methods**: Bearer token, Basic auth, API key
|
|
10
|
+
- **Response Management**: Size limiting, truncation, timing
|
|
11
|
+
- **SSL Control**: Enable/disable certificate verification
|
|
12
|
+
- **Custom Headers**: Configure via environment variables
|
|
13
|
+
- **Batch Requests**: Execute multiple requests sequentially
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
### Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# As standalone
|
|
21
|
+
npx @mcp-consultant-tools/rest-api
|
|
22
|
+
|
|
23
|
+
# Or install globally
|
|
24
|
+
npm install -g @mcp-consultant-tools/rest-api
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### MCP Client Configuration
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"mcpServers": {
|
|
32
|
+
"rest-api": {
|
|
33
|
+
"command": "npx",
|
|
34
|
+
"args": ["@mcp-consultant-tools/rest-api"],
|
|
35
|
+
"env": {
|
|
36
|
+
"REST_BASE_URL": "https://your-api.azurewebsites.net/api",
|
|
37
|
+
"OAUTH2_TOKEN_URL": "https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token",
|
|
38
|
+
"OAUTH2_CLIENT_ID": "your-client-id",
|
|
39
|
+
"OAUTH2_CLIENT_SECRET": "your-client-secret",
|
|
40
|
+
"OAUTH2_SCOPE": "api://your-app-id/.default"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Tools (4)
|
|
48
|
+
|
|
49
|
+
| Tool | Description |
|
|
50
|
+
|------|-------------|
|
|
51
|
+
| `rest-request` | Execute HTTP requests with automatic authentication |
|
|
52
|
+
| `rest-config` | Get current service configuration summary |
|
|
53
|
+
| `rest-refresh-token` | Force refresh OAuth2 token cache |
|
|
54
|
+
| `rest-batch-request` | Execute multiple requests sequentially |
|
|
55
|
+
|
|
56
|
+
## Prompts (2)
|
|
57
|
+
|
|
58
|
+
| Prompt | Description |
|
|
59
|
+
|--------|-------------|
|
|
60
|
+
| `rest-api-guide` | Comprehensive usage guide |
|
|
61
|
+
| `rest-api-troubleshoot` | Troubleshooting common issues |
|
|
62
|
+
|
|
63
|
+
## Authentication Methods
|
|
64
|
+
|
|
65
|
+
### OAuth2 Client Credentials (Recommended)
|
|
66
|
+
|
|
67
|
+
Best for Azure/Entra ID protected APIs like Data API Builder (DAB):
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
OAUTH2_TOKEN_URL=https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
|
|
71
|
+
OAUTH2_CLIENT_ID=your-client-id
|
|
72
|
+
OAUTH2_CLIENT_SECRET=your-secret
|
|
73
|
+
OAUTH2_SCOPE=api://your-api/.default
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Static Bearer Token
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
AUTH_BEARER=your-pre-acquired-token
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Basic Authentication
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
AUTH_BASIC_USERNAME=user
|
|
86
|
+
AUTH_BASIC_PASSWORD=pass
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### API Key
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
AUTH_APIKEY_HEADER_NAME=X-Api-Key
|
|
93
|
+
AUTH_APIKEY_VALUE=your-key
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Configuration Reference
|
|
97
|
+
|
|
98
|
+
| Variable | Required | Default | Description |
|
|
99
|
+
|----------|----------|---------|-------------|
|
|
100
|
+
| `REST_BASE_URL` | Yes | - | Base URL for API requests |
|
|
101
|
+
| `REST_RESPONSE_SIZE_LIMIT` | No | 10000 | Max response size in bytes |
|
|
102
|
+
| `REST_ENABLE_SSL_VERIFY` | No | true | SSL certificate verification |
|
|
103
|
+
| `REST_TIMEOUT` | No | 30000 | Request timeout in ms |
|
|
104
|
+
| `HEADER_*` | No | - | Custom headers (e.g., `HEADER_Accept`) |
|
|
105
|
+
|
|
106
|
+
## Example Usage
|
|
107
|
+
|
|
108
|
+
### Simple GET Request
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
Use rest-request with method GET and endpoint /users
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### POST with Body
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
Use rest-request with method POST, endpoint /orders, and body {"item": "widget", "qty": 5}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Batch Operations
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
Use rest-batch-request with an array of requests to test a complete workflow
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## License
|
|
127
|
+
|
|
128
|
+
MIT
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REST API Service
|
|
3
|
+
*
|
|
4
|
+
* Provides HTTP request functionality with multiple authentication methods:
|
|
5
|
+
* - Static Bearer Token
|
|
6
|
+
* - Basic Authentication
|
|
7
|
+
* - API Key (custom header)
|
|
8
|
+
* - OAuth2 Client Credentials Flow (JWT generation)
|
|
9
|
+
*/
|
|
10
|
+
export interface RestApiConfig {
|
|
11
|
+
/** Base URL for all requests (e.g., "https://api.example.com/v1") */
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
/** Response size limit in bytes (default: 10000) */
|
|
14
|
+
responseSizeLimit?: number;
|
|
15
|
+
/** Enable SSL certificate verification (default: true) */
|
|
16
|
+
enableSslVerify?: boolean;
|
|
17
|
+
/** Static bearer token (mutually exclusive with oauth2) */
|
|
18
|
+
bearerToken?: string;
|
|
19
|
+
/** Basic auth credentials */
|
|
20
|
+
basicAuth?: {
|
|
21
|
+
username: string;
|
|
22
|
+
password: string;
|
|
23
|
+
};
|
|
24
|
+
/** API key authentication */
|
|
25
|
+
apiKey?: {
|
|
26
|
+
headerName: string;
|
|
27
|
+
value: string;
|
|
28
|
+
};
|
|
29
|
+
/** OAuth2 client credentials configuration */
|
|
30
|
+
oauth2?: {
|
|
31
|
+
/** Token endpoint URL (e.g., "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token") */
|
|
32
|
+
tokenUrl: string;
|
|
33
|
+
/** OAuth2 Client ID */
|
|
34
|
+
clientId: string;
|
|
35
|
+
/** OAuth2 Client Secret */
|
|
36
|
+
clientSecret: string;
|
|
37
|
+
/** OAuth2 Scope (e.g., "https://api.example.com/.default") */
|
|
38
|
+
scope: string;
|
|
39
|
+
/** Optional grant type (defaults to "client_credentials") */
|
|
40
|
+
grantType?: string;
|
|
41
|
+
/** Optional additional token request parameters */
|
|
42
|
+
additionalParams?: Record<string, string>;
|
|
43
|
+
};
|
|
44
|
+
/** Custom headers to include in all requests */
|
|
45
|
+
customHeaders?: Record<string, string>;
|
|
46
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
47
|
+
timeout?: number;
|
|
48
|
+
}
|
|
49
|
+
export interface RequestOptions {
|
|
50
|
+
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
51
|
+
endpoint: string;
|
|
52
|
+
body?: any;
|
|
53
|
+
headers?: Record<string, string>;
|
|
54
|
+
/** Override base URL for this request only */
|
|
55
|
+
host?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface RequestResult {
|
|
58
|
+
request: {
|
|
59
|
+
url: string;
|
|
60
|
+
method: string;
|
|
61
|
+
headers: Record<string, string>;
|
|
62
|
+
body?: any;
|
|
63
|
+
authMethod: string;
|
|
64
|
+
};
|
|
65
|
+
response: {
|
|
66
|
+
statusCode: number;
|
|
67
|
+
statusText: string;
|
|
68
|
+
timing: string;
|
|
69
|
+
headers: Record<string, any>;
|
|
70
|
+
body: any;
|
|
71
|
+
};
|
|
72
|
+
validation: {
|
|
73
|
+
isError: boolean;
|
|
74
|
+
messages: string[];
|
|
75
|
+
truncated?: {
|
|
76
|
+
originalSize: number;
|
|
77
|
+
returnedSize: number;
|
|
78
|
+
truncationPoint: number;
|
|
79
|
+
sizeLimit: number;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
export declare class RestApiService {
|
|
84
|
+
private config;
|
|
85
|
+
private cachedToken;
|
|
86
|
+
private httpsAgent;
|
|
87
|
+
constructor(config: RestApiConfig);
|
|
88
|
+
/**
|
|
89
|
+
* Get the current authentication method name
|
|
90
|
+
*/
|
|
91
|
+
getAuthMethod(): string;
|
|
92
|
+
/**
|
|
93
|
+
* Get OAuth2 access token using client credentials flow
|
|
94
|
+
* Caches token and refreshes when expired
|
|
95
|
+
*/
|
|
96
|
+
private getOAuth2Token;
|
|
97
|
+
/**
|
|
98
|
+
* Get the Authorization header value based on configured auth method
|
|
99
|
+
*/
|
|
100
|
+
private getAuthHeader;
|
|
101
|
+
/**
|
|
102
|
+
* Sanitize headers for display (redact sensitive values)
|
|
103
|
+
*/
|
|
104
|
+
private sanitizeHeaders;
|
|
105
|
+
/**
|
|
106
|
+
* Execute an HTTP request
|
|
107
|
+
*/
|
|
108
|
+
request(options: RequestOptions): Promise<RequestResult>;
|
|
109
|
+
/**
|
|
110
|
+
* Force refresh the OAuth2 token (clears cache)
|
|
111
|
+
*/
|
|
112
|
+
clearTokenCache(): void;
|
|
113
|
+
/**
|
|
114
|
+
* Get configuration summary (safe to display)
|
|
115
|
+
*/
|
|
116
|
+
getConfigSummary(): {
|
|
117
|
+
baseUrl: string;
|
|
118
|
+
authMethod: string;
|
|
119
|
+
sslVerification: boolean;
|
|
120
|
+
responseSizeLimit: number;
|
|
121
|
+
customHeaderCount: number;
|
|
122
|
+
oauth2TokenUrl?: string;
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=RestApiService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RestApiService.d.ts","sourceRoot":"","sources":["../src/RestApiService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REST API Service
|
|
3
|
+
*
|
|
4
|
+
* Provides HTTP request functionality with multiple authentication methods:
|
|
5
|
+
* - Static Bearer Token
|
|
6
|
+
* - Basic Authentication
|
|
7
|
+
* - API Key (custom header)
|
|
8
|
+
* - OAuth2 Client Credentials Flow (JWT generation)
|
|
9
|
+
*/
|
|
10
|
+
import https from "https";
|
|
11
|
+
export class RestApiService {
|
|
12
|
+
config;
|
|
13
|
+
cachedToken = null;
|
|
14
|
+
httpsAgent;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.config = {
|
|
17
|
+
responseSizeLimit: 10000,
|
|
18
|
+
enableSslVerify: true,
|
|
19
|
+
timeout: 30000,
|
|
20
|
+
...config,
|
|
21
|
+
};
|
|
22
|
+
// Normalize base URL (remove trailing slashes)
|
|
23
|
+
this.config.baseUrl = this.config.baseUrl.replace(/\/+$/, "");
|
|
24
|
+
// Create HTTPS agent if SSL verification is disabled
|
|
25
|
+
if (!this.config.enableSslVerify) {
|
|
26
|
+
this.httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
|
27
|
+
}
|
|
28
|
+
// Validate mutually exclusive auth methods
|
|
29
|
+
const authMethods = [
|
|
30
|
+
this.config.bearerToken ? "bearer" : null,
|
|
31
|
+
this.config.basicAuth ? "basic" : null,
|
|
32
|
+
this.config.oauth2 ? "oauth2" : null,
|
|
33
|
+
this.config.apiKey ? "apikey" : null,
|
|
34
|
+
].filter(Boolean);
|
|
35
|
+
if (authMethods.length > 1) {
|
|
36
|
+
console.error(`Warning: Multiple auth methods configured (${authMethods.join(", ")}). Only one should be used.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get the current authentication method name
|
|
41
|
+
*/
|
|
42
|
+
getAuthMethod() {
|
|
43
|
+
if (this.config.oauth2)
|
|
44
|
+
return "oauth2";
|
|
45
|
+
if (this.config.bearerToken)
|
|
46
|
+
return "bearer";
|
|
47
|
+
if (this.config.basicAuth)
|
|
48
|
+
return "basic";
|
|
49
|
+
if (this.config.apiKey)
|
|
50
|
+
return "apikey";
|
|
51
|
+
return "none";
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get OAuth2 access token using client credentials flow
|
|
55
|
+
* Caches token and refreshes when expired
|
|
56
|
+
*/
|
|
57
|
+
async getOAuth2Token() {
|
|
58
|
+
const oauth2 = this.config.oauth2;
|
|
59
|
+
if (!oauth2) {
|
|
60
|
+
throw new Error("OAuth2 configuration not provided");
|
|
61
|
+
}
|
|
62
|
+
// Check if we have a valid cached token (with 5 minute buffer)
|
|
63
|
+
const now = Date.now();
|
|
64
|
+
if (this.cachedToken && this.cachedToken.expiresAt > now + 5 * 60 * 1000) {
|
|
65
|
+
return this.cachedToken.accessToken;
|
|
66
|
+
}
|
|
67
|
+
console.error("Acquiring new OAuth2 token...");
|
|
68
|
+
// Build token request body
|
|
69
|
+
const params = new URLSearchParams();
|
|
70
|
+
params.append("grant_type", oauth2.grantType || "client_credentials");
|
|
71
|
+
params.append("client_id", oauth2.clientId);
|
|
72
|
+
params.append("client_secret", oauth2.clientSecret);
|
|
73
|
+
params.append("scope", oauth2.scope);
|
|
74
|
+
// Add any additional parameters
|
|
75
|
+
if (oauth2.additionalParams) {
|
|
76
|
+
for (const [key, value] of Object.entries(oauth2.additionalParams)) {
|
|
77
|
+
params.append(key, value);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const response = await fetch(oauth2.tokenUrl, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers: {
|
|
83
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
84
|
+
},
|
|
85
|
+
body: params.toString(),
|
|
86
|
+
});
|
|
87
|
+
if (!response.ok) {
|
|
88
|
+
const errorText = await response.text();
|
|
89
|
+
throw new Error(`OAuth2 token request failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
90
|
+
}
|
|
91
|
+
const tokenResponse = await response.json();
|
|
92
|
+
if (!tokenResponse.access_token) {
|
|
93
|
+
throw new Error("OAuth2 response missing access_token");
|
|
94
|
+
}
|
|
95
|
+
// Cache the token
|
|
96
|
+
// Default to 1 hour expiry if not provided
|
|
97
|
+
const expiresIn = tokenResponse.expires_in || 3600;
|
|
98
|
+
this.cachedToken = {
|
|
99
|
+
accessToken: tokenResponse.access_token,
|
|
100
|
+
expiresAt: now + expiresIn * 1000,
|
|
101
|
+
};
|
|
102
|
+
console.error(`OAuth2 token acquired, expires in ${Math.round(expiresIn / 60)} minutes`);
|
|
103
|
+
return this.cachedToken.accessToken;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get the Authorization header value based on configured auth method
|
|
107
|
+
*/
|
|
108
|
+
async getAuthHeader() {
|
|
109
|
+
if (this.config.oauth2) {
|
|
110
|
+
const token = await this.getOAuth2Token();
|
|
111
|
+
return { name: "Authorization", value: `Bearer ${token}` };
|
|
112
|
+
}
|
|
113
|
+
if (this.config.bearerToken) {
|
|
114
|
+
return { name: "Authorization", value: `Bearer ${this.config.bearerToken}` };
|
|
115
|
+
}
|
|
116
|
+
if (this.config.basicAuth) {
|
|
117
|
+
const { username, password } = this.config.basicAuth;
|
|
118
|
+
const base64Credentials = Buffer.from(`${username}:${password}`).toString("base64");
|
|
119
|
+
return { name: "Authorization", value: `Basic ${base64Credentials}` };
|
|
120
|
+
}
|
|
121
|
+
if (this.config.apiKey) {
|
|
122
|
+
return { name: this.config.apiKey.headerName, value: this.config.apiKey.value };
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Sanitize headers for display (redact sensitive values)
|
|
128
|
+
*/
|
|
129
|
+
sanitizeHeaders(headers, isFromRequest = false) {
|
|
130
|
+
const sanitized = {};
|
|
131
|
+
const safeHeaders = new Set([
|
|
132
|
+
"accept",
|
|
133
|
+
"accept-language",
|
|
134
|
+
"content-type",
|
|
135
|
+
"user-agent",
|
|
136
|
+
"cache-control",
|
|
137
|
+
"if-match",
|
|
138
|
+
"if-none-match",
|
|
139
|
+
"if-modified-since",
|
|
140
|
+
"if-unmodified-since",
|
|
141
|
+
]);
|
|
142
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
143
|
+
const lowerKey = key.toLowerCase();
|
|
144
|
+
// Always include request-provided headers as-is
|
|
145
|
+
if (isFromRequest) {
|
|
146
|
+
sanitized[key] = value;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
// Redact auth headers
|
|
150
|
+
if (lowerKey === "authorization") {
|
|
151
|
+
sanitized[key] = "[REDACTED]";
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
// Redact API key header
|
|
155
|
+
if (this.config.apiKey &&
|
|
156
|
+
lowerKey === this.config.apiKey.headerName.toLowerCase()) {
|
|
157
|
+
sanitized[key] = "[REDACTED]";
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// Show safe headers, redact others
|
|
161
|
+
if (safeHeaders.has(lowerKey)) {
|
|
162
|
+
sanitized[key] = value;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
sanitized[key] = "[REDACTED]";
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return sanitized;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Execute an HTTP request
|
|
172
|
+
*/
|
|
173
|
+
async request(options) {
|
|
174
|
+
const { method, endpoint, body, headers: requestHeaders, host } = options;
|
|
175
|
+
// Normalize endpoint (ensure leading slash, remove trailing)
|
|
176
|
+
const normalizedEndpoint = `/${endpoint.replace(/^\/+|\/+$/g, "")}`;
|
|
177
|
+
// Build full URL
|
|
178
|
+
const baseUrl = host ? host.replace(/\/+$/, "") : this.config.baseUrl;
|
|
179
|
+
const fullUrl = `${baseUrl}${normalizedEndpoint}`;
|
|
180
|
+
// Build headers
|
|
181
|
+
const headers = {
|
|
182
|
+
...this.config.customHeaders,
|
|
183
|
+
...requestHeaders,
|
|
184
|
+
};
|
|
185
|
+
// Add content-type for JSON body
|
|
186
|
+
if (body && !headers["Content-Type"] && !headers["content-type"]) {
|
|
187
|
+
headers["Content-Type"] = "application/json";
|
|
188
|
+
}
|
|
189
|
+
// Add auth header
|
|
190
|
+
const authHeader = await this.getAuthHeader();
|
|
191
|
+
if (authHeader) {
|
|
192
|
+
headers[authHeader.name] = authHeader.value;
|
|
193
|
+
}
|
|
194
|
+
// Prepare fetch options
|
|
195
|
+
const fetchOptions = {
|
|
196
|
+
method,
|
|
197
|
+
headers,
|
|
198
|
+
};
|
|
199
|
+
// Add body for methods that support it
|
|
200
|
+
if (["POST", "PUT", "PATCH"].includes(method) && body) {
|
|
201
|
+
fetchOptions.body =
|
|
202
|
+
typeof body === "string" ? body : JSON.stringify(body);
|
|
203
|
+
}
|
|
204
|
+
// Add timeout via AbortController
|
|
205
|
+
const controller = new AbortController();
|
|
206
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout || 30000);
|
|
207
|
+
fetchOptions.signal = controller.signal;
|
|
208
|
+
const startTime = Date.now();
|
|
209
|
+
try {
|
|
210
|
+
const response = await fetch(fullUrl, fetchOptions);
|
|
211
|
+
clearTimeout(timeoutId);
|
|
212
|
+
const endTime = Date.now();
|
|
213
|
+
// Get response body
|
|
214
|
+
const responseText = await response.text();
|
|
215
|
+
let responseBody;
|
|
216
|
+
try {
|
|
217
|
+
responseBody = JSON.parse(responseText);
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
responseBody = responseText;
|
|
221
|
+
}
|
|
222
|
+
// Get response headers
|
|
223
|
+
const responseHeaders = {};
|
|
224
|
+
response.headers.forEach((value, key) => {
|
|
225
|
+
responseHeaders[key] = value;
|
|
226
|
+
});
|
|
227
|
+
// Check response size
|
|
228
|
+
const bodySize = Buffer.from(responseText).length;
|
|
229
|
+
const sizeLimit = this.config.responseSizeLimit || 10000;
|
|
230
|
+
const validation = {
|
|
231
|
+
isError: response.status >= 400,
|
|
232
|
+
messages: response.status >= 400
|
|
233
|
+
? [`Request failed with status ${response.status}`]
|
|
234
|
+
: ["Request completed successfully"],
|
|
235
|
+
};
|
|
236
|
+
if (bodySize > sizeLimit) {
|
|
237
|
+
responseBody =
|
|
238
|
+
typeof responseBody === "string"
|
|
239
|
+
? responseBody.slice(0, sizeLimit)
|
|
240
|
+
: JSON.stringify(responseBody).slice(0, sizeLimit);
|
|
241
|
+
validation.messages.push(`Response truncated: ${sizeLimit} of ${bodySize} bytes returned due to size limit`);
|
|
242
|
+
validation.truncated = {
|
|
243
|
+
originalSize: bodySize,
|
|
244
|
+
returnedSize: sizeLimit,
|
|
245
|
+
truncationPoint: sizeLimit,
|
|
246
|
+
sizeLimit,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
return {
|
|
250
|
+
request: {
|
|
251
|
+
url: fullUrl,
|
|
252
|
+
method,
|
|
253
|
+
headers: {
|
|
254
|
+
...this.sanitizeHeaders(headers, false),
|
|
255
|
+
...this.sanitizeHeaders(requestHeaders || {}, true),
|
|
256
|
+
},
|
|
257
|
+
body,
|
|
258
|
+
authMethod: this.getAuthMethod(),
|
|
259
|
+
},
|
|
260
|
+
response: {
|
|
261
|
+
statusCode: response.status,
|
|
262
|
+
statusText: response.statusText,
|
|
263
|
+
timing: `${endTime - startTime}ms`,
|
|
264
|
+
headers: this.sanitizeHeaders(responseHeaders, false),
|
|
265
|
+
body: responseBody,
|
|
266
|
+
},
|
|
267
|
+
validation,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
catch (error) {
|
|
271
|
+
clearTimeout(timeoutId);
|
|
272
|
+
// Handle abort/timeout
|
|
273
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
274
|
+
throw new Error(`Request timeout after ${this.config.timeout}ms`);
|
|
275
|
+
}
|
|
276
|
+
throw error;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Force refresh the OAuth2 token (clears cache)
|
|
281
|
+
*/
|
|
282
|
+
clearTokenCache() {
|
|
283
|
+
this.cachedToken = null;
|
|
284
|
+
console.error("OAuth2 token cache cleared");
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Get configuration summary (safe to display)
|
|
288
|
+
*/
|
|
289
|
+
getConfigSummary() {
|
|
290
|
+
return {
|
|
291
|
+
baseUrl: this.config.baseUrl,
|
|
292
|
+
authMethod: this.getAuthMethod(),
|
|
293
|
+
sslVerification: this.config.enableSslVerify !== false,
|
|
294
|
+
responseSizeLimit: this.config.responseSizeLimit || 10000,
|
|
295
|
+
customHeaderCount: Object.keys(this.config.customHeaders || {}).length,
|
|
296
|
+
...(this.config.oauth2 && { oauth2TokenUrl: this.config.oauth2.tokenUrl }),
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=RestApiService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RestApiService.js","sourceRoot":"","sources":["../src/RestApiService.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @mcp-consultant-tools/rest-api
|
|
4
|
+
*
|
|
5
|
+
* MCP server for REST API testing with OAuth2 client credentials support.
|
|
6
|
+
* Enables AI assistants to test HTTP endpoints with automatic JWT token generation.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - HTTP methods: GET, POST, PUT, DELETE, PATCH
|
|
10
|
+
* - Authentication: Static bearer, Basic auth, API key, OAuth2 client credentials
|
|
11
|
+
* - Response size limiting and truncation
|
|
12
|
+
* - SSL verification control
|
|
13
|
+
* - Custom headers support
|
|
14
|
+
*/
|
|
15
|
+
import { RestApiService } from "./RestApiService.js";
|
|
16
|
+
/**
|
|
17
|
+
* Register REST API tools and prompts to an MCP server
|
|
18
|
+
* @param server - The MCP server instance
|
|
19
|
+
* @param restApiService - Optional pre-configured RestApiService (for testing)
|
|
20
|
+
*/
|
|
21
|
+
export declare function registerRestApiTools(server: any, restApiService?: RestApiService): void;
|
|
22
|
+
/**
|
|
23
|
+
* Export service class for direct usage
|
|
24
|
+
*/
|
|
25
|
+
export { RestApiService } from "./RestApiService.js";
|
|
26
|
+
export type { RestApiConfig, RequestOptions, RequestResult } from "./RestApiService.js";
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAYH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAgGrD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,GAAG,EACX,cAAc,CAAC,EAAE,cAAc,QAqahC;AAED;;GAEG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @mcp-consultant-tools/rest-api
|
|
4
|
+
*
|
|
5
|
+
* MCP server for REST API testing with OAuth2 client credentials support.
|
|
6
|
+
* Enables AI assistants to test HTTP endpoints with automatic JWT token generation.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - HTTP methods: GET, POST, PUT, DELETE, PATCH
|
|
10
|
+
* - Authentication: Static bearer, Basic auth, API key, OAuth2 client credentials
|
|
11
|
+
* - Response size limiting and truncation
|
|
12
|
+
* - SSL verification control
|
|
13
|
+
* - Custom headers support
|
|
14
|
+
*/
|
|
15
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
16
|
+
import { z } from "zod";
|
|
17
|
+
import { pathToFileURL } from "node:url";
|
|
18
|
+
import { realpathSync } from "node:fs";
|
|
19
|
+
import { createMcpServer, createEnvLoader, createErrorResponse, createSuccessResponse, } from "@mcp-consultant-tools/core";
|
|
20
|
+
import { RestApiService } from "./RestApiService.js";
|
|
21
|
+
// Tool count for documentation
|
|
22
|
+
const TOOL_COUNT = 4;
|
|
23
|
+
const PROMPT_COUNT = 2;
|
|
24
|
+
/**
|
|
25
|
+
* Parse environment variables for custom headers (HEADER_* pattern)
|
|
26
|
+
*/
|
|
27
|
+
function getCustomHeadersFromEnv() {
|
|
28
|
+
const headers = {};
|
|
29
|
+
const headerPrefix = /^HEADER_/i;
|
|
30
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
31
|
+
if (headerPrefix.test(key) && value !== undefined) {
|
|
32
|
+
const headerName = key.replace(headerPrefix, "");
|
|
33
|
+
headers[headerName] = value;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return headers;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Build RestApiConfig from environment variables
|
|
40
|
+
*/
|
|
41
|
+
function buildConfigFromEnv() {
|
|
42
|
+
const baseUrl = process.env.REST_BASE_URL;
|
|
43
|
+
if (!baseUrl) {
|
|
44
|
+
throw new Error("REST_BASE_URL environment variable is required");
|
|
45
|
+
}
|
|
46
|
+
const config = {
|
|
47
|
+
baseUrl,
|
|
48
|
+
responseSizeLimit: process.env.REST_RESPONSE_SIZE_LIMIT
|
|
49
|
+
? parseInt(process.env.REST_RESPONSE_SIZE_LIMIT, 10)
|
|
50
|
+
: 10000,
|
|
51
|
+
enableSslVerify: process.env.REST_ENABLE_SSL_VERIFY !== "false",
|
|
52
|
+
timeout: process.env.REST_TIMEOUT
|
|
53
|
+
? parseInt(process.env.REST_TIMEOUT, 10)
|
|
54
|
+
: 30000,
|
|
55
|
+
customHeaders: getCustomHeadersFromEnv(),
|
|
56
|
+
};
|
|
57
|
+
// OAuth2 client credentials (highest priority)
|
|
58
|
+
if (process.env.OAUTH2_TOKEN_URL &&
|
|
59
|
+
process.env.OAUTH2_CLIENT_ID &&
|
|
60
|
+
process.env.OAUTH2_CLIENT_SECRET &&
|
|
61
|
+
process.env.OAUTH2_SCOPE) {
|
|
62
|
+
config.oauth2 = {
|
|
63
|
+
tokenUrl: process.env.OAUTH2_TOKEN_URL,
|
|
64
|
+
clientId: process.env.OAUTH2_CLIENT_ID,
|
|
65
|
+
clientSecret: process.env.OAUTH2_CLIENT_SECRET,
|
|
66
|
+
scope: process.env.OAUTH2_SCOPE,
|
|
67
|
+
grantType: process.env.OAUTH2_GRANT_TYPE || "client_credentials",
|
|
68
|
+
};
|
|
69
|
+
// Parse additional OAuth2 parameters
|
|
70
|
+
if (process.env.OAUTH2_ADDITIONAL_PARAMS) {
|
|
71
|
+
try {
|
|
72
|
+
config.oauth2.additionalParams = JSON.parse(process.env.OAUTH2_ADDITIONAL_PARAMS);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
console.error("Warning: OAUTH2_ADDITIONAL_PARAMS is not valid JSON");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Static bearer token
|
|
80
|
+
else if (process.env.AUTH_BEARER) {
|
|
81
|
+
config.bearerToken = process.env.AUTH_BEARER;
|
|
82
|
+
}
|
|
83
|
+
// Basic auth
|
|
84
|
+
else if (process.env.AUTH_BASIC_USERNAME && process.env.AUTH_BASIC_PASSWORD) {
|
|
85
|
+
config.basicAuth = {
|
|
86
|
+
username: process.env.AUTH_BASIC_USERNAME,
|
|
87
|
+
password: process.env.AUTH_BASIC_PASSWORD,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// API key
|
|
91
|
+
else if (process.env.AUTH_APIKEY_HEADER_NAME &&
|
|
92
|
+
process.env.AUTH_APIKEY_VALUE) {
|
|
93
|
+
config.apiKey = {
|
|
94
|
+
headerName: process.env.AUTH_APIKEY_HEADER_NAME,
|
|
95
|
+
value: process.env.AUTH_APIKEY_VALUE,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return config;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Register REST API tools and prompts to an MCP server
|
|
102
|
+
* @param server - The MCP server instance
|
|
103
|
+
* @param restApiService - Optional pre-configured RestApiService (for testing)
|
|
104
|
+
*/
|
|
105
|
+
export function registerRestApiTools(server, restApiService) {
|
|
106
|
+
let service = restApiService || null;
|
|
107
|
+
function getRestApiService() {
|
|
108
|
+
if (!service) {
|
|
109
|
+
const config = buildConfigFromEnv();
|
|
110
|
+
service = new RestApiService(config);
|
|
111
|
+
console.error("REST API service initialized");
|
|
112
|
+
console.error(` Base URL: ${config.baseUrl}`);
|
|
113
|
+
console.error(` Auth method: ${service.getAuthMethod()}`);
|
|
114
|
+
if (config.oauth2) {
|
|
115
|
+
console.error(` OAuth2 Token URL: ${config.oauth2.tokenUrl}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return service;
|
|
119
|
+
}
|
|
120
|
+
// ============================================================
|
|
121
|
+
// TOOLS
|
|
122
|
+
// ============================================================
|
|
123
|
+
// Tool: rest-request
|
|
124
|
+
server.tool("rest-request", `Test a REST API endpoint with automatic authentication. Supports GET, POST, PUT, DELETE, PATCH methods. Authentication is handled automatically based on server configuration (OAuth2 client credentials, bearer token, basic auth, or API key). Returns detailed request/response information including timing, headers, and body.`, {
|
|
125
|
+
method: z
|
|
126
|
+
.enum(["GET", "POST", "PUT", "DELETE", "PATCH"])
|
|
127
|
+
.describe("HTTP method to use"),
|
|
128
|
+
endpoint: z
|
|
129
|
+
.string()
|
|
130
|
+
.describe('Endpoint path (e.g., "/users", "/api/v1/orders"). Do not include the full URL - only the path.'),
|
|
131
|
+
body: z
|
|
132
|
+
.any()
|
|
133
|
+
.optional()
|
|
134
|
+
.describe("Request body for POST/PUT/PATCH requests (object or string)"),
|
|
135
|
+
headers: z
|
|
136
|
+
.record(z.string())
|
|
137
|
+
.optional()
|
|
138
|
+
.describe("Additional headers for this request. Do not use for auth - configure auth via environment variables."),
|
|
139
|
+
host: z
|
|
140
|
+
.string()
|
|
141
|
+
.optional()
|
|
142
|
+
.describe("Override base URL for this request only (e.g., 'https://other-api.com')"),
|
|
143
|
+
}, async ({ method, endpoint, body, headers, host, }) => {
|
|
144
|
+
try {
|
|
145
|
+
const restService = getRestApiService();
|
|
146
|
+
// Validate endpoint doesn't contain full URL
|
|
147
|
+
const urlPattern = /^(https?:\/\/|www\.)/i;
|
|
148
|
+
if (urlPattern.test(endpoint)) {
|
|
149
|
+
return createErrorResponse(new Error(`Invalid endpoint format. Do not include full URLs. Use just the path (e.g., "/api/users") and optionally specify 'host' to override the base URL.`), "rest-request");
|
|
150
|
+
}
|
|
151
|
+
const options = {
|
|
152
|
+
method,
|
|
153
|
+
endpoint,
|
|
154
|
+
body,
|
|
155
|
+
headers,
|
|
156
|
+
host,
|
|
157
|
+
};
|
|
158
|
+
const result = await restService.request(options);
|
|
159
|
+
return createSuccessResponse(result);
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
return createErrorResponse(error, "rest-request");
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
// Tool: rest-config
|
|
166
|
+
server.tool("rest-config", "Get the current REST API service configuration summary, including base URL, authentication method, SSL settings, and custom headers count.", {}, async () => {
|
|
167
|
+
try {
|
|
168
|
+
const restService = getRestApiService();
|
|
169
|
+
const summary = restService.getConfigSummary();
|
|
170
|
+
return createSuccessResponse(summary);
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
return createErrorResponse(error, "rest-config");
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
// Tool: rest-refresh-token
|
|
177
|
+
server.tool("rest-refresh-token", "Force refresh the OAuth2 access token. Clears the token cache and acquires a new token on the next request. Only relevant when using OAuth2 authentication.", {}, async () => {
|
|
178
|
+
try {
|
|
179
|
+
const restService = getRestApiService();
|
|
180
|
+
const authMethod = restService.getAuthMethod();
|
|
181
|
+
if (authMethod !== "oauth2") {
|
|
182
|
+
return createErrorResponse(new Error(`Token refresh only available for OAuth2 authentication. Current auth method: ${authMethod}`), "rest-refresh-token");
|
|
183
|
+
}
|
|
184
|
+
restService.clearTokenCache();
|
|
185
|
+
return createSuccessResponse({
|
|
186
|
+
message: "OAuth2 token cache cleared. A new token will be acquired on the next request.",
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
return createErrorResponse(error, "rest-refresh-token");
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
// Tool: rest-batch-request
|
|
194
|
+
server.tool("rest-batch-request", "Execute multiple REST API requests sequentially. Useful for testing a series of related endpoints or performing a workflow. Returns results for all requests.", {
|
|
195
|
+
requests: z.array(z.object({
|
|
196
|
+
method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH"]),
|
|
197
|
+
endpoint: z.string(),
|
|
198
|
+
body: z.any().optional(),
|
|
199
|
+
headers: z.record(z.string()).optional(),
|
|
200
|
+
host: z.string().optional(),
|
|
201
|
+
})).describe("Array of request configurations to execute sequentially"),
|
|
202
|
+
stopOnError: z
|
|
203
|
+
.boolean()
|
|
204
|
+
.optional()
|
|
205
|
+
.describe("Stop executing remaining requests if one fails (default: false)"),
|
|
206
|
+
}, async ({ requests, stopOnError = false, }) => {
|
|
207
|
+
try {
|
|
208
|
+
const restService = getRestApiService();
|
|
209
|
+
const results = [];
|
|
210
|
+
for (let i = 0; i < requests.length; i++) {
|
|
211
|
+
const req = requests[i];
|
|
212
|
+
try {
|
|
213
|
+
const result = await restService.request(req);
|
|
214
|
+
results.push({
|
|
215
|
+
index: i,
|
|
216
|
+
endpoint: req.endpoint,
|
|
217
|
+
success: !result.validation.isError,
|
|
218
|
+
result,
|
|
219
|
+
});
|
|
220
|
+
if (stopOnError && result.validation.isError) {
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
226
|
+
results.push({
|
|
227
|
+
index: i,
|
|
228
|
+
endpoint: req.endpoint,
|
|
229
|
+
success: false,
|
|
230
|
+
error: errorMessage,
|
|
231
|
+
});
|
|
232
|
+
if (stopOnError) {
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return createSuccessResponse({
|
|
238
|
+
totalRequests: requests.length,
|
|
239
|
+
executedRequests: results.length,
|
|
240
|
+
successfulRequests: results.filter((r) => r.success).length,
|
|
241
|
+
results,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
return createErrorResponse(error, "rest-batch-request");
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
// ============================================================
|
|
249
|
+
// PROMPTS
|
|
250
|
+
// ============================================================
|
|
251
|
+
// Prompt: rest-api-guide
|
|
252
|
+
server.prompt("rest-api-guide", "Comprehensive guide for using the REST API testing tools", {}, async () => {
|
|
253
|
+
const markdown = `# REST API Testing Guide
|
|
254
|
+
|
|
255
|
+
## Overview
|
|
256
|
+
|
|
257
|
+
This MCP server enables testing REST API endpoints with comprehensive authentication support, including automatic JWT token generation via OAuth2 client credentials flow.
|
|
258
|
+
|
|
259
|
+
## Available Tools
|
|
260
|
+
|
|
261
|
+
### 1. rest-request
|
|
262
|
+
Execute a single HTTP request to any REST endpoint.
|
|
263
|
+
|
|
264
|
+
**Parameters:**
|
|
265
|
+
- \`method\`: HTTP method (GET, POST, PUT, DELETE, PATCH)
|
|
266
|
+
- \`endpoint\`: API path (e.g., "/users", "/api/v1/orders")
|
|
267
|
+
- \`body\`: Request body for POST/PUT/PATCH (optional)
|
|
268
|
+
- \`headers\`: Additional headers (optional)
|
|
269
|
+
- \`host\`: Override base URL (optional)
|
|
270
|
+
|
|
271
|
+
**Example:**
|
|
272
|
+
\`\`\`json
|
|
273
|
+
{
|
|
274
|
+
"method": "POST",
|
|
275
|
+
"endpoint": "/api/users",
|
|
276
|
+
"body": { "name": "John", "email": "john@example.com" }
|
|
277
|
+
}
|
|
278
|
+
\`\`\`
|
|
279
|
+
|
|
280
|
+
### 2. rest-config
|
|
281
|
+
Get current service configuration summary.
|
|
282
|
+
|
|
283
|
+
### 3. rest-refresh-token
|
|
284
|
+
Force refresh OAuth2 token (clears cache).
|
|
285
|
+
|
|
286
|
+
### 4. rest-batch-request
|
|
287
|
+
Execute multiple requests sequentially.
|
|
288
|
+
|
|
289
|
+
## Authentication Methods
|
|
290
|
+
|
|
291
|
+
### OAuth2 Client Credentials (Recommended for APIs)
|
|
292
|
+
Automatically acquires and caches JWT tokens. Tokens are refreshed when expired.
|
|
293
|
+
|
|
294
|
+
Required environment variables:
|
|
295
|
+
- \`OAUTH2_TOKEN_URL\`: Token endpoint URL
|
|
296
|
+
- \`OAUTH2_CLIENT_ID\`: Client ID
|
|
297
|
+
- \`OAUTH2_CLIENT_SECRET\`: Client secret
|
|
298
|
+
- \`OAUTH2_SCOPE\`: OAuth2 scope
|
|
299
|
+
|
|
300
|
+
### Static Bearer Token
|
|
301
|
+
For pre-acquired tokens:
|
|
302
|
+
- \`AUTH_BEARER\`: The bearer token value
|
|
303
|
+
|
|
304
|
+
### Basic Authentication
|
|
305
|
+
- \`AUTH_BASIC_USERNAME\`: Username
|
|
306
|
+
- \`AUTH_BASIC_PASSWORD\`: Password
|
|
307
|
+
|
|
308
|
+
### API Key
|
|
309
|
+
- \`AUTH_APIKEY_HEADER_NAME\`: Header name
|
|
310
|
+
- \`AUTH_APIKEY_VALUE\`: API key value
|
|
311
|
+
|
|
312
|
+
## Configuration
|
|
313
|
+
|
|
314
|
+
### Required
|
|
315
|
+
- \`REST_BASE_URL\`: Base URL for all requests
|
|
316
|
+
|
|
317
|
+
### Optional
|
|
318
|
+
- \`REST_RESPONSE_SIZE_LIMIT\`: Max response size in bytes (default: 10000)
|
|
319
|
+
- \`REST_ENABLE_SSL_VERIFY\`: SSL verification (default: true)
|
|
320
|
+
- \`REST_TIMEOUT\`: Request timeout in ms (default: 30000)
|
|
321
|
+
- \`HEADER_*\`: Custom headers (e.g., HEADER_Accept=application/json)
|
|
322
|
+
|
|
323
|
+
## Best Practices
|
|
324
|
+
|
|
325
|
+
1. **Use OAuth2 for production APIs** - Automatic token management
|
|
326
|
+
2. **Set appropriate response limits** - Prevent memory issues
|
|
327
|
+
3. **Use custom headers wisely** - Don't put secrets in headers
|
|
328
|
+
4. **Enable SSL verification** - Only disable for development
|
|
329
|
+
`;
|
|
330
|
+
return {
|
|
331
|
+
messages: [
|
|
332
|
+
{
|
|
333
|
+
role: "user",
|
|
334
|
+
content: { type: "text", text: markdown },
|
|
335
|
+
},
|
|
336
|
+
],
|
|
337
|
+
};
|
|
338
|
+
});
|
|
339
|
+
// Prompt: rest-api-troubleshoot
|
|
340
|
+
server.prompt("rest-api-troubleshoot", "Troubleshooting guide for common REST API testing issues", {}, async () => {
|
|
341
|
+
const markdown = `# REST API Troubleshooting Guide
|
|
342
|
+
|
|
343
|
+
## Common Issues and Solutions
|
|
344
|
+
|
|
345
|
+
### 1. Authentication Failures
|
|
346
|
+
|
|
347
|
+
**Symptom:** 401 Unauthorized or 403 Forbidden responses
|
|
348
|
+
|
|
349
|
+
**Solutions:**
|
|
350
|
+
- For OAuth2: Check token URL, client ID, client secret, and scope
|
|
351
|
+
- Use \`rest-refresh-token\` to force a new token
|
|
352
|
+
- Verify scope matches API requirements
|
|
353
|
+
- Check if credentials have expired
|
|
354
|
+
|
|
355
|
+
### 2. Connection Issues
|
|
356
|
+
|
|
357
|
+
**Symptom:** ECONNREFUSED, ETIMEDOUT, or network errors
|
|
358
|
+
|
|
359
|
+
**Solutions:**
|
|
360
|
+
- Verify REST_BASE_URL is correct
|
|
361
|
+
- Check if API is accessible from your network
|
|
362
|
+
- For self-signed certs, set REST_ENABLE_SSL_VERIFY=false (dev only)
|
|
363
|
+
- Increase REST_TIMEOUT for slow APIs
|
|
364
|
+
|
|
365
|
+
### 3. Response Truncation
|
|
366
|
+
|
|
367
|
+
**Symptom:** Response body appears cut off
|
|
368
|
+
|
|
369
|
+
**Solution:** Increase REST_RESPONSE_SIZE_LIMIT environment variable
|
|
370
|
+
|
|
371
|
+
### 4. Token Expiration
|
|
372
|
+
|
|
373
|
+
**Symptom:** Requests work initially then fail with 401
|
|
374
|
+
|
|
375
|
+
**Solution:**
|
|
376
|
+
- OAuth2 tokens are auto-refreshed, but you can force with rest-refresh-token
|
|
377
|
+
- For static bearer tokens, manually update AUTH_BEARER
|
|
378
|
+
|
|
379
|
+
### 5. CORS Issues
|
|
380
|
+
|
|
381
|
+
**Note:** MCP servers run server-side, so CORS doesn't apply.
|
|
382
|
+
If you see CORS-related errors, the issue is elsewhere.
|
|
383
|
+
|
|
384
|
+
## Debugging Steps
|
|
385
|
+
|
|
386
|
+
1. Use \`rest-config\` to verify current configuration
|
|
387
|
+
2. Try a simple GET request first
|
|
388
|
+
3. Check response timing for network issues
|
|
389
|
+
4. Examine response headers for error details
|
|
390
|
+
5. Use \`rest-refresh-token\` if auth seems stale
|
|
391
|
+
|
|
392
|
+
## Environment Variable Reference
|
|
393
|
+
|
|
394
|
+
\`\`\`bash
|
|
395
|
+
# Required
|
|
396
|
+
REST_BASE_URL=https://api.example.com
|
|
397
|
+
|
|
398
|
+
# OAuth2 (recommended)
|
|
399
|
+
OAUTH2_TOKEN_URL=https://login.example.com/oauth2/token
|
|
400
|
+
OAUTH2_CLIENT_ID=your-client-id
|
|
401
|
+
OAUTH2_CLIENT_SECRET=your-secret
|
|
402
|
+
OAUTH2_SCOPE=api://your-app/.default
|
|
403
|
+
|
|
404
|
+
# Alternative: Static bearer
|
|
405
|
+
AUTH_BEARER=your-token
|
|
406
|
+
|
|
407
|
+
# Alternative: Basic auth
|
|
408
|
+
AUTH_BASIC_USERNAME=user
|
|
409
|
+
AUTH_BASIC_PASSWORD=pass
|
|
410
|
+
|
|
411
|
+
# Alternative: API key
|
|
412
|
+
AUTH_APIKEY_HEADER_NAME=X-Api-Key
|
|
413
|
+
AUTH_APIKEY_VALUE=your-key
|
|
414
|
+
|
|
415
|
+
# Optional settings
|
|
416
|
+
REST_RESPONSE_SIZE_LIMIT=50000
|
|
417
|
+
REST_ENABLE_SSL_VERIFY=true
|
|
418
|
+
REST_TIMEOUT=60000
|
|
419
|
+
|
|
420
|
+
# Custom headers
|
|
421
|
+
HEADER_Accept=application/json
|
|
422
|
+
HEADER_X-Custom=value
|
|
423
|
+
\`\`\`
|
|
424
|
+
`;
|
|
425
|
+
return {
|
|
426
|
+
messages: [
|
|
427
|
+
{
|
|
428
|
+
role: "user",
|
|
429
|
+
content: { type: "text", text: markdown },
|
|
430
|
+
},
|
|
431
|
+
],
|
|
432
|
+
};
|
|
433
|
+
});
|
|
434
|
+
console.error(`REST API tools registered: ${TOOL_COUNT} tools, ${PROMPT_COUNT} prompts`);
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Export service class for direct usage
|
|
438
|
+
*/
|
|
439
|
+
export { RestApiService } from "./RestApiService.js";
|
|
440
|
+
/**
|
|
441
|
+
* Standalone CLI server (when run directly)
|
|
442
|
+
*/
|
|
443
|
+
if (import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href) {
|
|
444
|
+
const loadEnv = createEnvLoader();
|
|
445
|
+
loadEnv();
|
|
446
|
+
const server = createMcpServer({
|
|
447
|
+
name: "@mcp-consultant-tools/rest-api",
|
|
448
|
+
version: "1.0.0",
|
|
449
|
+
capabilities: {
|
|
450
|
+
tools: {},
|
|
451
|
+
prompts: {},
|
|
452
|
+
},
|
|
453
|
+
});
|
|
454
|
+
registerRestApiTools(server);
|
|
455
|
+
const transport = new StdioServerTransport();
|
|
456
|
+
server.connect(transport).catch((error) => {
|
|
457
|
+
console.error("Failed to start REST API MCP server:", error);
|
|
458
|
+
process.exit(1);
|
|
459
|
+
});
|
|
460
|
+
console.error("@mcp-consultant-tools/rest-api server running on stdio");
|
|
461
|
+
}
|
|
462
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EACL,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,+BAA+B;AAC/B,MAAM,UAAU,GAAG,CAAC,CAAC;AACrB,MAAM,YAAY,GAAG,CAAC,CAAC;AAEvB;;GAEG;AACH,SAAS,uBAAuB;IAC9B,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,YAAY,GAAG,WAAW,CAAC;IAEjC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvD,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAClD,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YACjD,OAAO,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,kBAAkB;IACzB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,MAAM,GAAkB;QAC5B,OAAO;QACP,iBAAiB,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB;YACrD,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,EAAE,CAAC;YACpD,CAAC,CAAC,KAAK;QACT,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,KAAK,OAAO;QAC/D,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;YAC/B,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,CAAC;YACxC,CAAC,CAAC,KAAK;QACT,aAAa,EAAE,uBAAuB,EAAE;KACzC,CAAC;IAEF,+CAA+C;IAC/C,IACE,OAAO,CAAC,GAAG,CAAC,gBAAgB;QAC5B,OAAO,CAAC,GAAG,CAAC,gBAAgB;QAC5B,OAAO,CAAC,GAAG,CAAC,oBAAoB;QAChC,OAAO,CAAC,GAAG,CAAC,YAAY,EACxB,CAAC;QACD,MAAM,CAAC,MAAM,GAAG;YACd,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB;YACtC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB;YACtC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;YAC9C,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;YAC/B,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,oBAAoB;SACjE,CAAC;QAEF,qCAAqC;QACrC,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;YACzC,IAAI,CAAC;gBACH,MAAM,CAAC,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CACzC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CACrC,CAAC;YACJ,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACvE,CAAC;QACH,CAAC;IACH,CAAC;IACD,sBAAsB;SACjB,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACjC,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAC/C,CAAC;IACD,aAAa;SACR,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;QAC5E,MAAM,CAAC,SAAS,GAAG;YACjB,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;YACzC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB;SAC1C,CAAC;IACJ,CAAC;IACD,UAAU;SACL,IACH,OAAO,CAAC,GAAG,CAAC,uBAAuB;QACnC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAC7B,CAAC;QACD,MAAM,CAAC,MAAM,GAAG;YACd,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB;YAC/C,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;SACrC,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAW,EACX,cAA+B;IAE/B,IAAI,OAAO,GAA0B,cAAc,IAAI,IAAI,CAAC;IAE5D,SAAS,iBAAiB;QACxB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;YACpC,OAAO,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;YACrC,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAC9C,OAAO,CAAC,KAAK,CAAC,eAAe,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YAC/C,OAAO,CAAC,KAAK,CAAC,kBAAkB,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;YAC3D,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,OAAO,CAAC,KAAK,CAAC,uBAAuB,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,+DAA+D;IAC/D,QAAQ;IACR,+DAA+D;IAE/D,qBAAqB;IACrB,MAAM,CAAC,IAAI,CACT,cAAc,EACd,qUAAqU,EACrU;QACE,MAAM,EAAE,CAAC;aACN,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;aAC/C,QAAQ,CAAC,oBAAoB,CAAC;QACjC,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,CACP,gGAAgG,CACjG;QACH,IAAI,EAAE,CAAC;aACJ,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,CAAC,6DAA6D,CAAC;QAC1E,OAAO,EAAE,CAAC;aACP,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aAClB,QAAQ,EAAE;aACV,QAAQ,CACP,sGAAsG,CACvG;QACH,IAAI,EAAE,CAAC;aACJ,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,yEAAyE,CAC1E;KACJ,EACD,KAAK,EAAE,EACL,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,IAAI,GAOL,EAAE,EAAE;QACH,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,iBAAiB,EAAE,CAAC;YAExC,6CAA6C;YAC7C,MAAM,UAAU,GAAG,uBAAuB,CAAC;YAC3C,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9B,OAAO,mBAAmB,CACxB,IAAI,KAAK,CACP,mJAAmJ,CACpJ,EACD,cAAc,CACf,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAmB;gBAC9B,MAAM;gBACN,QAAQ;gBACR,IAAI;gBACJ,OAAO;gBACP,IAAI;aACL,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAClD,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,oBAAoB;IACpB,MAAM,CAAC,IAAI,CACT,aAAa,EACb,4IAA4I,EAC5I,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,iBAAiB,EAAE,CAAC;YACxC,MAAM,OAAO,GAAG,WAAW,CAAC,gBAAgB,EAAE,CAAC;YAC/C,OAAO,qBAAqB,CAAC,OAAO,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;QACnD,CAAC;IACH,CAAC,CACF,CAAC;IAEF,2BAA2B;IAC3B,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,6JAA6J,EAC7J,EAAE,EACF,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,iBAAiB,EAAE,CAAC;YACxC,MAAM,UAAU,GAAG,WAAW,CAAC,aAAa,EAAE,CAAC;YAE/C,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;gBAC5B,OAAO,mBAAmB,CACxB,IAAI,KAAK,CACP,gFAAgF,UAAU,EAAE,CAC7F,EACD,oBAAoB,CACrB,CAAC;YACJ,CAAC;YAED,WAAW,CAAC,eAAe,EAAE,CAAC;YAC9B,OAAO,qBAAqB,CAAC;gBAC3B,OAAO,EAAE,+EAA+E;aACzF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CACF,CAAC;IAEF,2BAA2B;IAC3B,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,+JAA+J,EAC/J;QACE,QAAQ,EAAE,CAAC,CAAC,KAAK,CACf,CAAC,CAAC,MAAM,CAAC;YACP,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YACzD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;YACpB,IAAI,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;YACxB,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SAC5B,CAAC,CACH,CAAC,QAAQ,CAAC,yDAAyD,CAAC;QACrE,WAAW,EAAE,CAAC;aACX,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CAAC,iEAAiE,CAAC;KAC/E,EACD,KAAK,EAAE,EACL,QAAQ,EACR,WAAW,GAAG,KAAK,GAIpB,EAAE,EAAE;QACH,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,iBAAiB,EAAE,CAAC;YACxC,MAAM,OAAO,GAMP,EAAE,CAAC;YAET,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAExB,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;oBAC9C,OAAO,CAAC,IAAI,CAAC;wBACX,KAAK,EAAE,CAAC;wBACR,QAAQ,EAAE,GAAG,CAAC,QAAQ;wBACtB,OAAO,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO;wBACnC,MAAM;qBACP,CAAC,CAAC;oBAEH,IAAI,WAAW,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;wBAC7C,MAAM;oBACR,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACzD,OAAO,CAAC,IAAI,CAAC;wBACX,KAAK,EAAE,CAAC;wBACR,QAAQ,EAAE,GAAG,CAAC,QAAQ;wBACtB,OAAO,EAAE,KAAK;wBACd,KAAK,EAAE,YAAY;qBACpB,CAAC,CAAC;oBAEH,IAAI,WAAW,EAAE,CAAC;wBAChB,MAAM;oBACR,CAAC;gBACH,CAAC;YACH,CAAC;YAED,OAAO,qBAAqB,CAAC;gBAC3B,aAAa,EAAE,QAAQ,CAAC,MAAM;gBAC9B,gBAAgB,EAAE,OAAO,CAAC,MAAM;gBAChC,kBAAkB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM;gBAC3D,OAAO;aACR,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,mBAAmB,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CACF,CAAC;IAEF,+DAA+D;IAC/D,UAAU;IACV,+DAA+D;IAE/D,yBAAyB;IACzB,MAAM,CAAC,MAAM,CACX,gBAAgB,EAChB,0DAA0D,EAC1D,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4EtB,CAAC;QACI,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;iBAC1C;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,gCAAgC;IAChC,MAAM,CAAC,MAAM,CACX,uBAAuB,EACvB,0DAA0D,EAC1D,EAAE,EACF,KAAK,IAAI,EAAE;QACT,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmFtB,CAAC;QACI,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE;iBAC1C;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,OAAO,CAAC,KAAK,CACX,8BAA8B,UAAU,WAAW,YAAY,UAAU,CAC1E,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD;;GAEG;AACH,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1E,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,OAAO,EAAE,CAAC;IAEV,MAAM,MAAM,GAAG,eAAe,CAAC;QAC7B,IAAI,EAAE,gCAAgC;QACtC,OAAO,EAAE,OAAO;QAChB,YAAY,EAAE;YACZ,KAAK,EAAE,EAAE;YACT,OAAO,EAAE,EAAE;SACZ;KACF,CAAC,CAAC;IAEH,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE7B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,KAAY,EAAE,EAAE;QAC/C,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;AAC1E,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcp-consultant-tools/rest-api",
|
|
3
|
+
"version": "22.0.0-beta.1",
|
|
4
|
+
"description": "MCP server for REST API testing with OAuth2 client credentials support - test HTTP endpoints with automatic JWT token generation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./build/index.js",
|
|
7
|
+
"types": "./build/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./build/index.js",
|
|
11
|
+
"types": "./build/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"build",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"clean": "rm -rf build *.tsbuildinfo",
|
|
21
|
+
"prepublishOnly": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"mcp",
|
|
25
|
+
"model-context-protocol",
|
|
26
|
+
"rest",
|
|
27
|
+
"api",
|
|
28
|
+
"http",
|
|
29
|
+
"oauth2",
|
|
30
|
+
"jwt",
|
|
31
|
+
"client-credentials",
|
|
32
|
+
"authentication",
|
|
33
|
+
"testing",
|
|
34
|
+
"data-api-builder",
|
|
35
|
+
"dab"
|
|
36
|
+
],
|
|
37
|
+
"author": "Michal Sobieraj",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/klemensms/mcp-consultant-tools.git",
|
|
42
|
+
"directory": "packages/rest-api"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18.0.0"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@mcp-consultant-tools/core": "^20.0.0",
|
|
49
|
+
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
50
|
+
"zod": "^3.24.1"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^22.10.5",
|
|
54
|
+
"typescript": "^5.8.2"
|
|
55
|
+
},
|
|
56
|
+
"bin": {
|
|
57
|
+
"mcp-rest-api": "build/index.js"
|
|
58
|
+
}
|
|
59
|
+
}
|