horizon-mcp 1.5.3 → 1.5.5

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.
Files changed (55) hide show
  1. package/README.md +5 -1
  2. package/dist/tools/__tests__/api-client.test.js +16 -0
  3. package/dist/tools/__tests__/api-client.test.js.map +1 -1
  4. package/dist/tools/__tests__/leaderboard.test.js +6 -3
  5. package/dist/tools/__tests__/leaderboard.test.js.map +1 -1
  6. package/dist/tools/__tests__/tool-metadata.test.d.ts +2 -0
  7. package/dist/tools/__tests__/tool-metadata.test.d.ts.map +1 -0
  8. package/dist/tools/__tests__/tool-metadata.test.js +34 -0
  9. package/dist/tools/__tests__/tool-metadata.test.js.map +1 -0
  10. package/dist/tools/api-client.d.ts +6 -1
  11. package/dist/tools/api-client.d.ts.map +1 -1
  12. package/dist/tools/api-client.js +30 -7
  13. package/dist/tools/api-client.js.map +1 -1
  14. package/dist/tools/auth.d.ts.map +1 -1
  15. package/dist/tools/auth.js +36 -9
  16. package/dist/tools/auth.js.map +1 -1
  17. package/dist/tools/cloud-save.d.ts.map +1 -1
  18. package/dist/tools/cloud-save.js +28 -11
  19. package/dist/tools/cloud-save.js.map +1 -1
  20. package/dist/tools/connection.d.ts.map +1 -1
  21. package/dist/tools/connection.js +6 -2
  22. package/dist/tools/connection.js.map +1 -1
  23. package/dist/tools/crash-reporting.d.ts.map +1 -1
  24. package/dist/tools/crash-reporting.js +12 -3
  25. package/dist/tools/crash-reporting.js.map +1 -1
  26. package/dist/tools/email-sending.d.ts.map +1 -1
  27. package/dist/tools/email-sending.js +21 -4
  28. package/dist/tools/email-sending.js.map +1 -1
  29. package/dist/tools/feedback.d.ts.map +1 -1
  30. package/dist/tools/feedback.js +8 -4
  31. package/dist/tools/feedback.js.map +1 -1
  32. package/dist/tools/gift-codes.d.ts.map +1 -1
  33. package/dist/tools/gift-codes.js +14 -5
  34. package/dist/tools/gift-codes.js.map +1 -1
  35. package/dist/tools/leaderboard.d.ts.map +1 -1
  36. package/dist/tools/leaderboard.js +44 -14
  37. package/dist/tools/leaderboard.js.map +1 -1
  38. package/dist/tools/localization.d.ts.map +1 -1
  39. package/dist/tools/localization.js +17 -5
  40. package/dist/tools/localization.js.map +1 -1
  41. package/dist/tools/news.d.ts.map +1 -1
  42. package/dist/tools/news.js +7 -2
  43. package/dist/tools/news.js.map +1 -1
  44. package/dist/tools/remote-config.d.ts.map +1 -1
  45. package/dist/tools/remote-config.js +12 -4
  46. package/dist/tools/remote-config.js.map +1 -1
  47. package/dist/tools/tool-helpers.d.ts +18 -0
  48. package/dist/tools/tool-helpers.d.ts.map +1 -1
  49. package/dist/tools/tool-helpers.js +16 -0
  50. package/dist/tools/tool-helpers.js.map +1 -1
  51. package/dist/tools/user-logs.d.ts.map +1 -1
  52. package/dist/tools/user-logs.js +8 -3
  53. package/dist/tools/user-logs.js.map +1 -1
  54. package/package.json +2 -1
  55. package/src/resources/api/app-api.md +14 -11
package/README.md CHANGED
@@ -4,7 +4,9 @@
4
4
  [![npm downloads](https://img.shields.io/npm/dm/horizon-mcp)](https://www.npmjs.com/package/horizon-mcp)
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
6
 
7
- **MCP server for horizOn Backend-as-a-Service** -- gives AI coding assistants documentation, live API tools, and workflow prompts for game and app development.
7
+ **MCP server for horizOn Backend-as-a-Service**
8
+
9
+ Gives AI coding assistants documentation, live API tools, and workflow prompts for game and app development.
8
10
 
9
11
  ---
10
12
 
@@ -55,6 +57,8 @@ Documentation resources are served directly from the MCP server. No API key requ
55
57
 
56
58
  Live API tools that call the horizOn backend. Requires a valid API key.
57
59
 
60
+ `horizon_submit_score`, `horizon_save_cloud_data` and `horizon_load_cloud_data` also need the player's session: sign in first and pass the returned `accessToken` as `sessionToken`.
61
+
58
62
  | Tool | Description |
59
63
  |------|-------------|
60
64
  | `horizon_test_connection` | Test connection to the horizOn API (health check) |
@@ -36,6 +36,22 @@ describe("HorizonApiClient", () => {
36
36
  expect(options.headers["X-API-Key"]).toBe("test-key");
37
37
  expect(options.headers["Content-Type"]).toBe("application/json");
38
38
  });
39
+ it("returns null for an empty body and plain text as a string", async () => {
40
+ const client = new HorizonApiClient("test-key", "https://example.com");
41
+ vi.stubGlobal("fetch", mockFetchResponse(""));
42
+ await expect(client.post("/api/v1/test")).resolves.toBeNull();
43
+ vi.stubGlobal("fetch", mockFetchResponse("ok"));
44
+ await expect(client.post("/api/v1/test")).resolves.toBe("ok");
45
+ });
46
+ it("POST merges extra headers such as a session", async () => {
47
+ const fakeFetch = mockFetchResponse({ ok: true });
48
+ vi.stubGlobal("fetch", fakeFetch);
49
+ const client = new HorizonApiClient("test-key", "https://example.com");
50
+ await client.post("/api/v1/test", { a: 1 }, { Authorization: "Bearer s" });
51
+ const [, options] = fakeFetch.mock.calls[0];
52
+ expect(options.headers["X-API-Key"]).toBe("test-key");
53
+ expect(options.headers.Authorization).toBe("Bearer s");
54
+ });
39
55
  it("GET appends query params", async () => {
40
56
  const fakeFetch = mockFetchResponse({ items: [] });
41
57
  vi.stubGlobal("fetch", fakeFetch);
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/api-client.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAE1B,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,iBAAiB,CACxB,IAAa,EACb,IAAwC;IAExC,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,GAAG,CAAC;IACnC,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,IAAI,CAAC,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,CAAC,CAAC;IAEvD,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;QAC/B,EAAE;QACF,MAAM;QACN,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;QACtB,IAAI,EAAE,KAAK,IAAI,EAAE,CACf,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAClC,CAAC,CAAC;AAC5B,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC;IAEvC,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,KAAK,GAAG,aAAa,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,gBAAgB,CAAC,EAAE,EAAE,qBAAqB,CAAC,CAAC,CAAC,OAAO,CACnE,2BAA2B,CAC5B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,SAAS,GAAG,iBAAiB,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;QACvE,MAAM,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAEjC,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QACpD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QACxC,MAAM,SAAS,GAAG,iBAAiB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QACnD,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;QAClE,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAEhE,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,SAAS,GAAG,iBAAiB,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACnD,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,QAAQ,EAAE,qBAAqB,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC5C,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAE7C,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;QACtD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACjE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,SAAS,GAAG,iBAAiB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;QAClE,MAAM,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAEpC,MAAM,CAAC,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,SAAS,GAAG,iBAAiB,CAAC,WAAW,EAAE;YAC/C,MAAM,EAAE,GAAG;YACX,EAAE,EAAE,KAAK;SACV,CAAC,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;QAElE,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CACzD,eAAe,CAChB,CAAC;QACF,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC;YAChE,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,WAAW;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,SAAS,GAAG,iBAAiB,CAAC,aAAa,EAAE;YACjD,MAAM,EAAE,GAAG;YACX,EAAE,EAAE,KAAK;SACV,CAAC,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;QAElE,MAAM,MAAM,CACV,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAC7C,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACnC,MAAM,MAAM,CACV,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAC7C,CAAC,OAAO,CAAC,aAAa,CAAC;YACtB,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,aAAa;SACpB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE;QACtC,MAAM,SAAS,GAAG,EAAE;aACjB,EAAE,EAAE;aACJ,iBAAiB,CAAC,IAAI,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC;QACpD,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;QAElE,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACzE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,SAAS,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACxC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC;QACnE,MAAM,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAEjC,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,MAAM,WAAW,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAEvC,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;QACnC,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,GAAG,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,sBAAsB,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,UAAU,CAAC;QACzC,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,UAAU,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,4BAA4B,CAAC;QAE5D,MAAM,SAAS,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACxC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,sBAAsB,EAAG,CAAC;QACzC,MAAM,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE1B,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAEpD,UAAU,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,0CAA0C;IACjF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,UAAU,CAAC;QAEzC,MAAM,SAAS,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACxC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAElC,MAAM,MAAM,GAAG,sBAAsB,EAAG,CAAC;QACzC,MAAM,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAE1B,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"api-client.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/api-client.test.ts"],"names":[],"mappings":"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"}
@@ -44,19 +44,22 @@ describe("registerLeaderboardTools", () => {
44
44
  it("submits scores to a named board", async () => {
45
45
  const server = createMockServer();
46
46
  registerLeaderboardTools(server);
47
- const mockPost = vi.fn().mockResolvedValue({ success: true });
47
+ // The API answers with an empty body, which the client turns into null
48
+ const mockPost = vi.fn().mockResolvedValue(null);
48
49
  mockedCreateApiClient.mockReturnValue({ post: mockPost });
49
50
  const { handler } = registeredTools.get("horizon_submit_score");
50
- await handler({
51
+ const result = await handler({
51
52
  userId: "550e8400-e29b-41d4-a716-446655440000",
52
53
  score: 1200,
53
54
  leaderboardKey: "weekly_speed",
55
+ sessionToken: "session-123",
54
56
  });
55
57
  expect(mockPost).toHaveBeenCalledWith("/api/v1/app/leaderboards/weekly_speed/submit", {
56
58
  userId: "550e8400-e29b-41d4-a716-446655440000",
57
59
  score: 1200,
58
60
  leaderboardKey: "weekly_speed",
59
- });
61
+ }, { Authorization: "Bearer session-123" });
62
+ expect(JSON.parse(result.content[0].text)).toEqual({ success: true });
60
63
  });
61
64
  it("gets top scores from a named board", async () => {
62
65
  const server = createMockServer();
@@ -1 +1 @@
1
- {"version":3,"file":"leaderboard.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/leaderboard.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"leaderboard.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/leaderboard.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE;IACnD,MAAM,MAAM,GAAG,MAAM,cAAc,EAAqC,CAAC;IACzE,OAAO;QACL,GAAG,MAAM;QACT,sBAAsB,EAAE,EAAE,CAAC,EAAE,EAAE;KAChC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,qBAAqB,GAAG,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAChE,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkD,CAAC;AAElF,SAAS,gBAAgB;IACvB,OAAO;QACL,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,MAAe,EAAE,OAAiB,EAAE,EAAE;YACvE,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC;KACqB,CAAC;AAC5B,CAAC;AAED,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,SAAS,CAAC,GAAG,EAAE;QACb,eAAe,CAAC,KAAK,EAAE,CAAC;QACxB,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAEjC,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/D,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtE,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzE,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAEjC,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC;QAC5E,qBAAqB,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,OAAO,EAAS,CAAC,CAAC;QAE/D,MAAM,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,2BAA2B,CAAE,CAAC;QACtE,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;QAElB,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,0BAA0B,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAEjC,uEAAuE;QACvE,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACjD,qBAAqB,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAS,CAAC,CAAC;QAEjE,MAAM,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,sBAAsB,CAAE,CAAC;QACjE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;YAC3B,MAAM,EAAE,sCAAsC;YAC9C,KAAK,EAAE,IAAI;YACX,cAAc,EAAE,cAAc;YAC9B,YAAY,EAAE,aAAa;SAC5B,CAAC,CAAC;QAEH,MAAM,CAAC,QAAQ,CAAC,CAAC,oBAAoB,CACnC,8CAA8C,EAC9C;YACE,MAAM,EAAE,sCAAsC;YAC9C,KAAK,EAAE,IAAI;YACX,cAAc,EAAE,cAAc;SAC/B,EACD,EAAE,aAAa,EAAE,oBAAoB,EAAE,CACxC,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;QAClC,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAEjC,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3D,qBAAqB,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,OAAO,EAAS,CAAC,CAAC;QAE/D,MAAM,EAAE,OAAO,EAAE,GAAG,eAAe,CAAC,GAAG,CAAC,6BAA6B,CAAE,CAAC;QACxE,MAAM,OAAO,CAAC;YACZ,MAAM,EAAE,sCAAsC;YAC9C,KAAK,EAAE,CAAC;YACR,cAAc,EAAE,OAAO;SACxB,CAAC,CAAC;QAEH,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAClC,oCAAoC,EACpC;YACE,MAAM,EAAE,sCAAsC;YAC9C,KAAK,EAAE,GAAG;SACX,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tool-metadata.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-metadata.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/tool-metadata.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ import { describe, it, expect, vi, afterEach } from "vitest";
2
+ import { registerAllTools } from "../index.js";
3
+ import { errorResponse, noApiKeyResponse, API_ERRORS } from "../tool-helpers.js";
4
+ const registeredTools = new Map();
5
+ function createMockServer() {
6
+ return {
7
+ registerTool: vi.fn((name, config) => {
8
+ registeredTools.set(name, config);
9
+ }),
10
+ registerPrompt: vi.fn(),
11
+ registerResource: vi.fn(),
12
+ };
13
+ }
14
+ describe("player tool metadata", () => {
15
+ afterEach(() => {
16
+ registeredTools.clear();
17
+ vi.unstubAllEnvs();
18
+ });
19
+ it("gives every player tool annotations and the API error note", () => {
20
+ vi.stubEnv("HORIZON_ACCOUNT_API_KEY", "");
21
+ registerAllTools(createMockServer());
22
+ expect(registeredTools.size).toBe(28);
23
+ for (const [name, config] of registeredTools) {
24
+ expect(config.annotations, name).toBeDefined();
25
+ expect(config.annotations?.openWorldHint, name).toBe(true);
26
+ expect(config.description, name).toContain(API_ERRORS);
27
+ }
28
+ });
29
+ it("marks error results as errors", () => {
30
+ expect(noApiKeyResponse().isError).toBe(true);
31
+ expect(errorResponse(new Error("boom")).isError).toBe(true);
32
+ });
33
+ });
34
+ //# sourceMappingURL=tool-metadata.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-metadata.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/tool-metadata.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAOjF,MAAM,eAAe,GAAG,IAAI,GAAG,EAAsB,CAAC;AAEtD,SAAS,gBAAgB;IACvB,OAAO;QACL,YAAY,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,MAAkB,EAAE,EAAE;YACvD,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACpC,CAAC,CAAC;QACF,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE;QACvB,gBAAgB,EAAE,EAAE,CAAC,EAAE,EAAE;KACF,CAAC;AAC5B,CAAC;AAED,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,SAAS,CAAC,GAAG,EAAE;QACb,eAAe,CAAC,KAAK,EAAE,CAAC;QACxB,EAAE,CAAC,aAAa,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,EAAE,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;QAC1C,gBAAgB,CAAC,gBAAgB,EAAE,CAAC,CAAC;QAErC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3D,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACzD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,CAAC,gBAAgB,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -12,6 +12,11 @@ export declare class HorizonApiError extends Error {
12
12
  readonly body: string;
13
13
  constructor(status: number, body: string);
14
14
  }
15
+ /**
16
+ * Authorization header for endpoints that need a player session
17
+ * (leaderboard submit, cloud save). The token is the accessToken from sign-in.
18
+ */
19
+ export declare function sessionHeaders(sessionToken: string): Record<string, string>;
15
20
  export declare class HorizonApiClient {
16
21
  private readonly apiKey;
17
22
  private readonly baseUrl;
@@ -19,7 +24,7 @@ export declare class HorizonApiClient {
19
24
  constructor(apiKey: string, baseUrl: string, headerName?: string);
20
25
  private authHeaders;
21
26
  get<T>(path: string, params?: Record<string, string>): Promise<T>;
22
- post<T>(path: string, body?: unknown): Promise<T>;
27
+ post<T>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
23
28
  put<T>(path: string, body?: unknown): Promise<T>;
24
29
  patch<T>(path: string, body?: unknown): Promise<T>;
25
30
  delete<T>(path: string, body?: unknown): Promise<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/tools/api-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,qBAAa,eAAgB,SAAQ,KAAK;aAEtB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;gBADZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM;CAK/B;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAE,MAAoB;IAU7E,OAAO,CAAC,WAAW;IAOb,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAsBjE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAejD,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAehD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAelD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;CAc1D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,GAAG,IAAI,CAOhE"}
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/tools/api-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,qBAAa,eAAgB,SAAQ,KAAK;aAEtB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;gBADZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM;CAK/B;AAiBD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE3E;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAE,MAAoB;IAU7E,OAAO,CAAC,WAAW;IAOb,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAsBjE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAenF,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAehD,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAelD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;CAc1D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,GAAG,IAAI,CAOhE"}
@@ -17,6 +17,29 @@ export class HorizonApiError extends Error {
17
17
  this.name = "HorizonApiError";
18
18
  }
19
19
  }
20
+ /**
21
+ * Reads a response body as JSON. Some endpoints answer with an empty body
22
+ * (leaderboard submit) or plain text (feedback submit), so an empty body
23
+ * becomes null and non-JSON text is returned as a string.
24
+ */
25
+ async function parseBody(response) {
26
+ const text = await response.text();
27
+ if (!text)
28
+ return null;
29
+ try {
30
+ return JSON.parse(text);
31
+ }
32
+ catch {
33
+ return text;
34
+ }
35
+ }
36
+ /**
37
+ * Authorization header for endpoints that need a player session
38
+ * (leaderboard submit, cloud save). The token is the accessToken from sign-in.
39
+ */
40
+ export function sessionHeaders(sessionToken) {
41
+ return { Authorization: `Bearer ${sessionToken}` };
42
+ }
20
43
  export class HorizonApiClient {
21
44
  apiKey;
22
45
  baseUrl;
@@ -52,19 +75,19 @@ export class HorizonApiClient {
52
75
  const body = await response.text();
53
76
  throw new HorizonApiError(response.status, body);
54
77
  }
55
- return (await response.json());
78
+ return parseBody(response);
56
79
  }
57
- async post(path, body) {
80
+ async post(path, body, headers) {
58
81
  const response = await fetch(`${this.baseUrl}${path}`, {
59
82
  method: "POST",
60
- headers: this.authHeaders(),
83
+ headers: { ...this.authHeaders(), ...headers },
61
84
  body: body !== undefined ? JSON.stringify(body) : undefined,
62
85
  });
63
86
  if (!response.ok) {
64
87
  const responseBody = await response.text();
65
88
  throw new HorizonApiError(response.status, responseBody);
66
89
  }
67
- return (await response.json());
90
+ return parseBody(response);
68
91
  }
69
92
  async put(path, body) {
70
93
  const response = await fetch(`${this.baseUrl}${path}`, {
@@ -76,7 +99,7 @@ export class HorizonApiClient {
76
99
  const responseBody = await response.text();
77
100
  throw new HorizonApiError(response.status, responseBody);
78
101
  }
79
- return (await response.json());
102
+ return parseBody(response);
80
103
  }
81
104
  async patch(path, body) {
82
105
  const response = await fetch(`${this.baseUrl}${path}`, {
@@ -88,7 +111,7 @@ export class HorizonApiClient {
88
111
  const responseBody = await response.text();
89
112
  throw new HorizonApiError(response.status, responseBody);
90
113
  }
91
- return (await response.json());
114
+ return parseBody(response);
92
115
  }
93
116
  async delete(path, body) {
94
117
  const response = await fetch(`${this.baseUrl}${path}`, {
@@ -100,7 +123,7 @@ export class HorizonApiClient {
100
123
  const responseBody = await response.text();
101
124
  throw new HorizonApiError(response.status, responseBody);
102
125
  }
103
- return (await response.json());
126
+ return parseBody(response);
104
127
  }
105
128
  }
106
129
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/tools/api-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/tools/api-client.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0HzD"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqJzD"}
@@ -1,14 +1,19 @@
1
1
  import { z } from "zod/v4";
2
2
  import { createApiClientFromEnv } from "./api-client.js";
3
- import { noApiKeyResponse, errorResponse, jsonResponse } from "./tool-helpers.js";
3
+ import { noApiKeyResponse, errorResponse, jsonResponse, ADDITIVE_WRITE, API_ERRORS } from "./tool-helpers.js";
4
4
  export function registerAuthTools(server) {
5
5
  // --- Sign up anonymously ---
6
6
  server.registerTool("horizon_signup_anonymous", {
7
7
  title: "Sign Up Anonymously",
8
- description: "Creates a new anonymous user account on horizOn with a display name.",
8
+ description: "Creates a guest account with only a display name, for players without email. For accounts with email and password, use horizon_signup_email. " +
9
+ "The server generates an anonymousToken and returns it with the new user as {userId, username, isAnonymous, anonymousToken, createdAt}. " +
10
+ "Keep the anonymousToken: it is the only way back into this account with horizon_signin_anonymous. " +
11
+ "Sign-up starts no session, so call horizon_signin_anonymous before tools that need one. Each call creates another account. " +
12
+ API_ERRORS,
9
13
  inputSchema: {
10
14
  displayName: z.string().max(30).describe("Display name for the anonymous user (max 30 characters)"),
11
15
  },
16
+ annotations: ADDITIVE_WRITE,
12
17
  }, async ({ displayName }) => {
13
18
  const client = createApiClientFromEnv();
14
19
  if (!client)
@@ -27,12 +32,16 @@ export function registerAuthTools(server) {
27
32
  // --- Sign up with email ---
28
33
  server.registerTool("horizon_signup_email", {
29
34
  title: "Sign Up with Email",
30
- description: "Creates a new user account on horizOn with email and password.",
35
+ description: "Creates an account with email, password and display name. Use horizon_signin_email for existing accounts and horizon_signup_anonymous for guests. " +
36
+ "The new account starts unverified and sign-up starts no session: horizon_signin_email returns 403 (NOT_VERIFIED) until the email address is verified. " +
37
+ "Returns the new user with userId and isVerified false. An email that is already registered gives 409. " +
38
+ API_ERRORS,
31
39
  inputSchema: {
32
40
  email: z.string().email().max(40).describe("Email address (max 40 characters)"),
33
41
  password: z.string().min(4).max(32).describe("Password (4-32 characters)"),
34
42
  displayName: z.string().max(30).describe("Display name (max 30 characters)"),
35
43
  },
44
+ annotations: ADDITIVE_WRITE,
36
45
  }, async ({ email, password, displayName }) => {
37
46
  const client = createApiClientFromEnv();
38
47
  if (!client)
@@ -53,11 +62,16 @@ export function registerAuthTools(server) {
53
62
  // --- Sign in with email ---
54
63
  server.registerTool("horizon_signin_email", {
55
64
  title: "Sign In with Email",
56
- description: "Signs in an existing user on horizOn using email and password.",
65
+ description: "Signs in an existing email account and starts a session. Use horizon_signup_email to create one and horizon_signin_anonymous for guest accounts. " +
66
+ "Returns {userId, username, email, accessToken, authStatus, message}. Pass accessToken as sessionToken to horizon_submit_score, " +
67
+ "horizon_save_cloud_data, horizon_load_cloud_data and horizon_check_auth; it stays valid for one hour after its last use. " +
68
+ "A wrong password or unknown email gives 401, an unverified email 403. Signing in again does not end older sessions. " +
69
+ API_ERRORS,
57
70
  inputSchema: {
58
71
  email: z.string().email().describe("Email address"),
59
72
  password: z.string().describe("Password"),
60
73
  },
74
+ annotations: ADDITIVE_WRITE,
61
75
  }, async ({ email, password }) => {
62
76
  const client = createApiClientFromEnv();
63
77
  if (!client)
@@ -77,10 +91,14 @@ export function registerAuthTools(server) {
77
91
  // --- Sign in anonymously ---
78
92
  server.registerTool("horizon_signin_anonymous", {
79
93
  title: "Sign In Anonymously",
80
- description: "Signs in an anonymous user on horizOn using their anonymous token.",
94
+ description: "Signs in a guest account with the anonymousToken returned by horizon_signup_anonymous and starts a session. Use horizon_signin_email for email accounts. " +
95
+ "Returns {userId, username, accessToken, authStatus, message}; pass accessToken as sessionToken to the tools that need a session. " +
96
+ "An unknown token gives 404. Besides the account rate limit, anonymous sign-in allows 5 attempts per token and 30 per IP address per minute. " +
97
+ API_ERRORS,
81
98
  inputSchema: {
82
- anonymousToken: z.string().max(32).describe("Anonymous token (max 32 characters)"),
99
+ anonymousToken: z.string().max(32).describe("anonymousToken returned by horizon_signup_anonymous (max 32 characters)"),
83
100
  },
101
+ annotations: ADDITIVE_WRITE,
84
102
  }, async ({ anonymousToken }) => {
85
103
  const client = createApiClientFromEnv();
86
104
  if (!client)
@@ -99,10 +117,19 @@ export function registerAuthTools(server) {
99
117
  // --- Check auth ---
100
118
  server.registerTool("horizon_check_auth", {
101
119
  title: "Check Authentication",
102
- description: "Checks whether a user session is still valid on horizOn.",
120
+ description: "Checks whether a session token from horizon_signin_email or horizon_signin_anonymous is still valid for this user, for example before a call that needs a session. " +
121
+ "Returns {userId, isAuthenticated, authStatus, message}. An invalid or expired token is not an HTTP error: isAuthenticated is false and the player has to sign in again. " +
122
+ "A successful check can extend the session's lifetime. To test the API key itself, use horizon_test_connection. " +
123
+ API_ERRORS,
103
124
  inputSchema: {
104
- userId: z.string().uuid().describe("User ID (UUID)"),
105
- sessionToken: z.string().max(256).describe("Session token (max 256 characters)"),
125
+ userId: z.string().uuid().describe("User ID (UUID) returned by a horizon_signup_* or horizon_signin_* tool"),
126
+ sessionToken: z.string().max(256).describe("accessToken returned by a horizon_signin_* tool (max 256 characters)"),
127
+ },
128
+ annotations: {
129
+ readOnlyHint: false,
130
+ destructiveHint: false,
131
+ idempotentHint: true,
132
+ openWorldHint: true,
106
133
  },
107
134
  }, async ({ userId, sessionToken }) => {
108
135
  const client = createApiClientFromEnv();
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-save.d.ts","sourceRoot":"","sources":["../../src/tools/cloud-save.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8C9D"}
1
+ {"version":3,"file":"cloud-save.d.ts","sourceRoot":"","sources":["../../src/tools/cloud-save.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+D9D"}
@@ -1,16 +1,28 @@
1
1
  import { z } from "zod/v4";
2
- import { createApiClientFromEnv } from "./api-client.js";
3
- import { noApiKeyResponse, errorResponse, jsonResponse } from "./tool-helpers.js";
2
+ import { createApiClientFromEnv, sessionHeaders } from "./api-client.js";
3
+ import { noApiKeyResponse, errorResponse, jsonResponse, READ_ONLY, API_ERRORS } from "./tool-helpers.js";
4
4
  export function registerCloudSaveTools(server) {
5
5
  // --- Save cloud data ---
6
6
  server.registerTool("horizon_save_cloud_data", {
7
7
  title: "Save Cloud Data",
8
- description: "Saves cloud data for a user on horizOn. Data is a string (max 300,000 characters).",
8
+ description: "Stores a player's save game as a string, usually JSON, and replaces any earlier save of that player. " +
9
+ "Needs the player's session: pass the accessToken from horizon_signin_email or horizon_signin_anonymous. " +
10
+ "Read it back with horizon_load_cloud_data. The allowed size depends on the account tier, by default " +
11
+ "FREE 1 KB, BASIC 5 KB, PRO 20 KB and ENTERPRISE 250 KB; a larger save fails with HTTP 403. " +
12
+ "Returns {success: true, dataSizeBytes}. " +
13
+ API_ERRORS,
9
14
  inputSchema: {
10
- userId: z.string().uuid().describe("User ID (UUID)"),
11
- data: z.string().max(300000).describe("Save data string (max 300,000 characters)"),
15
+ userId: z.string().uuid().describe("User ID (UUID) returned by a horizon_signup_* or horizon_signin_* tool"),
16
+ data: z.string().max(300000).describe("Save data string, usually serialized JSON (max 300,000 characters; the tier limit is usually lower)"),
17
+ sessionToken: z.string().min(1).max(256).describe("accessToken returned by horizon_signin_email or horizon_signin_anonymous for this user; sent as a Bearer session"),
12
18
  },
13
- }, async ({ userId, data }) => {
19
+ annotations: {
20
+ readOnlyHint: false,
21
+ destructiveHint: true,
22
+ idempotentHint: true,
23
+ openWorldHint: true,
24
+ },
25
+ }, async ({ userId, data, sessionToken }) => {
14
26
  const client = createApiClientFromEnv();
15
27
  if (!client)
16
28
  return noApiKeyResponse();
@@ -18,7 +30,7 @@ export function registerCloudSaveTools(server) {
18
30
  const result = await client.post("/api/v1/app/cloud-save/save", {
19
31
  userId,
20
32
  saveData: data,
21
- });
33
+ }, sessionHeaders(sessionToken));
22
34
  return jsonResponse(result);
23
35
  }
24
36
  catch (error) {
@@ -28,18 +40,23 @@ export function registerCloudSaveTools(server) {
28
40
  // --- Load cloud data ---
29
41
  server.registerTool("horizon_load_cloud_data", {
30
42
  title: "Load Cloud Data",
31
- description: "Loads cloud save data for a user from horizOn.",
43
+ description: "Reads a player's save game that was stored with horizon_save_cloud_data. " +
44
+ "Needs the player's session: pass the accessToken from horizon_signin_email or horizon_signin_anonymous. " +
45
+ "Returns {found, saveData}. A player who never saved gets found false and saveData null, which is normal on first start: initialize default data then. " +
46
+ API_ERRORS,
32
47
  inputSchema: {
33
- userId: z.string().uuid().describe("User ID (UUID)"),
48
+ userId: z.string().uuid().describe("User ID (UUID) returned by a horizon_signup_* or horizon_signin_* tool"),
49
+ sessionToken: z.string().min(1).max(256).describe("accessToken returned by horizon_signin_email or horizon_signin_anonymous for this user; sent as a Bearer session"),
34
50
  },
35
- }, async ({ userId }) => {
51
+ annotations: READ_ONLY,
52
+ }, async ({ userId, sessionToken }) => {
36
53
  const client = createApiClientFromEnv();
37
54
  if (!client)
38
55
  return noApiKeyResponse();
39
56
  try {
40
57
  const result = await client.post("/api/v1/app/cloud-save/load", {
41
58
  userId,
42
- });
59
+ }, sessionHeaders(sessionToken));
43
60
  return jsonResponse(result);
44
61
  }
45
62
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-save.js","sourceRoot":"","sources":["../../src/tools/cloud-save.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAElF,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,0BAA0B;IAC1B,MAAM,CAAC,YAAY,CAAC,yBAAyB,EAAE;QAC7C,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,oFAAoF;QACtF,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YACpD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,2CAA2C,CAAC;SACnF;KACF,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM;YAAE,OAAO,gBAAgB,EAAE,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;gBAC9D,MAAM;gBACN,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,0BAA0B;IAC1B,MAAM,CAAC,YAAY,CAAC,yBAAyB,EAAE;QAC7C,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,gDAAgD;QAClD,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;SACrD;KACF,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACtB,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM;YAAE,OAAO,gBAAgB,EAAE,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;gBAC9D,MAAM;aACP,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"cloud-save.js","sourceRoot":"","sources":["../../src/tools/cloud-save.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAC3B,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEzG,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,0BAA0B;IAC1B,MAAM,CAAC,YAAY,CAAC,yBAAyB,EAAE;QAC7C,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,uGAAuG;YACvG,0GAA0G;YAC1G,sGAAsG;YACtG,6FAA6F;YAC7F,0CAA0C;YAC1C,UAAU;QACZ,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,wEAAwE,CAAC;YAC5G,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,qGAAqG,CAAC;YAC5I,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,kHAAkH,CAAC;SACtK;QACD,WAAW,EAAE;YACX,YAAY,EAAE,KAAK;YACnB,eAAe,EAAE,IAAI;YACrB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,IAAI;SACpB;KACF,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM;YAAE,OAAO,gBAAgB,EAAE,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;gBAC9D,MAAM;gBACN,QAAQ,EAAE,IAAI;aACf,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;YACjC,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,0BAA0B;IAC1B,MAAM,CAAC,YAAY,CAAC,yBAAyB,EAAE;QAC7C,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,2EAA2E;YAC3E,0GAA0G;YAC1G,wJAAwJ;YACxJ,UAAU;QACZ,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,wEAAwE,CAAC;YAC5G,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,kHAAkH,CAAC;SACtK;QACD,WAAW,EAAE,SAAS;KACvB,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM;YAAE,OAAO,gBAAgB,EAAE,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;gBAC9D,MAAM;aACP,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;YACjC,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/tools/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgB/D"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/tools/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoB/D"}
@@ -1,9 +1,13 @@
1
1
  import { createApiClientFromEnv } from "./api-client.js";
2
- import { noApiKeyResponse, errorResponse, jsonResponse } from "./tool-helpers.js";
2
+ import { noApiKeyResponse, errorResponse, jsonResponse, READ_ONLY, API_ERRORS } from "./tool-helpers.js";
3
3
  export function registerConnectionTools(server) {
4
4
  server.registerTool("horizon_test_connection", {
5
5
  title: "Test Connection",
6
- description: "Tests the connection to the horizOn API by fetching all remote configs as a health check. Returns success or failure.",
6
+ description: "Checks that HORIZON_API_KEY and HORIZON_BASE_URL work by fetching all remote configs of the app. " +
7
+ "Call it first during setup or when other tools fail. To check a player's session, use horizon_check_auth instead. " +
8
+ "Returns {success: true, data} with the remote configs; a 401 error means the API key is wrong. " +
9
+ API_ERRORS,
10
+ annotations: READ_ONLY,
7
11
  }, async () => {
8
12
  const client = createApiClientFromEnv();
9
13
  if (!client)
@@ -1 +1 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/tools/connection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAElF,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,YAAY,CAAC,yBAAyB,EAAE;QAC7C,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,uHAAuH;KAC1H,EAAE,KAAK,IAAI,EAAE;QACZ,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM;YAAE,OAAO,gBAAgB,EAAE,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YACjE,OAAO,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/tools/connection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEzG,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,YAAY,CAAC,yBAAyB,EAAE;QAC7C,KAAK,EAAE,iBAAiB;QACxB,WAAW,EACT,mGAAmG;YACnG,oHAAoH;YACpH,iGAAiG;YACjG,UAAU;QACZ,WAAW,EAAE,SAAS;KACvB,EAAE,KAAK,IAAI,EAAE;QACZ,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM;YAAE,OAAO,gBAAgB,EAAE,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;YACjE,OAAO,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACvD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"crash-reporting.d.ts","sourceRoot":"","sources":["../../src/tools/crash-reporting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAWpE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmEnE"}
1
+ {"version":3,"file":"crash-reporting.d.ts","sourceRoot":"","sources":["../../src/tools/crash-reporting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAWpE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4EnE"}
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod/v4";
2
2
  import { createApiClientFromEnv } from "./api-client.js";
3
- import { noApiKeyResponse, errorResponse, jsonResponse } from "./tool-helpers.js";
3
+ import { noApiKeyResponse, errorResponse, jsonResponse, ADDITIVE_WRITE, API_ERRORS } from "./tool-helpers.js";
4
4
  const BreadcrumbSchema = z.object({
5
5
  timestamp: z.string().describe("When the event occurred"),
6
6
  type: z.string().min(1).max(50).describe("Event type (e.g. 'navigation', 'http', 'user', 'error')"),
@@ -9,7 +9,11 @@ const BreadcrumbSchema = z.object({
9
9
  export function registerCrashReportingTools(server) {
10
10
  server.registerTool("horizon_create_crash_report", {
11
11
  title: "Create Crash Report",
12
- description: "Submits a crash report to horizOn. Crashes are grouped by fingerprint, with automatic regression detection when a resolved group receives new crashes.",
12
+ description: "Submits a crash (CRASH), a caught exception (NON_FATAL) or a freeze (ANR) to horizOn Crash Reporting, where it shows up in the dashboard. " +
13
+ "Register the session with horizon_create_crash_session first and pass the same sessionId. " +
14
+ "Reports with the same fingerprint form one group; if that group was marked resolved and a newer app version crashes again, it becomes REGRESSED. " +
15
+ "Each call adds a new report. Returns {id, groupId, createdAt}. For events that are not crashes, use horizon_create_log. " +
16
+ API_ERRORS,
13
17
  inputSchema: {
14
18
  type: z.enum(["CRASH", "NON_FATAL", "ANR"]).describe("Crash type: CRASH (fatal), NON_FATAL (exception), or ANR (Application Not Responding)"),
15
19
  message: z.string().min(1).max(5000).describe("Error message (1-5000 characters)"),
@@ -26,6 +30,7 @@ export function registerCrashReportingTools(server) {
26
30
  breadcrumbs: z.array(BreadcrumbSchema).max(50).optional().describe("Activity trail before the crash (max 50 items)"),
27
31
  customKeys: z.record(z.string(), z.string()).optional().describe("Key-value metadata (max 10 entries)"),
28
32
  },
33
+ annotations: ADDITIVE_WRITE,
29
34
  }, async ({ type, message, stackTrace, fingerprint, appVersion, sdkVersion, platform, os, deviceModel, deviceMemoryMb, sessionId, userId, breadcrumbs, customKeys }) => {
30
35
  const client = createApiClientFromEnv();
31
36
  if (!client)
@@ -54,13 +59,17 @@ export function registerCrashReportingTools(server) {
54
59
  });
55
60
  server.registerTool("horizon_create_crash_session", {
56
61
  title: "Create Crash Session",
57
- description: "Registers a game session for crash-free rate calculation. Call this at app start. If the session later has a crash report, it is marked automatically.",
62
+ description: "Registers a game session so horizOn can calculate the crash-free rate. Call it once at app start with a new unique sessionId, " +
63
+ "then pass that sessionId to horizon_create_crash_report if the session crashes; the session is then marked as crashed automatically. " +
64
+ "Returns {status: 'ok'}. " +
65
+ API_ERRORS,
58
66
  inputSchema: {
59
67
  sessionId: z.string().min(1).max(100).describe("Unique session identifier (1-100 characters)"),
60
68
  appVersion: z.string().min(1).max(50).describe("App version (e.g. '1.2.3')"),
61
69
  platform: z.string().min(1).max(50).describe("Platform (e.g. 'Android', 'iOS', 'Windows')"),
62
70
  userId: z.string().uuid().optional().describe("User ID (UUID) starting the session"),
63
71
  },
72
+ annotations: ADDITIVE_WRITE,
64
73
  }, async ({ sessionId, appVersion, platform, userId }) => {
65
74
  const client = createApiClientFromEnv();
66
75
  if (!client)