@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.
@@ -1814,12 +1814,23 @@ var tools = [
1814
1814
  }
1815
1815
  ];
1816
1816
 
1817
- // ../mcp-server/dist/jsonrpc/index.js
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
- console.error("[mcp-jsonrpc] tool dispatch failed", {
1919
- tool: params.name,
1920
- message: rawMessage
1921
- });
1922
- const message = opts.formatToolError ? opts.formatToolError(err2) : rawMessage;
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 req;
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
- req = JSON.parse(body);
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 response = await dispatchJsonRpc(req, {
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 (response === null) {
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, response);
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", { method: req.method, message });
2176
- return jsonResponse(
2177
- 500,
2178
- jsonRpcError(req.id ?? null, JSON_RPC_INTERNAL_ERROR, message)
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.89",
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.66",
73
- "ampless": "1.0.0-beta.59"
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",