horizon-mcp 1.0.0 → 1.2.0
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 +5 -1
- package/dist/prompts/explain-feature.d.ts.map +1 -1
- package/dist/prompts/explain-feature.js +1 -0
- package/dist/prompts/explain-feature.js.map +1 -1
- package/dist/prompts/integrate-feature.d.ts.map +1 -1
- package/dist/prompts/integrate-feature.js +1 -0
- package/dist/prompts/integrate-feature.js.map +1 -1
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +28 -0
- package/dist/resources/index.js.map +1 -1
- package/dist/tools/__tests__/crash-reporting.test.d.ts +2 -0
- package/dist/tools/__tests__/crash-reporting.test.d.ts.map +1 -0
- package/dist/tools/__tests__/crash-reporting.test.js +191 -0
- package/dist/tools/__tests__/crash-reporting.test.js.map +1 -0
- package/dist/tools/api-client.d.ts +1 -0
- package/dist/tools/api-client.d.ts.map +1 -1
- package/dist/tools/api-client.js +14 -0
- package/dist/tools/api-client.js.map +1 -1
- package/dist/tools/crash-reporting.d.ts +3 -0
- package/dist/tools/crash-reporting.d.ts.map +1 -0
- package/dist/tools/crash-reporting.js +80 -0
- package/dist/tools/crash-reporting.js.map +1 -0
- package/dist/tools/email-sending.d.ts +3 -0
- package/dist/tools/email-sending.d.ts.map +1 -0
- package/dist/tools/email-sending.js +71 -0
- package/dist/tools/email-sending.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -1
- package/package.json +5 -2
- package/src/resources/docs/crash-reporting.md +228 -0
- package/src/resources/docs/email-sending.md +172 -0
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# horizOn MCP Server
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/horizon-mcp)
|
|
4
|
+
[](https://www.npmjs.com/package/horizon-mcp)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
3
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.
|
|
4
8
|
|
|
5
9
|
---
|
|
@@ -105,7 +109,7 @@ Core features:
|
|
|
105
109
|
- User Feedback
|
|
106
110
|
- User Logs
|
|
107
111
|
|
|
108
|
-
Learn more at [horizon.pm](https://horizon.pm).
|
|
112
|
+
Learn more at [horizon.pm](https://horizon.pm). Install this MCP server via [npm](https://www.npmjs.com/package/horizon-mcp).
|
|
109
113
|
|
|
110
114
|
## Supported Engines
|
|
111
115
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain-feature.d.ts","sourceRoot":"","sources":["../../src/prompts/explain-feature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"explain-feature.d.ts","sourceRoot":"","sources":["../../src/prompts/explain-feature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8BpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain-feature.js","sourceRoot":"","sources":["../../src/prompts/explain-feature.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,MAAM,UAAU,4BAA4B,CAAC,MAAiB;IAC5D,MAAM,CAAC,cAAc,CAAC,iBAAiB,EAAE;QACvC,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,oDAAoD;QACjE,UAAU,EAAE;YACV,OAAO,EAAE,CAAC;iBACP,IAAI,CAAC;gBACJ,MAAM;gBACN,aAAa;gBACb,YAAY;gBACZ,eAAe;gBACf,MAAM;gBACN,YAAY;gBACZ,UAAU;gBACV,WAAW;
|
|
1
|
+
{"version":3,"file":"explain-feature.js","sourceRoot":"","sources":["../../src/prompts/explain-feature.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,MAAM,UAAU,4BAA4B,CAAC,MAAiB;IAC5D,MAAM,CAAC,cAAc,CAAC,iBAAiB,EAAE;QACvC,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,oDAAoD;QACjE,UAAU,EAAE;YACV,OAAO,EAAE,CAAC;iBACP,IAAI,CAAC;gBACJ,MAAM;gBACN,aAAa;gBACb,YAAY;gBACZ,eAAe;gBACf,MAAM;gBACN,YAAY;gBACZ,UAAU;gBACV,WAAW;gBACX,iBAAiB;aAClB,CAAC;iBACD,QAAQ,CAAC,wBAAwB,CAAC;SACtC;KACF,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC;QACnB,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,wBAAwB,OAAO,wFAAwF,OAAO,uOAAuO;iBAC5W;aACF;SACF;KACF,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integrate-feature.d.ts","sourceRoot":"","sources":["../../src/prompts/integrate-feature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"integrate-feature.d.ts","sourceRoot":"","sources":["../../src/prompts/integrate-feature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkCtE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integrate-feature.js","sourceRoot":"","sources":["../../src/prompts/integrate-feature.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,MAAM,UAAU,8BAA8B,CAAC,MAAiB;IAC9D,MAAM,CAAC,cAAc,CAAC,mBAAmB,EAAE;QACzC,KAAK,EAAE,2BAA2B;QAClC,WAAW,EACT,+EAA+E;QACjF,UAAU,EAAE;YACV,OAAO,EAAE,CAAC;iBACP,IAAI,CAAC;gBACJ,MAAM;gBACN,aAAa;gBACb,YAAY;gBACZ,eAAe;gBACf,MAAM;gBACN,YAAY;gBACZ,UAAU;gBACV,WAAW;
|
|
1
|
+
{"version":3,"file":"integrate-feature.js","sourceRoot":"","sources":["../../src/prompts/integrate-feature.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,MAAM,UAAU,8BAA8B,CAAC,MAAiB;IAC9D,MAAM,CAAC,cAAc,CAAC,mBAAmB,EAAE;QACzC,KAAK,EAAE,2BAA2B;QAClC,WAAW,EACT,+EAA+E;QACjF,UAAU,EAAE;YACV,OAAO,EAAE,CAAC;iBACP,IAAI,CAAC;gBACJ,MAAM;gBACN,aAAa;gBACb,YAAY;gBACZ,eAAe;gBACf,MAAM;gBACN,YAAY;gBACZ,UAAU;gBACV,WAAW;gBACX,iBAAiB;aAClB,CAAC;iBACD,QAAQ,CAAC,kCAAkC,CAAC;YAC/C,MAAM,EAAE,CAAC;iBACN,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;iBAClC,QAAQ,CAAC,iBAAiB,CAAC;SAC/B;KACF,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3B,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,oCAAoC,OAAO,qBAAqB,MAAM,sGAAsG,OAAO,kBAAkB,MAAM,qDAAqD,MAAM,iMAAiM,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,mCAAmC,EAAE;iBACjkB;aACF;SACF;KACF,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0BpE;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0BpE;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2T5D"}
|
package/dist/resources/index.js
CHANGED
|
@@ -148,6 +148,20 @@ export function registerAllResources(server) {
|
|
|
148
148
|
},
|
|
149
149
|
],
|
|
150
150
|
}));
|
|
151
|
+
// Crash Reporting
|
|
152
|
+
server.registerResource("docs-crash-reporting", "horizon://docs/crash-reporting", {
|
|
153
|
+
title: "Crash Reporting",
|
|
154
|
+
description: "Crash report submission, session tracking, fingerprinting, breadcrumbs, and auto-regression detection. SDK examples.",
|
|
155
|
+
mimeType: "text/markdown",
|
|
156
|
+
}, () => ({
|
|
157
|
+
contents: [
|
|
158
|
+
{
|
|
159
|
+
uri: "horizon://docs/crash-reporting",
|
|
160
|
+
mimeType: "text/markdown",
|
|
161
|
+
text: loadDoc("docs/crash-reporting.md"),
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
}));
|
|
151
165
|
// API Reference
|
|
152
166
|
server.registerResource("api-reference", "horizon://api/reference", {
|
|
153
167
|
title: "App API Reference",
|
|
@@ -190,6 +204,20 @@ export function registerAllResources(server) {
|
|
|
190
204
|
},
|
|
191
205
|
],
|
|
192
206
|
}));
|
|
207
|
+
// Email Sending
|
|
208
|
+
server.registerResource("docs-email-sending", "horizon://docs/email-sending", {
|
|
209
|
+
title: "Email Sending",
|
|
210
|
+
description: "Transactional and event-based email delivery to registered users. Templates, scheduling, status tracking, and SMTP integration. SDK examples.",
|
|
211
|
+
mimeType: "text/markdown",
|
|
212
|
+
}, () => ({
|
|
213
|
+
contents: [
|
|
214
|
+
{
|
|
215
|
+
uri: "horizon://docs/email-sending",
|
|
216
|
+
mimeType: "text/markdown",
|
|
217
|
+
text: loadDoc("docs/email-sending.md"),
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
}));
|
|
193
221
|
// Quickstart: Unreal
|
|
194
222
|
server.registerResource("quickstart-unreal", "horizon://quickstart/unreal", {
|
|
195
223
|
title: "Unreal Engine Quickstart",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crash-reporting.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/crash-reporting.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { describe, it, expect, vi, afterEach } from "vitest";
|
|
2
|
+
import { registerCrashReportingTools } from "../crash-reporting.js";
|
|
3
|
+
// Mock api-client — keep real HorizonApiError so tool-helpers.ts works
|
|
4
|
+
vi.mock("../api-client.js", async (importOriginal) => {
|
|
5
|
+
const actual = await importOriginal();
|
|
6
|
+
return {
|
|
7
|
+
...actual,
|
|
8
|
+
createApiClientFromEnv: vi.fn(),
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
import { createApiClientFromEnv } from "../api-client.js";
|
|
12
|
+
const mockedCreateApiClient = vi.mocked(createApiClientFromEnv);
|
|
13
|
+
// Capture registered tools
|
|
14
|
+
const registeredTools = new Map();
|
|
15
|
+
function createMockServer() {
|
|
16
|
+
return {
|
|
17
|
+
registerTool: vi.fn((name, config, handler) => {
|
|
18
|
+
registeredTools.set(name, { schema: config, handler });
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
describe("registerCrashReportingTools", () => {
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
registeredTools.clear();
|
|
25
|
+
vi.restoreAllMocks();
|
|
26
|
+
});
|
|
27
|
+
it("registers both tools", () => {
|
|
28
|
+
const server = createMockServer();
|
|
29
|
+
registerCrashReportingTools(server);
|
|
30
|
+
expect(registeredTools.has("horizon_create_crash_report")).toBe(true);
|
|
31
|
+
expect(registeredTools.has("horizon_create_crash_session")).toBe(true);
|
|
32
|
+
expect(registeredTools.size).toBe(2);
|
|
33
|
+
});
|
|
34
|
+
describe("horizon_create_crash_report", () => {
|
|
35
|
+
it("returns no-api-key response when client is null", async () => {
|
|
36
|
+
const server = createMockServer();
|
|
37
|
+
registerCrashReportingTools(server);
|
|
38
|
+
mockedCreateApiClient.mockReturnValue(null);
|
|
39
|
+
const { handler } = registeredTools.get("horizon_create_crash_report");
|
|
40
|
+
const result = await handler({
|
|
41
|
+
type: "CRASH",
|
|
42
|
+
message: "test",
|
|
43
|
+
fingerprint: "fp1",
|
|
44
|
+
appVersion: "1.0",
|
|
45
|
+
sdkVersion: "0.5",
|
|
46
|
+
platform: "Android",
|
|
47
|
+
os: "Android 14",
|
|
48
|
+
deviceModel: "Pixel 8",
|
|
49
|
+
sessionId: "sess-1",
|
|
50
|
+
});
|
|
51
|
+
expect(result.content[0].text).toContain("HORIZON_API_KEY");
|
|
52
|
+
});
|
|
53
|
+
it("sends correct body with required fields only", async () => {
|
|
54
|
+
const server = createMockServer();
|
|
55
|
+
registerCrashReportingTools(server);
|
|
56
|
+
const mockPost = vi.fn().mockResolvedValue({ id: "r1", groupId: "g1", createdAt: "2025-01-01T00:00:00" });
|
|
57
|
+
mockedCreateApiClient.mockReturnValue({ post: mockPost });
|
|
58
|
+
const { handler } = registeredTools.get("horizon_create_crash_report");
|
|
59
|
+
await handler({
|
|
60
|
+
type: "CRASH",
|
|
61
|
+
message: "NullRef",
|
|
62
|
+
fingerprint: "fp1",
|
|
63
|
+
appVersion: "1.0",
|
|
64
|
+
sdkVersion: "0.5",
|
|
65
|
+
platform: "Android",
|
|
66
|
+
os: "Android 14",
|
|
67
|
+
deviceModel: "Pixel 8",
|
|
68
|
+
sessionId: "sess-1",
|
|
69
|
+
});
|
|
70
|
+
expect(mockPost).toHaveBeenCalledWith("/api/v1/app/crash-reports/create", {
|
|
71
|
+
type: "CRASH",
|
|
72
|
+
message: "NullRef",
|
|
73
|
+
fingerprint: "fp1",
|
|
74
|
+
appVersion: "1.0",
|
|
75
|
+
sdkVersion: "0.5",
|
|
76
|
+
platform: "Android",
|
|
77
|
+
os: "Android 14",
|
|
78
|
+
deviceModel: "Pixel 8",
|
|
79
|
+
sessionId: "sess-1",
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
it("includes optional fields only when defined", async () => {
|
|
83
|
+
const server = createMockServer();
|
|
84
|
+
registerCrashReportingTools(server);
|
|
85
|
+
const mockPost = vi.fn().mockResolvedValue({ id: "r1", groupId: "g1", createdAt: "2025-01-01" });
|
|
86
|
+
mockedCreateApiClient.mockReturnValue({ post: mockPost });
|
|
87
|
+
const { handler } = registeredTools.get("horizon_create_crash_report");
|
|
88
|
+
await handler({
|
|
89
|
+
type: "NON_FATAL",
|
|
90
|
+
message: "test",
|
|
91
|
+
stackTrace: "at line 42",
|
|
92
|
+
fingerprint: "fp2",
|
|
93
|
+
appVersion: "1.0",
|
|
94
|
+
sdkVersion: "0.5",
|
|
95
|
+
platform: "iOS",
|
|
96
|
+
os: "iOS 17",
|
|
97
|
+
deviceModel: "iPhone 15",
|
|
98
|
+
deviceMemoryMb: 6144,
|
|
99
|
+
sessionId: "sess-2",
|
|
100
|
+
userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
101
|
+
breadcrumbs: [{ timestamp: "2025-01-01T00:00:00Z", type: "error", message: "something" }],
|
|
102
|
+
customKeys: { scene: "Level5" },
|
|
103
|
+
});
|
|
104
|
+
const body = mockPost.mock.calls[0][1];
|
|
105
|
+
expect(body.stackTrace).toBe("at line 42");
|
|
106
|
+
expect(body.deviceMemoryMb).toBe(6144);
|
|
107
|
+
expect(body.userId).toBe("550e8400-e29b-41d4-a716-446655440000");
|
|
108
|
+
expect(body.breadcrumbs).toHaveLength(1);
|
|
109
|
+
expect(body.customKeys).toEqual({ scene: "Level5" });
|
|
110
|
+
});
|
|
111
|
+
it("returns error response on API failure", async () => {
|
|
112
|
+
const server = createMockServer();
|
|
113
|
+
registerCrashReportingTools(server);
|
|
114
|
+
const mockPost = vi.fn().mockRejectedValue(new Error("Network error"));
|
|
115
|
+
mockedCreateApiClient.mockReturnValue({ post: mockPost });
|
|
116
|
+
const { handler } = registeredTools.get("horizon_create_crash_report");
|
|
117
|
+
const result = await handler({
|
|
118
|
+
type: "CRASH",
|
|
119
|
+
message: "test",
|
|
120
|
+
fingerprint: "fp1",
|
|
121
|
+
appVersion: "1.0",
|
|
122
|
+
sdkVersion: "0.5",
|
|
123
|
+
platform: "Android",
|
|
124
|
+
os: "Android 14",
|
|
125
|
+
deviceModel: "Pixel 8",
|
|
126
|
+
sessionId: "sess-1",
|
|
127
|
+
});
|
|
128
|
+
expect(result.content[0].text).toContain("Network error");
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe("horizon_create_crash_session", () => {
|
|
132
|
+
it("returns no-api-key response when client is null", async () => {
|
|
133
|
+
const server = createMockServer();
|
|
134
|
+
registerCrashReportingTools(server);
|
|
135
|
+
mockedCreateApiClient.mockReturnValue(null);
|
|
136
|
+
const { handler } = registeredTools.get("horizon_create_crash_session");
|
|
137
|
+
const result = await handler({
|
|
138
|
+
sessionId: "sess-1",
|
|
139
|
+
appVersion: "1.0",
|
|
140
|
+
platform: "Android",
|
|
141
|
+
});
|
|
142
|
+
expect(result.content[0].text).toContain("HORIZON_API_KEY");
|
|
143
|
+
});
|
|
144
|
+
it("sends correct body with required fields", async () => {
|
|
145
|
+
const server = createMockServer();
|
|
146
|
+
registerCrashReportingTools(server);
|
|
147
|
+
const mockPost = vi.fn().mockResolvedValue({ status: "ok" });
|
|
148
|
+
mockedCreateApiClient.mockReturnValue({ post: mockPost });
|
|
149
|
+
const { handler } = registeredTools.get("horizon_create_crash_session");
|
|
150
|
+
await handler({
|
|
151
|
+
sessionId: "sess-1",
|
|
152
|
+
appVersion: "1.0",
|
|
153
|
+
platform: "Android",
|
|
154
|
+
});
|
|
155
|
+
expect(mockPost).toHaveBeenCalledWith("/api/v1/app/crash-reports/session", {
|
|
156
|
+
sessionId: "sess-1",
|
|
157
|
+
appVersion: "1.0",
|
|
158
|
+
platform: "Android",
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
it("includes userId when provided", async () => {
|
|
162
|
+
const server = createMockServer();
|
|
163
|
+
registerCrashReportingTools(server);
|
|
164
|
+
const mockPost = vi.fn().mockResolvedValue({ status: "ok" });
|
|
165
|
+
mockedCreateApiClient.mockReturnValue({ post: mockPost });
|
|
166
|
+
const { handler } = registeredTools.get("horizon_create_crash_session");
|
|
167
|
+
await handler({
|
|
168
|
+
sessionId: "sess-1",
|
|
169
|
+
appVersion: "1.0",
|
|
170
|
+
platform: "Android",
|
|
171
|
+
userId: "550e8400-e29b-41d4-a716-446655440000",
|
|
172
|
+
});
|
|
173
|
+
const body = mockPost.mock.calls[0][1];
|
|
174
|
+
expect(body.userId).toBe("550e8400-e29b-41d4-a716-446655440000");
|
|
175
|
+
});
|
|
176
|
+
it("returns error response on API failure", async () => {
|
|
177
|
+
const server = createMockServer();
|
|
178
|
+
registerCrashReportingTools(server);
|
|
179
|
+
const mockPost = vi.fn().mockRejectedValue(new Error("timeout"));
|
|
180
|
+
mockedCreateApiClient.mockReturnValue({ post: mockPost });
|
|
181
|
+
const { handler } = registeredTools.get("horizon_create_crash_session");
|
|
182
|
+
const result = await handler({
|
|
183
|
+
sessionId: "sess-1",
|
|
184
|
+
appVersion: "1.0",
|
|
185
|
+
platform: "Android",
|
|
186
|
+
});
|
|
187
|
+
expect(result.content[0].text).toContain("timeout");
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
//# sourceMappingURL=crash-reporting.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crash-reporting.test.js","sourceRoot":"","sources":["../../../src/tools/__tests__/crash-reporting.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,7 @@ export declare class HorizonApiClient {
|
|
|
15
15
|
constructor(apiKey: string, baseUrl: string);
|
|
16
16
|
get<T>(path: string, params?: Record<string, string>): Promise<T>;
|
|
17
17
|
post<T>(path: string, body?: unknown): Promise<T>;
|
|
18
|
+
delete<T>(path: string): Promise<T>;
|
|
18
19
|
}
|
|
19
20
|
/**
|
|
20
21
|
* Creates an API client from environment variables.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/tools/api-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;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;gBAErB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IASrC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAyBjE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/tools/api-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;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;gBAErB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IASrC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAyBjE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;IAkBjD,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;CAgB1C;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,GAAG,IAAI,CAOhE"}
|
package/dist/tools/api-client.js
CHANGED
|
@@ -61,6 +61,20 @@ export class HorizonApiClient {
|
|
|
61
61
|
}
|
|
62
62
|
return (await response.json());
|
|
63
63
|
}
|
|
64
|
+
async delete(path) {
|
|
65
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
66
|
+
method: "DELETE",
|
|
67
|
+
headers: {
|
|
68
|
+
"X-API-Key": this.apiKey,
|
|
69
|
+
"Content-Type": "application/json",
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
const responseBody = await response.text();
|
|
74
|
+
throw new HorizonApiError(response.status, responseBody);
|
|
75
|
+
}
|
|
76
|
+
return (await response.json());
|
|
77
|
+
}
|
|
64
78
|
}
|
|
65
79
|
/**
|
|
66
80
|
* Creates an API client from environment variables.
|
|
@@ -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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"}
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
import { createApiClientFromEnv } from "./api-client.js";
|
|
3
|
+
import { noApiKeyResponse, errorResponse, jsonResponse } from "./tool-helpers.js";
|
|
4
|
+
const BreadcrumbSchema = z.object({
|
|
5
|
+
timestamp: z.string().describe("When the event occurred"),
|
|
6
|
+
type: z.string().min(1).max(50).describe("Event type (e.g. 'navigation', 'http', 'user', 'error')"),
|
|
7
|
+
message: z.string().min(1).max(500).describe("Event description"),
|
|
8
|
+
});
|
|
9
|
+
export function registerCrashReportingTools(server) {
|
|
10
|
+
server.registerTool("horizon_create_crash_report", {
|
|
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.",
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: z.enum(["CRASH", "NON_FATAL", "ANR"]).describe("Crash type: CRASH (fatal), NON_FATAL (exception), or ANR (Application Not Responding)"),
|
|
15
|
+
message: z.string().min(1).max(5000).describe("Error message (1-5000 characters)"),
|
|
16
|
+
stackTrace: z.string().max(20000).optional().describe("Full stack trace (max 20000 characters)"),
|
|
17
|
+
fingerprint: z.string().min(1).max(128).describe("Grouping key — crashes with the same fingerprint are grouped together (1-128 characters)"),
|
|
18
|
+
appVersion: z.string().min(1).max(50).describe("App version (e.g. '1.2.3')"),
|
|
19
|
+
sdkVersion: z.string().min(1).max(50).describe("horizOn SDK version"),
|
|
20
|
+
platform: z.string().min(1).max(50).describe("Platform (e.g. 'Android', 'iOS', 'Windows')"),
|
|
21
|
+
os: z.string().min(1).max(100).describe("OS details (e.g. 'Android 14', 'iOS 17.2')"),
|
|
22
|
+
deviceModel: z.string().min(1).max(100).describe("Device model (e.g. 'Pixel 8', 'iPhone 15')"),
|
|
23
|
+
deviceMemoryMb: z.number().int().optional().describe("Device RAM in MB"),
|
|
24
|
+
sessionId: z.string().min(1).max(100).describe("Session ID from horizon_create_crash_session"),
|
|
25
|
+
userId: z.string().uuid().optional().describe("User ID (UUID) who experienced the crash"),
|
|
26
|
+
breadcrumbs: z.array(BreadcrumbSchema).max(50).optional().describe("Activity trail before the crash (max 50 items)"),
|
|
27
|
+
customKeys: z.record(z.string(), z.string()).optional().describe("Key-value metadata (max 10 entries)"),
|
|
28
|
+
},
|
|
29
|
+
}, async ({ type, message, stackTrace, fingerprint, appVersion, sdkVersion, platform, os, deviceModel, deviceMemoryMb, sessionId, userId, breadcrumbs, customKeys }) => {
|
|
30
|
+
const client = createApiClientFromEnv();
|
|
31
|
+
if (!client)
|
|
32
|
+
return noApiKeyResponse();
|
|
33
|
+
try {
|
|
34
|
+
const body = {
|
|
35
|
+
type, message, fingerprint, appVersion, sdkVersion,
|
|
36
|
+
platform, os, deviceModel, sessionId,
|
|
37
|
+
};
|
|
38
|
+
if (stackTrace !== undefined)
|
|
39
|
+
body.stackTrace = stackTrace;
|
|
40
|
+
if (deviceMemoryMb !== undefined)
|
|
41
|
+
body.deviceMemoryMb = deviceMemoryMb;
|
|
42
|
+
if (userId !== undefined)
|
|
43
|
+
body.userId = userId;
|
|
44
|
+
if (breadcrumbs !== undefined)
|
|
45
|
+
body.breadcrumbs = breadcrumbs;
|
|
46
|
+
if (customKeys !== undefined)
|
|
47
|
+
body.customKeys = customKeys;
|
|
48
|
+
const result = await client.post("/api/v1/app/crash-reports/create", body);
|
|
49
|
+
return jsonResponse(result);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
return errorResponse(error);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
server.registerTool("horizon_create_crash_session", {
|
|
56
|
+
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.",
|
|
58
|
+
inputSchema: {
|
|
59
|
+
sessionId: z.string().min(1).max(100).describe("Unique session identifier (1-100 characters)"),
|
|
60
|
+
appVersion: z.string().min(1).max(50).describe("App version (e.g. '1.2.3')"),
|
|
61
|
+
platform: z.string().min(1).max(50).describe("Platform (e.g. 'Android', 'iOS', 'Windows')"),
|
|
62
|
+
userId: z.string().uuid().optional().describe("User ID (UUID) starting the session"),
|
|
63
|
+
},
|
|
64
|
+
}, async ({ sessionId, appVersion, platform, userId }) => {
|
|
65
|
+
const client = createApiClientFromEnv();
|
|
66
|
+
if (!client)
|
|
67
|
+
return noApiKeyResponse();
|
|
68
|
+
try {
|
|
69
|
+
const body = { sessionId, appVersion, platform };
|
|
70
|
+
if (userId !== undefined)
|
|
71
|
+
body.userId = userId;
|
|
72
|
+
const result = await client.post("/api/v1/app/crash-reports/session", body);
|
|
73
|
+
return jsonResponse(result);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
return errorResponse(error);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=crash-reporting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crash-reporting.js","sourceRoot":"","sources":["../../src/tools/crash-reporting.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,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IACzD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,yDAAyD,CAAC;IACnG,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,mBAAmB,CAAC;CAClE,CAAC,CAAC;AAEH,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,YAAY,CAAC,6BAA6B,EAAE;QACjD,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EACT,wJAAwJ;QAC1J,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,uFAAuF,CAAC;YAC7I,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YAClF,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yCAAyC,CAAC;YAChG,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,0FAA0F,CAAC;YAC5I,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YAC5E,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC;YACrE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YAC3F,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,4CAA4C,CAAC;YACrF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,4CAA4C,CAAC;YAC9F,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YACxE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;YAC9F,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YACzF,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;YACpH,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;SACxG;KACF,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,EAAE;QACrK,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM;YAAE,OAAO,gBAAgB,EAAE,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,IAAI,GAA4B;gBACpC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU;gBAClD,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,SAAS;aACrC,CAAC;YACF,IAAI,UAAU,KAAK,SAAS;gBAAE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAC3D,IAAI,cAAc,KAAK,SAAS;gBAAE,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;YACvE,IAAI,MAAM,KAAK,SAAS;gBAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YAC/C,IAAI,WAAW,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;YAC9D,IAAI,UAAU,KAAK,SAAS;gBAAE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;YAE3D,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,IAAI,CAAC,CAAC;YAC3E,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,MAAM,CAAC,YAAY,CAAC,8BAA8B,EAAE;QAClD,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,wJAAwJ;QAC1J,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;YAC9F,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;YAC5E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YAC3F,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC;SACrF;KACF,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE;QACvD,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM;YAAE,OAAO,gBAAgB,EAAE,CAAC;QAEvC,IAAI,CAAC;YACH,MAAM,IAAI,GAA4B,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;YAC1E,IAAI,MAAM,KAAK,SAAS;gBAAE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YAE/C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,mCAAmC,EAAE,IAAI,CAAC,CAAC;YAC5E,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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-sending.d.ts","sourceRoot":"","sources":["../../src/tools/email-sending.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAoEjE"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
import { createApiClientFromEnv } from "./api-client.js";
|
|
3
|
+
import { noApiKeyResponse, errorResponse, jsonResponse } from "./tool-helpers.js";
|
|
4
|
+
export function registerEmailSendingTools(server) {
|
|
5
|
+
server.registerTool("horizon_send_email", {
|
|
6
|
+
title: "Send Email",
|
|
7
|
+
description: "Sends a transactional email to a registered horizOn user using a pre-configured template. " +
|
|
8
|
+
"The email is sent through the developer's own SMTP server. " +
|
|
9
|
+
"Optionally schedule delivery for a future time (up to 30 days ahead).",
|
|
10
|
+
inputSchema: {
|
|
11
|
+
userId: z.string().uuid().describe("horizOn user ID of the recipient"),
|
|
12
|
+
templateSlug: z.string().min(1).describe("Slug of the email template (e.g. 'welcome', 'reminder')"),
|
|
13
|
+
variables: z.record(z.string(), z.string()).describe("Template variable values as key-value pairs (e.g. {\"username\": \"John\"})"),
|
|
14
|
+
language: z.string().length(2).describe("ISO 639-1 language code for template rendering (e.g. 'en', 'de')"),
|
|
15
|
+
scheduledAt: z.string().optional().describe("ISO 8601 timestamp for scheduled delivery. Omit to send immediately."),
|
|
16
|
+
},
|
|
17
|
+
}, async ({ userId, templateSlug, variables, language, scheduledAt }) => {
|
|
18
|
+
const client = createApiClientFromEnv();
|
|
19
|
+
if (!client)
|
|
20
|
+
return noApiKeyResponse();
|
|
21
|
+
try {
|
|
22
|
+
const body = { userId, templateSlug, variables, language };
|
|
23
|
+
if (scheduledAt !== undefined)
|
|
24
|
+
body.scheduledAt = scheduledAt;
|
|
25
|
+
const result = await client.post("/api/v1/app/email-sending/send", body);
|
|
26
|
+
return jsonResponse(result);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
return errorResponse(error);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
server.registerTool("horizon_cancel_email", {
|
|
33
|
+
title: "Cancel Email",
|
|
34
|
+
description: "Cancels a pending or scheduled email. Only emails with status 'pending' can be cancelled. " +
|
|
35
|
+
"The email must belong to the same API key.",
|
|
36
|
+
inputSchema: {
|
|
37
|
+
emailId: z.string().uuid().describe("ID of the email to cancel (returned by send_email)"),
|
|
38
|
+
},
|
|
39
|
+
}, async ({ emailId }) => {
|
|
40
|
+
const client = createApiClientFromEnv();
|
|
41
|
+
if (!client)
|
|
42
|
+
return noApiKeyResponse();
|
|
43
|
+
try {
|
|
44
|
+
const result = await client.delete(`/api/v1/app/email-sending/${emailId}`);
|
|
45
|
+
return jsonResponse(result);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
return errorResponse(error);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
server.registerTool("horizon_get_email_status", {
|
|
52
|
+
title: "Get Email Status",
|
|
53
|
+
description: "Gets the current status of a specific email (pending, processing, sent, or failed). " +
|
|
54
|
+
"Use this to check whether a sent or scheduled email has been delivered.",
|
|
55
|
+
inputSchema: {
|
|
56
|
+
emailId: z.string().uuid().describe("ID of the email to check (returned by send_email)"),
|
|
57
|
+
},
|
|
58
|
+
}, async ({ emailId }) => {
|
|
59
|
+
const client = createApiClientFromEnv();
|
|
60
|
+
if (!client)
|
|
61
|
+
return noApiKeyResponse();
|
|
62
|
+
try {
|
|
63
|
+
const result = await client.get(`/api/v1/app/email-sending/${emailId}`);
|
|
64
|
+
return jsonResponse(result);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
return errorResponse(error);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=email-sending.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-sending.js","sourceRoot":"","sources":["../../src/tools/email-sending.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAapE;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAYxD"}
|
package/dist/tools/index.js
CHANGED
|
@@ -7,6 +7,8 @@ import { registerNewsTools } from "./news.js";
|
|
|
7
7
|
import { registerGiftCodeTools } from "./gift-codes.js";
|
|
8
8
|
import { registerFeedbackTools } from "./feedback.js";
|
|
9
9
|
import { registerUserLogTools } from "./user-logs.js";
|
|
10
|
+
import { registerCrashReportingTools } from "./crash-reporting.js";
|
|
11
|
+
import { registerEmailSendingTools } from "./email-sending.js";
|
|
10
12
|
/**
|
|
11
13
|
* Registers all horizOn MCP tools on the given server.
|
|
12
14
|
*/
|
|
@@ -20,5 +22,7 @@ export function registerAllTools(server) {
|
|
|
20
22
|
registerGiftCodeTools(server);
|
|
21
23
|
registerFeedbackTools(server);
|
|
22
24
|
registerUserLogTools(server);
|
|
25
|
+
registerCrashReportingTools(server);
|
|
26
|
+
registerEmailSendingTools(server);
|
|
23
27
|
}
|
|
24
28
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,2BAA2B,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAE/D;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACjC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAClC,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,2BAA2B,CAAC,MAAM,CAAC,CAAC;IACpC,yBAAyB,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "horizon-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "MCP server for horizOn Backend-as-a-Service — documentation, live API tools, and workflow prompts for Godot, Unity, and Unreal Engine integration.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -35,7 +35,10 @@
|
|
|
35
35
|
"type": "git",
|
|
36
36
|
"url": "https://github.com/ProjectMakersDE/horizOn-mcp.git"
|
|
37
37
|
},
|
|
38
|
-
"homepage": "https://horizon
|
|
38
|
+
"homepage": "https://www.npmjs.com/package/horizon-mcp",
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/ProjectMakersDE/horizOn-mcp/issues"
|
|
41
|
+
},
|
|
39
42
|
"engines": {
|
|
40
43
|
"node": ">=18.0.0"
|
|
41
44
|
},
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# Crash Reporting
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Crash Reporting lets you track fatal crashes, non-fatal exceptions, and ANR (Application Not Responding) events from your game. Reports are automatically grouped by fingerprint, and the system detects regressions when a previously resolved crash reappears in a newer version.
|
|
6
|
+
|
|
7
|
+
**Workflow:**
|
|
8
|
+
1. Register a session at app start (`POST /session`)
|
|
9
|
+
2. If a crash occurs, submit a crash report (`POST /create`)
|
|
10
|
+
3. The backend groups reports by fingerprint and tracks affected versions
|
|
11
|
+
4. View and manage crash groups in the horizOn Dashboard
|
|
12
|
+
|
|
13
|
+
## Endpoints
|
|
14
|
+
|
|
15
|
+
### Create Crash Session
|
|
16
|
+
|
|
17
|
+
**`POST /api/v1/app/crash-reports/session`**
|
|
18
|
+
|
|
19
|
+
Registers a game session. Used to calculate crash-free rate. Call once at app startup.
|
|
20
|
+
|
|
21
|
+
**Request Body:**
|
|
22
|
+
|
|
23
|
+
| Field | Type | Required | Description |
|
|
24
|
+
|-------|------|----------|-------------|
|
|
25
|
+
| `sessionId` | string | Yes | Unique session identifier (1-100 characters) |
|
|
26
|
+
| `appVersion` | string | Yes | App version (e.g. "1.2.3") |
|
|
27
|
+
| `platform` | string | Yes | Platform (e.g. "Android", "iOS", "Windows") |
|
|
28
|
+
| `userId` | string | No | User ID (UUID) |
|
|
29
|
+
|
|
30
|
+
**Response (201):**
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{ "status": "ok" }
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Create Crash Report
|
|
37
|
+
|
|
38
|
+
**`POST /api/v1/app/crash-reports/create`**
|
|
39
|
+
|
|
40
|
+
Submits a crash report. The backend groups it by fingerprint.
|
|
41
|
+
|
|
42
|
+
**Request Body:**
|
|
43
|
+
|
|
44
|
+
| Field | Type | Required | Description |
|
|
45
|
+
|-------|------|----------|-------------|
|
|
46
|
+
| `type` | string | Yes | `CRASH`, `NON_FATAL`, or `ANR` |
|
|
47
|
+
| `message` | string | Yes | Error message (1-5000 characters) |
|
|
48
|
+
| `stackTrace` | string | No | Full stack trace (max 20000 characters) |
|
|
49
|
+
| `fingerprint` | string | Yes | Grouping key (1-128 characters) |
|
|
50
|
+
| `appVersion` | string | Yes | App version |
|
|
51
|
+
| `sdkVersion` | string | Yes | horizOn SDK version |
|
|
52
|
+
| `platform` | string | Yes | Platform |
|
|
53
|
+
| `os` | string | Yes | OS details (e.g. "Android 14") |
|
|
54
|
+
| `deviceModel` | string | Yes | Device model (e.g. "Pixel 8") |
|
|
55
|
+
| `deviceMemoryMb` | number | No | Device RAM in MB |
|
|
56
|
+
| `sessionId` | string | Yes | Session ID from session registration |
|
|
57
|
+
| `userId` | string | No | User ID (UUID) |
|
|
58
|
+
| `breadcrumbs` | array | No | Activity trail before crash (max 50 items) |
|
|
59
|
+
| `customKeys` | object | No | Key-value metadata (max 10 entries) |
|
|
60
|
+
|
|
61
|
+
**Breadcrumb item:**
|
|
62
|
+
|
|
63
|
+
| Field | Type | Description |
|
|
64
|
+
|-------|------|-------------|
|
|
65
|
+
| `timestamp` | string | When the event occurred |
|
|
66
|
+
| `type` | string | Event type: `navigation`, `http`, `user`, `error`, `warning` |
|
|
67
|
+
| `message` | string | Event description (max 500 characters) |
|
|
68
|
+
|
|
69
|
+
**Response (201):**
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"id": "550e8400-e29b-41d4-a716-446655440000",
|
|
74
|
+
"groupId": "660e8400-e29b-41d4-a716-446655440001",
|
|
75
|
+
"createdAt": "2025-01-15T10:30:00"
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Crash Types
|
|
80
|
+
|
|
81
|
+
| Type | Description |
|
|
82
|
+
|------|-------------|
|
|
83
|
+
| `CRASH` | Fatal crash — the app terminated unexpectedly |
|
|
84
|
+
| `NON_FATAL` | Non-fatal exception — caught but worth tracking |
|
|
85
|
+
| `ANR` | Application Not Responding — the app froze/hung |
|
|
86
|
+
|
|
87
|
+
## Fingerprinting
|
|
88
|
+
|
|
89
|
+
The `fingerprint` field determines how crashes are grouped. Crashes with the same fingerprint belong to the same group. Typical fingerprint strategies:
|
|
90
|
+
|
|
91
|
+
- **Stack trace hash** — Hash the top N frames of the stack trace
|
|
92
|
+
- **Error class + location** — Combine exception class name with file/line
|
|
93
|
+
- **Manual grouping** — Use a custom identifier for known crash patterns
|
|
94
|
+
|
|
95
|
+
## Auto-Regression Detection
|
|
96
|
+
|
|
97
|
+
When a crash group is marked as **RESOLVED** (with a `resolvedInVersion`), and a new crash arrives with a higher app version, the group automatically transitions to **REGRESSED** status. This helps catch bugs that were thought to be fixed.
|
|
98
|
+
|
|
99
|
+
## Code Examples
|
|
100
|
+
|
|
101
|
+
### Godot (GDScript)
|
|
102
|
+
|
|
103
|
+
```gdscript
|
|
104
|
+
# Register session at app start
|
|
105
|
+
await Horizon.crashReporting.createSession()
|
|
106
|
+
|
|
107
|
+
# Report a crash with breadcrumbs
|
|
108
|
+
var breadcrumbs = [
|
|
109
|
+
{"timestamp": "2025-01-15T10:29:55Z", "type": "navigation", "message": "Entered level 5"},
|
|
110
|
+
{"timestamp": "2025-01-15T10:29:58Z", "type": "user", "message": "Used power-up"},
|
|
111
|
+
{"timestamp": "2025-01-15T10:30:00Z", "type": "error", "message": "Null reference"}
|
|
112
|
+
]
|
|
113
|
+
await Horizon.crashReporting.createCrashReport(
|
|
114
|
+
HorizonCrashReporting.CrashType.CRASH,
|
|
115
|
+
"NullReferenceException in CombatSystem.gd",
|
|
116
|
+
stack_trace,
|
|
117
|
+
"combat_null_ref_line42",
|
|
118
|
+
breadcrumbs
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Report a non-fatal exception
|
|
122
|
+
await Horizon.crashReporting.createCrashReport(
|
|
123
|
+
HorizonCrashReporting.CrashType.NON_FATAL,
|
|
124
|
+
"Failed to load texture: res://assets/missing.png",
|
|
125
|
+
"",
|
|
126
|
+
"texture_load_fail"
|
|
127
|
+
)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Unity (C#)
|
|
131
|
+
|
|
132
|
+
```csharp
|
|
133
|
+
using PM.horizOn.Cloud.Manager;
|
|
134
|
+
using PM.horizOn.Cloud.Enums;
|
|
135
|
+
|
|
136
|
+
// Register session at app start
|
|
137
|
+
await CrashReportingManager.Instance.CreateSession();
|
|
138
|
+
|
|
139
|
+
// Report a crash
|
|
140
|
+
await CrashReportingManager.Instance.CreateCrashReport(
|
|
141
|
+
CrashType.CRASH,
|
|
142
|
+
"NullReferenceException: Object reference not set",
|
|
143
|
+
exception.StackTrace,
|
|
144
|
+
"combat_null_ref",
|
|
145
|
+
breadcrumbs: new List<Breadcrumb>
|
|
146
|
+
{
|
|
147
|
+
new("2025-01-15T10:30:00Z", "error", "Null ref in CombatSystem")
|
|
148
|
+
},
|
|
149
|
+
customKeys: new Dictionary<string, string>
|
|
150
|
+
{
|
|
151
|
+
{ "scene", "Level5" },
|
|
152
|
+
{ "player_level", "12" }
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
# Report a non-fatal exception
|
|
157
|
+
await CrashReportingManager.Instance.CreateCrashReport(
|
|
158
|
+
CrashType.NON_FATAL,
|
|
159
|
+
"Texture load failed",
|
|
160
|
+
fingerprint: "texture_load_fail"
|
|
161
|
+
);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### REST (cURL)
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Register session
|
|
168
|
+
curl -X POST https://horizon.pm/api/v1/app/crash-reports/session \
|
|
169
|
+
-H "X-API-Key: YOUR_API_KEY" \
|
|
170
|
+
-H "Content-Type: application/json" \
|
|
171
|
+
-d '{
|
|
172
|
+
"sessionId": "sess-abc123",
|
|
173
|
+
"appVersion": "1.2.3",
|
|
174
|
+
"platform": "Android"
|
|
175
|
+
}'
|
|
176
|
+
|
|
177
|
+
# Submit crash report
|
|
178
|
+
curl -X POST https://horizon.pm/api/v1/app/crash-reports/create \
|
|
179
|
+
-H "X-API-Key: YOUR_API_KEY" \
|
|
180
|
+
-H "Content-Type: application/json" \
|
|
181
|
+
-d '{
|
|
182
|
+
"type": "CRASH",
|
|
183
|
+
"message": "NullReferenceException in CombatSystem",
|
|
184
|
+
"stackTrace": "at CombatSystem.Update() line 42...",
|
|
185
|
+
"fingerprint": "combat_null_ref_line42",
|
|
186
|
+
"appVersion": "1.2.3",
|
|
187
|
+
"sdkVersion": "0.5.0",
|
|
188
|
+
"platform": "Android",
|
|
189
|
+
"os": "Android 14",
|
|
190
|
+
"deviceModel": "Pixel 8",
|
|
191
|
+
"deviceMemoryMb": 8192,
|
|
192
|
+
"sessionId": "sess-abc123",
|
|
193
|
+
"breadcrumbs": [
|
|
194
|
+
{"timestamp": "2025-01-15T10:30:00Z", "type": "error", "message": "Null ref in combat"}
|
|
195
|
+
],
|
|
196
|
+
"customKeys": {"scene": "Level5", "player_level": "12"}
|
|
197
|
+
}'
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Best Practices
|
|
201
|
+
|
|
202
|
+
- **Register sessions early** — Call `createSession` at app launch so crash-free rate is accurate.
|
|
203
|
+
- **Use consistent fingerprints** — Same crash should always produce the same fingerprint for proper grouping.
|
|
204
|
+
- **Add breadcrumbs** — They provide context for what the user did before the crash, making debugging easier.
|
|
205
|
+
- **Include custom keys** — Add scene name, player state, or other context that helps reproduce the issue.
|
|
206
|
+
- **Keep stack traces** — Always include the full stack trace when available.
|
|
207
|
+
|
|
208
|
+
## Tier Requirements
|
|
209
|
+
|
|
210
|
+
All tiers can use crash reporting, but with different limits:
|
|
211
|
+
|
|
212
|
+
| Tier | Report Limit | Retention |
|
|
213
|
+
|------|-------------|-----------|
|
|
214
|
+
| FREE | Configured per tier | Configured per tier |
|
|
215
|
+
| BASIC | Higher limit | Longer retention |
|
|
216
|
+
| PRO | Higher limit | Longer retention |
|
|
217
|
+
| ENTERPRISE | Highest limit | Longest retention |
|
|
218
|
+
|
|
219
|
+
Exact limits are configured via system configuration and may change.
|
|
220
|
+
|
|
221
|
+
## Common Errors
|
|
222
|
+
|
|
223
|
+
| Status | Cause | Solution |
|
|
224
|
+
|--------|-------|----------|
|
|
225
|
+
| 400 | Missing required fields | Ensure all required fields are provided |
|
|
226
|
+
| 401 | Invalid API key | Check `X-API-Key` header |
|
|
227
|
+
| 403 | Crash report limit reached | Upgrade tier or wait for retention cleanup |
|
|
228
|
+
| 429 | Rate limit exceeded | Throttle crash report submissions |
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Email Sending
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Email Sending lets you send transactional and event-based emails to your registered end-users through their horizOn user ID. Emails are rendered from reusable templates with variable substitution and multi-language support. All emails are sent through the developer's own SMTP server — horizOn never sends on behalf of developers.
|
|
6
|
+
|
|
7
|
+
This feature is designed for notifications, reminders, confirmations, and event-based communication. It is **not** a newsletter or marketing automation tool.
|
|
8
|
+
|
|
9
|
+
**Requires:** BASIC tier or higher. SMTP credentials must be configured in the horizOn Dashboard.
|
|
10
|
+
|
|
11
|
+
## Key Concepts
|
|
12
|
+
|
|
13
|
+
- **Templates** are created and managed in the Dashboard (not via SDK/API). Each template has a slug, subject, HTML body, and variable definitions — all with multi-language support.
|
|
14
|
+
- **Variables** are placeholders in templates (e.g., `{{username}}`). The app provides values when sending.
|
|
15
|
+
- **Immediate emails** are processed on the next ticker run (~5 minutes).
|
|
16
|
+
- **Scheduled emails** are stored with a future timestamp and sent when the time arrives.
|
|
17
|
+
- **Email lifecycle:** `pending` -> `processing` -> `sent` or `failed`. Cancelled emails are deleted immediately.
|
|
18
|
+
|
|
19
|
+
## Endpoints
|
|
20
|
+
|
|
21
|
+
### Send Email
|
|
22
|
+
|
|
23
|
+
**`POST /api/v1/app/email-sending/send`**
|
|
24
|
+
|
|
25
|
+
Sends an email to a registered user. Optionally schedule for later delivery.
|
|
26
|
+
|
|
27
|
+
**Request Body:**
|
|
28
|
+
|
|
29
|
+
| Field | Type | Required | Description |
|
|
30
|
+
|-------|------|----------|-------------|
|
|
31
|
+
| `userId` | UUID | Yes | horizOn user ID of the recipient |
|
|
32
|
+
| `templateSlug` | string | Yes | Template slug (e.g., `welcome`, `reminder`) |
|
|
33
|
+
| `variables` | object | Yes | Variable values as key-value pairs. Can be `{}`. |
|
|
34
|
+
| `language` | string | Yes | Language code (e.g., `en`, `de`) |
|
|
35
|
+
| `scheduledAt` | string | No | ISO 8601 timestamp. Omit for immediate delivery. |
|
|
36
|
+
|
|
37
|
+
**Response (201):**
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"id": "uuid",
|
|
42
|
+
"status": "pending",
|
|
43
|
+
"scheduledAt": "2026-04-12T09:00:00Z"
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Cancel Email
|
|
48
|
+
|
|
49
|
+
**`DELETE /api/v1/app/email-sending/{emailId}`**
|
|
50
|
+
|
|
51
|
+
Cancels a pending email. Only emails with status `pending` can be cancelled.
|
|
52
|
+
|
|
53
|
+
**Response (200):**
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"message": "Email cancelled"
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Get Email Status
|
|
62
|
+
|
|
63
|
+
**`GET /api/v1/app/email-sending/{emailId}`**
|
|
64
|
+
|
|
65
|
+
Returns the current status of an email.
|
|
66
|
+
|
|
67
|
+
**Response (200):**
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"id": "uuid",
|
|
72
|
+
"status": "sent",
|
|
73
|
+
"templateSlug": "reminder",
|
|
74
|
+
"userId": "uuid",
|
|
75
|
+
"language": "en",
|
|
76
|
+
"scheduledAt": null,
|
|
77
|
+
"processedAt": "2026-04-11T10:05:00Z",
|
|
78
|
+
"errorReason": null,
|
|
79
|
+
"createdAt": "2026-04-11T10:00:00Z"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Code Examples
|
|
84
|
+
|
|
85
|
+
### Godot (GDScript)
|
|
86
|
+
|
|
87
|
+
```gdscript
|
|
88
|
+
# Send an immediate email
|
|
89
|
+
var result = await Horizon.emailSending.sendEmail(
|
|
90
|
+
user_id, "welcome", {"username": "John"}, "en"
|
|
91
|
+
)
|
|
92
|
+
print("Email queued: %s" % result.id)
|
|
93
|
+
|
|
94
|
+
# Schedule an email for tomorrow
|
|
95
|
+
var result = await Horizon.emailSending.sendEmail(
|
|
96
|
+
user_id, "reminder", {"appointmentTime": "14:00"}, "en",
|
|
97
|
+
"2026-04-12T09:00:00Z"
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# Cancel a scheduled email
|
|
101
|
+
await Horizon.emailSending.cancelEmail(result.id)
|
|
102
|
+
|
|
103
|
+
# Check status
|
|
104
|
+
var status = await Horizon.emailSending.getEmailStatus(result.id)
|
|
105
|
+
print("Status: %s" % status.status)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Unity (C#)
|
|
109
|
+
|
|
110
|
+
```csharp
|
|
111
|
+
using PM.horizOn.Cloud.Manager;
|
|
112
|
+
|
|
113
|
+
// Send immediately
|
|
114
|
+
var result = await EmailSendingManager.Instance.SendEmail(
|
|
115
|
+
userId, "welcome",
|
|
116
|
+
new Dictionary<string, string> { { "username", "John" } },
|
|
117
|
+
"en"
|
|
118
|
+
);
|
|
119
|
+
Debug.Log($"Email queued: {result.Id}");
|
|
120
|
+
|
|
121
|
+
// Schedule for later
|
|
122
|
+
var scheduled = await EmailSendingManager.Instance.SendEmail(
|
|
123
|
+
userId, "reminder",
|
|
124
|
+
new Dictionary<string, string> { { "appointmentTime", "14:00" } },
|
|
125
|
+
"en", scheduledAt: "2026-04-12T09:00:00Z"
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
// Cancel
|
|
129
|
+
await EmailSendingManager.Instance.CancelEmail(scheduled.Id);
|
|
130
|
+
|
|
131
|
+
// Check status
|
|
132
|
+
var status = await EmailSendingManager.Instance.GetEmailStatus(scheduled.Id);
|
|
133
|
+
Debug.Log($"Status: {status.Status}");
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### REST (cURL)
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Send email
|
|
140
|
+
curl -X POST "https://horizon.pm/api/v1/app/email-sending/send" \
|
|
141
|
+
-H "X-API-Key: YOUR_API_KEY" \
|
|
142
|
+
-H "Content-Type: application/json" \
|
|
143
|
+
-d '{"userId":"USER_UUID","templateSlug":"welcome","variables":{"username":"John"},"language":"en"}'
|
|
144
|
+
|
|
145
|
+
# Cancel email
|
|
146
|
+
curl -X DELETE "https://horizon.pm/api/v1/app/email-sending/EMAIL_UUID" \
|
|
147
|
+
-H "X-API-Key: YOUR_API_KEY"
|
|
148
|
+
|
|
149
|
+
# Get status
|
|
150
|
+
curl "https://horizon.pm/api/v1/app/email-sending/EMAIL_UUID" \
|
|
151
|
+
-H "X-API-Key: YOUR_API_KEY"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Best Practices
|
|
155
|
+
|
|
156
|
+
- **Use meaningful template slugs** like `welcome`, `reminder`, `purchase_confirm` for self-documenting API calls.
|
|
157
|
+
- **Check email status** after sending to confirm delivery, especially for critical notifications.
|
|
158
|
+
- **Schedule one email at a time** — don't schedule weeks ahead. Schedule the next relevant one and plan the following when the user returns.
|
|
159
|
+
- **Handle errors gracefully** — if SMTP is misconfigured or the user has no verified email, the API returns clear error messages.
|
|
160
|
+
- **Monitor the Dashboard** — regularly check the failed emails section to catch SMTP issues early.
|
|
161
|
+
|
|
162
|
+
## Common Errors
|
|
163
|
+
|
|
164
|
+
| Status | Cause | Solution |
|
|
165
|
+
|--------|-------|----------|
|
|
166
|
+
| 400 | SMTP not configured | Configure SMTP credentials in the Dashboard |
|
|
167
|
+
| 400 | Template not found | Verify the template slug exists for this API key |
|
|
168
|
+
| 400 | User has no verified email | Ensure the user has verified their email address |
|
|
169
|
+
| 400 | Missing required variable | Provide all variables the template expects |
|
|
170
|
+
| 403 | Feature not available | Upgrade from FREE tier to BASIC or higher |
|
|
171
|
+
| 404 | Email not found | Verify the email ID and API key ownership |
|
|
172
|
+
| 429 | Rate limit exceeded | Reduce request frequency |
|