@skaleagents/swarm 0.6.1 → 0.6.2
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/package.json +1 -1
- package/dist/application/graph.d.ts +0 -45
- package/dist/application/graph.js +0 -264
- package/dist/application/intake.d.ts +0 -63
- package/dist/application/intake.js +0 -182
- package/dist/application/review.d.ts +0 -71
- package/dist/application/review.js +0 -360
- package/dist/application/tools.d.ts +0 -2
- package/dist/application/tools.js +0 -94
- package/dist/auth.d.ts +0 -22
- package/dist/auth.js +0 -285
- package/dist/config.d.ts +0 -4
- package/dist/config.js +0 -15
- package/dist/http.d.ts +0 -2
- package/dist/http.js +0 -134
- package/dist/iac/parse.d.ts +0 -25
- package/dist/iac/parse.js +0 -239
- package/dist/iac/rules.d.ts +0 -16
- package/dist/iac/rules.js +0 -450
- package/dist/iac/scan.d.ts +0 -43
- package/dist/iac/scan.js +0 -60
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -9
- package/dist/review.d.ts +0 -19
- package/dist/review.js +0 -190
- package/dist/server.d.ts +0 -2
- package/dist/server.js +0 -154
- package/dist/version.d.ts +0 -1
- package/dist/version.js +0 -1
package/dist/auth.js
DELETED
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
import { createServer } from "node:http";
|
|
2
|
-
import { spawn } from "node:child_process";
|
|
3
|
-
import { createHash, randomBytes } from "node:crypto";
|
|
4
|
-
import { chmod, mkdir, readFile, unlink, writeFile } from "node:fs/promises";
|
|
5
|
-
import { dirname } from "node:path";
|
|
6
|
-
import { getApiToken, getApiUrl, getOAuthCachePath, isOAuthEnabled } from "./config.js";
|
|
7
|
-
let cachedCredentials = null;
|
|
8
|
-
let authenticationInFlight = null;
|
|
9
|
-
/**
|
|
10
|
-
* Validate the API bearer token before running any tool. OAuth starts in the
|
|
11
|
-
* user's browser when no legacy SKALEAGENTS_API_TOKEN is configured.
|
|
12
|
-
*/
|
|
13
|
-
export async function requireApiAuth() {
|
|
14
|
-
const token = await getAccessToken();
|
|
15
|
-
if (!token) {
|
|
16
|
-
return {
|
|
17
|
-
ok: false,
|
|
18
|
-
reason: isOAuthEnabled() ? "oauth_failed" : "oauth_required",
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
try {
|
|
22
|
-
let res = await fetchApiUser(token);
|
|
23
|
-
if ((res.status === 401 || res.status === 403) && !getApiToken()) {
|
|
24
|
-
const replacementToken = await reauthorizeAfterRejection();
|
|
25
|
-
if (replacementToken) {
|
|
26
|
-
res = await fetchApiUser(replacementToken);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
if (res.status === 401 || res.status === 403) {
|
|
30
|
-
return { ok: false, reason: "unauthorized" };
|
|
31
|
-
}
|
|
32
|
-
if (!res.ok) {
|
|
33
|
-
return { ok: false, reason: "api_unavailable" };
|
|
34
|
-
}
|
|
35
|
-
const user = (await res.json());
|
|
36
|
-
return { ok: true, userId: user.id };
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
return { ok: false, reason: "api_unavailable" };
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
export async function getApiAccessToken() {
|
|
43
|
-
return getAccessToken();
|
|
44
|
-
}
|
|
45
|
-
export function unauthorizedContent(reason) {
|
|
46
|
-
const text = reason.reason === "oauth_required"
|
|
47
|
-
? "MCP OAuth is disabled. Set SKALEAGENTS_API_TOKEN or enable OAuth."
|
|
48
|
-
: reason.reason === "oauth_failed"
|
|
49
|
-
? "MCP sign-in could not be completed. Check the browser window and try again."
|
|
50
|
-
: reason.reason === "unauthorized"
|
|
51
|
-
? "unauthorized: the SkaleAgents connection was rejected"
|
|
52
|
-
: "api unavailable: could not validate the SkaleAgents connection";
|
|
53
|
-
return {
|
|
54
|
-
isError: true,
|
|
55
|
-
content: [{ type: "text", text }],
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
async function getAccessToken() {
|
|
59
|
-
const legacyToken = getApiToken();
|
|
60
|
-
if (legacyToken)
|
|
61
|
-
return legacyToken;
|
|
62
|
-
if (!isOAuthEnabled())
|
|
63
|
-
return null;
|
|
64
|
-
if (!authenticationInFlight) {
|
|
65
|
-
authenticationInFlight = getOAuthAccessToken().finally(() => {
|
|
66
|
-
authenticationInFlight = null;
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
try {
|
|
70
|
-
return await authenticationInFlight;
|
|
71
|
-
}
|
|
72
|
-
catch {
|
|
73
|
-
return null;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
async function fetchApiUser(token) {
|
|
77
|
-
return fetch(`${getApiUrl()}/api/user`, {
|
|
78
|
-
headers: {
|
|
79
|
-
Accept: "application/json",
|
|
80
|
-
Authorization: `Bearer ${token}`,
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
async function reauthorizeAfterRejection() {
|
|
85
|
-
cachedCredentials = null;
|
|
86
|
-
await removeCredentials();
|
|
87
|
-
return getAccessToken();
|
|
88
|
-
}
|
|
89
|
-
async function getOAuthAccessToken() {
|
|
90
|
-
const apiUrl = getApiUrl();
|
|
91
|
-
const metadata = await getMetadata(apiUrl);
|
|
92
|
-
const stored = await readCredentials(apiUrl);
|
|
93
|
-
if (stored && stored.expiresAt > Date.now() + 30_000) {
|
|
94
|
-
cachedCredentials = stored;
|
|
95
|
-
return stored.accessToken;
|
|
96
|
-
}
|
|
97
|
-
if (stored?.refreshToken) {
|
|
98
|
-
try {
|
|
99
|
-
const refreshed = await exchangeRefreshToken(metadata.token_endpoint, stored.refreshToken);
|
|
100
|
-
await saveCredentials(apiUrl, refreshed);
|
|
101
|
-
return refreshed.accessToken;
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
cachedCredentials = null;
|
|
105
|
-
await removeCredentials();
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
const authorizationCode = await authorizeInBrowser(metadata.authorization_endpoint);
|
|
109
|
-
const exchanged = await exchangeAuthorizationCode(metadata.token_endpoint, authorizationCode.code, authorizationCode.redirectUri, authorizationCode.verifier);
|
|
110
|
-
await saveCredentials(apiUrl, exchanged);
|
|
111
|
-
return exchanged.accessToken;
|
|
112
|
-
}
|
|
113
|
-
async function getMetadata(apiUrl) {
|
|
114
|
-
const response = await fetch(`${apiUrl}/.well-known/oauth-authorization-server`, {
|
|
115
|
-
headers: { Accept: "application/json" },
|
|
116
|
-
});
|
|
117
|
-
if (!response.ok) {
|
|
118
|
-
throw new Error(`OAuth metadata request failed with status ${response.status}`);
|
|
119
|
-
}
|
|
120
|
-
const metadata = (await response.json());
|
|
121
|
-
if (typeof metadata.authorization_endpoint !== "string" ||
|
|
122
|
-
typeof metadata.token_endpoint !== "string") {
|
|
123
|
-
throw new Error("OAuth metadata is incomplete");
|
|
124
|
-
}
|
|
125
|
-
return metadata;
|
|
126
|
-
}
|
|
127
|
-
async function authorizeInBrowser(authorizationEndpoint) {
|
|
128
|
-
const verifier = randomBytes(48).toString("base64url");
|
|
129
|
-
const challenge = createCodeChallenge(verifier);
|
|
130
|
-
const state = randomBytes(32).toString("base64url");
|
|
131
|
-
return new Promise((resolve, reject) => {
|
|
132
|
-
let settled = false;
|
|
133
|
-
let redirectUri = "";
|
|
134
|
-
const server = createServer((request, response) => {
|
|
135
|
-
const requestUrl = new URL(request.url ?? "/", `http://${request.headers.host ?? "127.0.0.1"}`);
|
|
136
|
-
if (requestUrl.pathname !== "/oauth/callback") {
|
|
137
|
-
response.writeHead(404);
|
|
138
|
-
response.end("Not found");
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
const receivedState = requestUrl.searchParams.get("state");
|
|
142
|
-
const error = requestUrl.searchParams.get("error");
|
|
143
|
-
const code = requestUrl.searchParams.get("code");
|
|
144
|
-
response.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
145
|
-
response.end("<!doctype html><title>SkaleAgents connected</title>" +
|
|
146
|
-
"<p>You can close this window and return to your AI client.</p>");
|
|
147
|
-
if (settled)
|
|
148
|
-
return;
|
|
149
|
-
settled = true;
|
|
150
|
-
server.close();
|
|
151
|
-
if (receivedState !== state) {
|
|
152
|
-
reject(new Error("OAuth state validation failed"));
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
if (error || !code) {
|
|
156
|
-
reject(new Error("OAuth authorization was denied"));
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
resolve({
|
|
160
|
-
code,
|
|
161
|
-
redirectUri,
|
|
162
|
-
verifier,
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
server.once("error", reject);
|
|
166
|
-
server.listen(0, "127.0.0.1", () => {
|
|
167
|
-
const port = addressPort(server);
|
|
168
|
-
redirectUri = `http://127.0.0.1:${port}/oauth/callback`;
|
|
169
|
-
const url = new URL(authorizationEndpoint);
|
|
170
|
-
url.search = new URLSearchParams({
|
|
171
|
-
client_id: "skaleagents-mcp",
|
|
172
|
-
response_type: "code",
|
|
173
|
-
redirect_uri: redirectUri,
|
|
174
|
-
scope: "mcp",
|
|
175
|
-
state,
|
|
176
|
-
code_challenge: challenge,
|
|
177
|
-
code_challenge_method: "S256",
|
|
178
|
-
}).toString();
|
|
179
|
-
console.error("Opening SkaleAgents sign-in in your browser...");
|
|
180
|
-
console.error(url.toString());
|
|
181
|
-
openBrowser(url.toString());
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
async function exchangeAuthorizationCode(tokenEndpoint, code, redirectUri, verifier) {
|
|
186
|
-
const response = await fetchToken(tokenEndpoint, {
|
|
187
|
-
grant_type: "authorization_code",
|
|
188
|
-
client_id: "skaleagents-mcp",
|
|
189
|
-
code,
|
|
190
|
-
redirect_uri: redirectUri,
|
|
191
|
-
code_verifier: verifier,
|
|
192
|
-
});
|
|
193
|
-
return parseTokenResponse(response);
|
|
194
|
-
}
|
|
195
|
-
async function exchangeRefreshToken(tokenEndpoint, refreshToken) {
|
|
196
|
-
const response = await fetchToken(tokenEndpoint, {
|
|
197
|
-
grant_type: "refresh_token",
|
|
198
|
-
client_id: "skaleagents-mcp",
|
|
199
|
-
refresh_token: refreshToken,
|
|
200
|
-
});
|
|
201
|
-
return parseTokenResponse(response);
|
|
202
|
-
}
|
|
203
|
-
async function fetchToken(tokenEndpoint, values) {
|
|
204
|
-
const response = await fetch(tokenEndpoint, {
|
|
205
|
-
method: "POST",
|
|
206
|
-
headers: {
|
|
207
|
-
Accept: "application/json",
|
|
208
|
-
"Content-Type": "application/x-www-form-urlencoded",
|
|
209
|
-
},
|
|
210
|
-
body: new URLSearchParams(values),
|
|
211
|
-
});
|
|
212
|
-
const payload = (await response.json().catch(() => ({})));
|
|
213
|
-
if (!response.ok) {
|
|
214
|
-
throw new Error(`OAuth token request failed with status ${response.status}`);
|
|
215
|
-
}
|
|
216
|
-
return payload;
|
|
217
|
-
}
|
|
218
|
-
function parseTokenResponse(response) {
|
|
219
|
-
if (typeof response.access_token !== "string" ||
|
|
220
|
-
typeof response.refresh_token !== "string" ||
|
|
221
|
-
typeof response.expires_in !== "number") {
|
|
222
|
-
throw new Error("OAuth token response is incomplete");
|
|
223
|
-
}
|
|
224
|
-
return {
|
|
225
|
-
apiUrl: getApiUrl(),
|
|
226
|
-
accessToken: response.access_token,
|
|
227
|
-
refreshToken: response.refresh_token,
|
|
228
|
-
expiresAt: Date.now() + response.expires_in * 1000,
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
async function readCredentials(apiUrl) {
|
|
232
|
-
if (cachedCredentials?.apiUrl === apiUrl)
|
|
233
|
-
return cachedCredentials;
|
|
234
|
-
try {
|
|
235
|
-
const parsed = JSON.parse(await readFile(getOAuthCachePath(), "utf8"));
|
|
236
|
-
if (parsed.apiUrl !== apiUrl ||
|
|
237
|
-
typeof parsed.accessToken !== "string" ||
|
|
238
|
-
typeof parsed.refreshToken !== "string" ||
|
|
239
|
-
typeof parsed.expiresAt !== "number") {
|
|
240
|
-
return null;
|
|
241
|
-
}
|
|
242
|
-
return parsed;
|
|
243
|
-
}
|
|
244
|
-
catch {
|
|
245
|
-
return null;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
async function saveCredentials(apiUrl, credentials) {
|
|
249
|
-
cachedCredentials = { ...credentials, apiUrl };
|
|
250
|
-
const path = getOAuthCachePath();
|
|
251
|
-
await mkdir(dirname(path), { recursive: true, mode: 0o700 });
|
|
252
|
-
await writeFile(path, JSON.stringify(cachedCredentials), { encoding: "utf8", mode: 0o600 });
|
|
253
|
-
await chmod(path, 0o600);
|
|
254
|
-
}
|
|
255
|
-
async function removeCredentials() {
|
|
256
|
-
try {
|
|
257
|
-
await unlink(getOAuthCachePath());
|
|
258
|
-
}
|
|
259
|
-
catch {
|
|
260
|
-
/* Cache may not exist. */
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
function createCodeChallenge(verifier) {
|
|
264
|
-
return createHash("sha256").update(verifier).digest("base64url");
|
|
265
|
-
}
|
|
266
|
-
function addressPort(server) {
|
|
267
|
-
const address = server.address();
|
|
268
|
-
if (address === null || typeof address === "string") {
|
|
269
|
-
throw new Error("OAuth callback server did not receive a port");
|
|
270
|
-
}
|
|
271
|
-
return address.port;
|
|
272
|
-
}
|
|
273
|
-
function openBrowser(url) {
|
|
274
|
-
const command = process.platform === "darwin"
|
|
275
|
-
? "open"
|
|
276
|
-
: process.platform === "win32"
|
|
277
|
-
? "cmd"
|
|
278
|
-
: "xdg-open";
|
|
279
|
-
const args = process.platform === "win32" ? ["/c", "start", "", url] : [url];
|
|
280
|
-
const child = spawn(command, args, { detached: true, stdio: "ignore" });
|
|
281
|
-
child.once("error", () => {
|
|
282
|
-
console.error("Could not open a browser automatically. Open the URL printed above.");
|
|
283
|
-
});
|
|
284
|
-
child.unref();
|
|
285
|
-
}
|
package/dist/config.d.ts
DELETED
package/dist/config.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { homedir } from "node:os";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
export function getApiUrl() {
|
|
4
|
-
return (process.env.PLATFORM_API_URL?.trim().replace(/\/+$/, "") || "https://api.skaleagents.com");
|
|
5
|
-
}
|
|
6
|
-
export function getApiToken() {
|
|
7
|
-
return process.env.SKALEAGENTS_API_TOKEN?.trim() ?? "";
|
|
8
|
-
}
|
|
9
|
-
export function getOAuthCachePath() {
|
|
10
|
-
return (process.env.SKALEAGENTS_OAUTH_CACHE?.trim() ??
|
|
11
|
-
join(homedir(), ".config", "skaleagents", "oauth.json"));
|
|
12
|
-
}
|
|
13
|
-
export function isOAuthEnabled() {
|
|
14
|
-
return process.env.SKALEAGENTS_OAUTH_ENABLED !== "false";
|
|
15
|
-
}
|
package/dist/http.d.ts
DELETED
package/dist/http.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
2
|
-
import { createServer } from "./server.js";
|
|
3
|
-
import { getApiUrl } from "./config.js";
|
|
4
|
-
const resource = process.env.MCP_RESOURCE_URL ?? "https://skaleagents.com/mcp";
|
|
5
|
-
const metadataUrl = `${new URL(resource).origin}/.well-known/oauth-protected-resource/mcp`;
|
|
6
|
-
const allowedOrigins = new Set([
|
|
7
|
-
"https://claude.ai",
|
|
8
|
-
"https://chatgpt.com",
|
|
9
|
-
"https://platform.openai.com",
|
|
10
|
-
new URL(resource).origin,
|
|
11
|
-
]);
|
|
12
|
-
const headers = {
|
|
13
|
-
"Cache-Control": "no-store",
|
|
14
|
-
"Access-Control-Allow-Origin": "*",
|
|
15
|
-
"Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
|
|
16
|
-
"Access-Control-Allow-Headers": "Authorization, Content-Type, Accept, MCP-Protocol-Version, MCP-Session-Id, Last-Event-ID",
|
|
17
|
-
"Access-Control-Expose-Headers": "WWW-Authenticate, MCP-Session-Id, MCP-Protocol-Version",
|
|
18
|
-
};
|
|
19
|
-
function json(status, body, extraHeaders = {}) {
|
|
20
|
-
return Response.json(body, {
|
|
21
|
-
status,
|
|
22
|
-
headers: { ...headers, ...extraHeaders },
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
function challenge() {
|
|
26
|
-
return json(401, { error: "unauthorized" }, {
|
|
27
|
-
"WWW-Authenticate": `Bearer resource_metadata="${metadataUrl}", scope="mcp"`,
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
export function protectedResourceMetadata() {
|
|
31
|
-
return json(200, {
|
|
32
|
-
resource,
|
|
33
|
-
authorization_servers: [getApiUrl()],
|
|
34
|
-
scopes_supported: ["mcp"],
|
|
35
|
-
bearer_methods_supported: ["header"],
|
|
36
|
-
resource_documentation: "https://skaleagents.com/settings",
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
export async function handleMcpRequest(request) {
|
|
40
|
-
const origin = request.headers.get("origin");
|
|
41
|
-
if (origin && !allowedOrigins.has(origin))
|
|
42
|
-
return json(403, { error: "origin_not_allowed" });
|
|
43
|
-
if (request.method === "OPTIONS")
|
|
44
|
-
return new Response(null, { status: 204, headers });
|
|
45
|
-
const authorization = request.headers.get("authorization");
|
|
46
|
-
if (!authorization || !/^Bearer [^\s]+$/i.test(authorization))
|
|
47
|
-
return challenge();
|
|
48
|
-
try {
|
|
49
|
-
// Validate the opaque token with its issuer, including the MCP audience.
|
|
50
|
-
const validation = await fetch(`${getApiUrl()}/api/oauth/mcp-token`, {
|
|
51
|
-
headers: { Authorization: authorization, Accept: "application/json" },
|
|
52
|
-
signal: AbortSignal.timeout(10_000),
|
|
53
|
-
redirect: "error",
|
|
54
|
-
cache: "no-store",
|
|
55
|
-
});
|
|
56
|
-
if (validation.status === 401 || validation.status === 403)
|
|
57
|
-
return challenge();
|
|
58
|
-
if (!validation.ok)
|
|
59
|
-
return json(503, { error: "authorization_unavailable" });
|
|
60
|
-
const token = (await validation.json());
|
|
61
|
-
if (!token.active ||
|
|
62
|
-
token.resource !== resource ||
|
|
63
|
-
token.scope !== "mcp" ||
|
|
64
|
-
!token.expiresAt ||
|
|
65
|
-
token.expiresAt * 1000 <= Date.now()) {
|
|
66
|
-
return challenge();
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
return json(503, { error: "authorization_unavailable" });
|
|
71
|
-
}
|
|
72
|
-
if (request.method !== "POST")
|
|
73
|
-
return json(405, { error: "method_not_allowed" }, { Allow: "POST, OPTIONS" });
|
|
74
|
-
if (!request.headers.get("content-type")?.startsWith("application/json"))
|
|
75
|
-
return json(415, { error: "expected_json" });
|
|
76
|
-
let body;
|
|
77
|
-
try {
|
|
78
|
-
const reader = request.body?.getReader();
|
|
79
|
-
if (!reader)
|
|
80
|
-
return json(400, { error: "missing_body" });
|
|
81
|
-
const chunks = [];
|
|
82
|
-
let size = 0;
|
|
83
|
-
try {
|
|
84
|
-
for (;;) {
|
|
85
|
-
const { value, done } = await reader.read();
|
|
86
|
-
if (done)
|
|
87
|
-
break;
|
|
88
|
-
size += value.byteLength;
|
|
89
|
-
if (size > 2_100_000) {
|
|
90
|
-
await reader.cancel();
|
|
91
|
-
return json(413, { error: "request_too_large" });
|
|
92
|
-
}
|
|
93
|
-
chunks.push(value);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
finally {
|
|
97
|
-
reader.releaseLock();
|
|
98
|
-
}
|
|
99
|
-
body = JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
return json(400, {
|
|
103
|
-
jsonrpc: "2.0",
|
|
104
|
-
id: null,
|
|
105
|
-
error: { code: -32700, message: "Invalid JSON" },
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
const server = createServer(true);
|
|
109
|
-
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
110
|
-
sessionIdGenerator: undefined,
|
|
111
|
-
enableJsonResponse: true,
|
|
112
|
-
});
|
|
113
|
-
try {
|
|
114
|
-
await server.connect(transport);
|
|
115
|
-
const response = await transport.handleRequest(request, {
|
|
116
|
-
parsedBody: body,
|
|
117
|
-
});
|
|
118
|
-
// Finish the JSON response before closing this request-scoped transport.
|
|
119
|
-
const responseBody = await response.arrayBuffer();
|
|
120
|
-
const responseHeaders = new Headers(response.headers);
|
|
121
|
-
for (const [key, value] of Object.entries(headers))
|
|
122
|
-
responseHeaders.set(key, value);
|
|
123
|
-
return new Response(responseBody.byteLength ? responseBody : null, {
|
|
124
|
-
status: response.status,
|
|
125
|
-
headers: responseHeaders,
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
catch {
|
|
129
|
-
return json(500, { error: "mcp_request_failed" });
|
|
130
|
-
}
|
|
131
|
-
finally {
|
|
132
|
-
await server.close();
|
|
133
|
-
}
|
|
134
|
-
}
|
package/dist/iac/parse.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export type IacFormat = "terraform" | "cloudformation" | "kubernetes";
|
|
2
|
-
export type Path = (string | number)[];
|
|
3
|
-
export type Location = {
|
|
4
|
-
line: number;
|
|
5
|
-
column: number;
|
|
6
|
-
path: string;
|
|
7
|
-
};
|
|
8
|
-
export type Resource = {
|
|
9
|
-
id: string;
|
|
10
|
-
type: string;
|
|
11
|
-
value: Record<string, unknown>;
|
|
12
|
-
locate: (path?: Path) => Location;
|
|
13
|
-
};
|
|
14
|
-
export type ParsedIac = {
|
|
15
|
-
format: IacFormat;
|
|
16
|
-
resources: Resource[];
|
|
17
|
-
warnings: string[];
|
|
18
|
-
};
|
|
19
|
-
export declare class ScanInputError extends Error {
|
|
20
|
-
constructor(message: string);
|
|
21
|
-
}
|
|
22
|
-
export declare function object(value: unknown): Record<string, unknown>;
|
|
23
|
-
export declare function array(value: unknown): unknown[];
|
|
24
|
-
export declare function looksLikeIac(content: string): boolean;
|
|
25
|
-
export declare function parseIac(content: string, requested?: IacFormat | "auto"): ParsedIac;
|