@ampless/backend 1.0.0-beta.89 → 1.0.0-beta.91
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/dist/functions/mcp-handler.js +97 -26
- package/package.json +3 -3
|
@@ -1814,12 +1814,23 @@ var tools = [
|
|
|
1814
1814
|
}
|
|
1815
1815
|
];
|
|
1816
1816
|
|
|
1817
|
-
// ../mcp-server/dist/
|
|
1817
|
+
// ../mcp-server/dist/chunk-4REBPD2N.js
|
|
1818
1818
|
var JSON_RPC_PARSE_ERROR = -32700;
|
|
1819
1819
|
var JSON_RPC_INVALID_REQUEST = -32600;
|
|
1820
1820
|
var JSON_RPC_METHOD_NOT_FOUND = -32601;
|
|
1821
1821
|
var JSON_RPC_INVALID_PARAMS = -32602;
|
|
1822
1822
|
var JSON_RPC_INTERNAL_ERROR = -32603;
|
|
1823
|
+
var TOOL_USER_ERROR_BRAND = /* @__PURE__ */ Symbol.for("ampless.mcp.toolUserError");
|
|
1824
|
+
var ToolUserError = class extends Error {
|
|
1825
|
+
[TOOL_USER_ERROR_BRAND] = true;
|
|
1826
|
+
constructor(message) {
|
|
1827
|
+
super(message);
|
|
1828
|
+
this.name = "ToolUserError";
|
|
1829
|
+
}
|
|
1830
|
+
};
|
|
1831
|
+
function isToolUserError(error) {
|
|
1832
|
+
return error instanceof Error && error[TOOL_USER_ERROR_BRAND] === true;
|
|
1833
|
+
}
|
|
1823
1834
|
var SUPPORTED_PROTOCOL_VERSIONS = ["2025-03-26", "2024-11-05"];
|
|
1824
1835
|
var LATEST_SUPPORTED_PROTOCOL_VERSION = SUPPORTED_PROTOCOL_VERSIONS[0];
|
|
1825
1836
|
function jsonRpcResult(id, result) {
|
|
@@ -1841,6 +1852,69 @@ function hasValidJsonRpcId(req) {
|
|
|
1841
1852
|
function isPlainObject(v) {
|
|
1842
1853
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
1843
1854
|
}
|
|
1855
|
+
var MAX_BATCH = 50;
|
|
1856
|
+
function idForError(input) {
|
|
1857
|
+
if (isPlainObject(input) && hasValidJsonRpcId(input)) {
|
|
1858
|
+
return input.id ?? null;
|
|
1859
|
+
}
|
|
1860
|
+
return null;
|
|
1861
|
+
}
|
|
1862
|
+
function validateEnvelope(input, inBatch) {
|
|
1863
|
+
if (!isPlainObject(input)) {
|
|
1864
|
+
return { ok: false, error: jsonRpcError(null, JSON_RPC_INVALID_REQUEST, "Invalid Request") };
|
|
1865
|
+
}
|
|
1866
|
+
const jsonrpc = input.jsonrpc;
|
|
1867
|
+
const method = input.method;
|
|
1868
|
+
if (jsonrpc !== "2.0" || typeof method !== "string" || !hasValidJsonRpcId(input)) {
|
|
1869
|
+
return {
|
|
1870
|
+
ok: false,
|
|
1871
|
+
error: jsonRpcError(idForError(input), JSON_RPC_INVALID_REQUEST, "Invalid Request")
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
if (inBatch && method === "initialize") {
|
|
1875
|
+
return {
|
|
1876
|
+
ok: false,
|
|
1877
|
+
error: jsonRpcError(
|
|
1878
|
+
idForError(input),
|
|
1879
|
+
JSON_RPC_INVALID_REQUEST,
|
|
1880
|
+
"Invalid Request: `initialize` is not allowed in a batch"
|
|
1881
|
+
)
|
|
1882
|
+
};
|
|
1883
|
+
}
|
|
1884
|
+
return { ok: true, req: input };
|
|
1885
|
+
}
|
|
1886
|
+
async function dispatchJsonRpcMessage(input, opts) {
|
|
1887
|
+
const maxBatch = opts.maxBatch ?? MAX_BATCH;
|
|
1888
|
+
if (Array.isArray(input)) {
|
|
1889
|
+
if (input.length === 0 || input.length > maxBatch) {
|
|
1890
|
+
return {
|
|
1891
|
+
status: "invalid",
|
|
1892
|
+
body: jsonRpcError(
|
|
1893
|
+
null,
|
|
1894
|
+
JSON_RPC_INVALID_REQUEST,
|
|
1895
|
+
input.length === 0 ? "Invalid Request: empty batch" : `Invalid Request: batch exceeds the maximum of ${maxBatch} elements`
|
|
1896
|
+
)
|
|
1897
|
+
};
|
|
1898
|
+
}
|
|
1899
|
+
const responses = [];
|
|
1900
|
+
for (const element of input) {
|
|
1901
|
+
const validated2 = validateEnvelope(element, true);
|
|
1902
|
+
if (!validated2.ok) {
|
|
1903
|
+
responses.push(validated2.error);
|
|
1904
|
+
continue;
|
|
1905
|
+
}
|
|
1906
|
+
const res2 = await dispatchJsonRpc(validated2.req, opts);
|
|
1907
|
+
if (res2 !== null) responses.push(res2);
|
|
1908
|
+
}
|
|
1909
|
+
return responses.length === 0 ? { status: "no-content" } : { status: "ok", body: responses };
|
|
1910
|
+
}
|
|
1911
|
+
const validated = validateEnvelope(input, false);
|
|
1912
|
+
if (!validated.ok) {
|
|
1913
|
+
return { status: "invalid", body: validated.error };
|
|
1914
|
+
}
|
|
1915
|
+
const res = await dispatchJsonRpc(validated.req, opts);
|
|
1916
|
+
return res === null ? { status: "no-content" } : { status: "ok", body: res };
|
|
1917
|
+
}
|
|
1844
1918
|
function toolAnnotations(t) {
|
|
1845
1919
|
const annotations = {};
|
|
1846
1920
|
if (typeof t.readOnly === "boolean") annotations.readOnlyHint = t.readOnly;
|
|
@@ -1915,11 +1989,14 @@ async function dispatchMethod(req, opts) {
|
|
|
1915
1989
|
});
|
|
1916
1990
|
} catch (err2) {
|
|
1917
1991
|
const rawMessage = err2 instanceof Error ? err2.message : String(err2);
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1992
|
+
const userError = isToolUserError(err2);
|
|
1993
|
+
if (!userError) {
|
|
1994
|
+
console.error("[mcp-jsonrpc] tool dispatch failed", {
|
|
1995
|
+
tool: params.name,
|
|
1996
|
+
message: rawMessage
|
|
1997
|
+
});
|
|
1998
|
+
}
|
|
1999
|
+
const message = userError ? rawMessage : opts.formatToolError ? opts.formatToolError(err2) : rawMessage;
|
|
1923
2000
|
return jsonRpcResult(id, {
|
|
1924
2001
|
isError: true,
|
|
1925
2002
|
content: [{ type: "text", text: message }]
|
|
@@ -2140,43 +2217,37 @@ var handler = async (event) => {
|
|
|
2140
2217
|
return jsonResponse(401, { error: "invalid_token" });
|
|
2141
2218
|
}
|
|
2142
2219
|
await touchLastUsedAt(meta.hash);
|
|
2143
|
-
let
|
|
2220
|
+
let parsed;
|
|
2144
2221
|
try {
|
|
2145
2222
|
const body = event.isBase64Encoded ? Buffer.from(event.body ?? "", "base64").toString("utf8") : event.body ?? "";
|
|
2146
2223
|
if (!body) {
|
|
2147
2224
|
return jsonResponse(400, jsonRpcError(null, JSON_RPC_INVALID_REQUEST, "Empty body"));
|
|
2148
2225
|
}
|
|
2149
|
-
|
|
2226
|
+
parsed = JSON.parse(body);
|
|
2150
2227
|
} catch {
|
|
2151
2228
|
return jsonResponse(400, jsonRpcError(null, JSON_RPC_PARSE_ERROR, "Parse error"));
|
|
2152
2229
|
}
|
|
2153
|
-
if (typeof req !== "object" || req === null || Array.isArray(req)) {
|
|
2154
|
-
return jsonResponse(400, jsonRpcError(null, JSON_RPC_INVALID_REQUEST, "Invalid Request"));
|
|
2155
|
-
}
|
|
2156
|
-
if (req.jsonrpc !== "2.0" || typeof req.method !== "string" || !hasValidJsonRpcId(req)) {
|
|
2157
|
-
const responseId = hasValidJsonRpcId(req) ? req.id ?? null : null;
|
|
2158
|
-
return jsonResponse(
|
|
2159
|
-
400,
|
|
2160
|
-
jsonRpcError(responseId, JSON_RPC_INVALID_REQUEST, "Invalid Request")
|
|
2161
|
-
);
|
|
2162
|
-
}
|
|
2163
2230
|
try {
|
|
2164
|
-
const
|
|
2231
|
+
const result = await dispatchJsonRpcMessage(parsed, {
|
|
2165
2232
|
tools: HTTP_TOOLS,
|
|
2166
2233
|
getContext: makeContext,
|
|
2167
2234
|
serverInfo: { name: "ampless-mcp", version: "0.2" }
|
|
2168
2235
|
});
|
|
2169
|
-
if (
|
|
2236
|
+
if (result.status === "invalid") {
|
|
2237
|
+
return jsonResponse(400, result.body);
|
|
2238
|
+
}
|
|
2239
|
+
if (result.status === "no-content") {
|
|
2170
2240
|
return { statusCode: 202, body: "" };
|
|
2171
2241
|
}
|
|
2172
|
-
return jsonResponse(200,
|
|
2242
|
+
return jsonResponse(200, result.body);
|
|
2173
2243
|
} catch (err2) {
|
|
2244
|
+
const method = typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed.method : void 0;
|
|
2174
2245
|
const message = err2 instanceof Error ? err2.message : String(err2);
|
|
2175
|
-
console.error("[mcp-handler] dispatch threw", {
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
);
|
|
2246
|
+
console.error("[mcp-handler] dispatch threw", {
|
|
2247
|
+
method: typeof method === "string" ? method : void 0,
|
|
2248
|
+
message
|
|
2249
|
+
});
|
|
2250
|
+
return jsonResponse(500, jsonRpcError(null, JSON_RPC_INTERNAL_ERROR, message));
|
|
2180
2251
|
}
|
|
2181
2252
|
};
|
|
2182
2253
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ampless/backend",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.91",
|
|
4
4
|
"description": "Amplify Gen 2 backend factories for ampless: auth, data, storage, event processors, API key renewer",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
"@smithy/protocol-http": "^5.4.4",
|
|
70
70
|
"@smithy/signature-v4": "^5.4.4",
|
|
71
71
|
"fflate": "^0.8.3",
|
|
72
|
-
"@ampless/mcp-server": "1.0.0-beta.
|
|
73
|
-
"ampless": "1.0.0-beta.
|
|
72
|
+
"@ampless/mcp-server": "1.0.0-beta.68",
|
|
73
|
+
"ampless": "1.0.0-beta.61"
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
76
|
"@aws-amplify/backend": "^1.19.0",
|