horizon-mcp 1.3.1 → 1.4.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.
@@ -1 +1 @@
1
- {"version":3,"file":"leaderboard.d.ts","sourceRoot":"","sources":["../../src/tools/leaderboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKpE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8FhE"}
1
+ {"version":3,"file":"leaderboard.d.ts","sourceRoot":"","sources":["../../src/tools/leaderboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAqCpE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgIhE"}
@@ -1,24 +1,55 @@
1
1
  import { z } from "zod/v4";
2
2
  import { createApiClientFromEnv } from "./api-client.js";
3
3
  import { noApiKeyResponse, errorResponse, jsonResponse } from "./tool-helpers.js";
4
+ /**
5
+ * Slug constraint mirrors the server-side validator on
6
+ * `SubmitScoreRequest.leaderboardKey` and `Leaderboard.key`.
7
+ */
8
+ const leaderboardKeySchema = z
9
+ .string()
10
+ .min(1)
11
+ .max(64)
12
+ .regex(/^[a-z0-9_-]+$/, "Lowercase alphanumeric with - or _")
13
+ .optional()
14
+ .describe("Leaderboard key — selects a named board on the API key. Omit to use the default board.");
15
+ function topPath(leaderboardKey) {
16
+ return leaderboardKey
17
+ ? `/api/v1/app/leaderboards/${encodeURIComponent(leaderboardKey)}/top`
18
+ : "/api/v1/app/leaderboard/top";
19
+ }
20
+ function rankPath(leaderboardKey) {
21
+ return leaderboardKey
22
+ ? `/api/v1/app/leaderboards/${encodeURIComponent(leaderboardKey)}/rank`
23
+ : "/api/v1/app/leaderboard/rank";
24
+ }
25
+ function aroundPath(leaderboardKey) {
26
+ return leaderboardKey
27
+ ? `/api/v1/app/leaderboards/${encodeURIComponent(leaderboardKey)}/around`
28
+ : "/api/v1/app/leaderboard/around";
29
+ }
4
30
  export function registerLeaderboardTools(server) {
5
31
  // --- Submit score ---
6
32
  server.registerTool("horizon_submit_score", {
7
33
  title: "Submit Score",
8
- description: "Submits a score to the horizOn leaderboard for a given user.",
34
+ description: "Submits a score to a horizOn leaderboard for a given user. Pass leaderboardKey to target a specific board; omit it for the default board.",
9
35
  inputSchema: {
10
36
  userId: z.string().uuid().describe("User ID (UUID)"),
11
- score: z.number().int().min(0).describe("Score to submit (non-negative integer)"),
37
+ score: z
38
+ .number()
39
+ .int()
40
+ .min(0)
41
+ .describe("Score to submit (non-negative integer)"),
42
+ leaderboardKey: leaderboardKeySchema,
12
43
  },
13
- }, async ({ userId, score }) => {
44
+ }, async ({ userId, score, leaderboardKey }) => {
14
45
  const client = createApiClientFromEnv();
15
46
  if (!client)
16
47
  return noApiKeyResponse();
17
48
  try {
18
- const result = await client.post("/api/v1/app/leaderboard/submit", {
19
- userId,
20
- score,
21
- });
49
+ const path = leaderboardKey
50
+ ? `/api/v1/app/leaderboards/${encodeURIComponent(leaderboardKey)}/submit`
51
+ : "/api/v1/app/leaderboard/submit";
52
+ const result = await client.post(path, { userId, score });
22
53
  return jsonResponse(result);
23
54
  }
24
55
  catch (error) {
@@ -28,17 +59,24 @@ export function registerLeaderboardTools(server) {
28
59
  // --- Get leaderboard top ---
29
60
  server.registerTool("horizon_get_leaderboard_top", {
30
61
  title: "Get Leaderboard Top",
31
- description: "Gets the top entries from the horizOn leaderboard.",
62
+ description: "Gets the top entries from a horizOn leaderboard. Pass leaderboardKey to target a specific board.",
32
63
  inputSchema: {
33
64
  userId: z.string().uuid().describe("User ID (UUID)"),
34
- limit: z.number().int().min(1).max(100).default(10).describe("Number of top entries to return (1-100, default 10)"),
65
+ limit: z
66
+ .number()
67
+ .int()
68
+ .min(1)
69
+ .max(100)
70
+ .default(10)
71
+ .describe("Number of top entries to return (1-100, default 10)"),
72
+ leaderboardKey: leaderboardKeySchema,
35
73
  },
36
- }, async ({ userId, limit }) => {
74
+ }, async ({ userId, limit, leaderboardKey }) => {
37
75
  const client = createApiClientFromEnv();
38
76
  if (!client)
39
77
  return noApiKeyResponse();
40
78
  try {
41
- const result = await client.get("/api/v1/app/leaderboard/top", {
79
+ const result = await client.get(topPath(leaderboardKey), {
42
80
  userId,
43
81
  limit: String(limit),
44
82
  });
@@ -51,18 +89,17 @@ export function registerLeaderboardTools(server) {
51
89
  // --- Get user rank ---
52
90
  server.registerTool("horizon_get_user_rank", {
53
91
  title: "Get User Rank",
54
- description: "Gets the rank of a specific user on the horizOn leaderboard.",
92
+ description: "Gets the rank of a specific user on a horizOn leaderboard. Pass leaderboardKey to target a specific board.",
55
93
  inputSchema: {
56
94
  userId: z.string().uuid().describe("User ID (UUID)"),
95
+ leaderboardKey: leaderboardKeySchema,
57
96
  },
58
- }, async ({ userId }) => {
97
+ }, async ({ userId, leaderboardKey }) => {
59
98
  const client = createApiClientFromEnv();
60
99
  if (!client)
61
100
  return noApiKeyResponse();
62
101
  try {
63
- const result = await client.get("/api/v1/app/leaderboard/rank", {
64
- userId,
65
- });
102
+ const result = await client.get(rankPath(leaderboardKey), { userId });
66
103
  return jsonResponse(result);
67
104
  }
68
105
  catch (error) {
@@ -72,17 +109,24 @@ export function registerLeaderboardTools(server) {
72
109
  // --- Get leaderboard around user ---
73
110
  server.registerTool("horizon_get_leaderboard_around", {
74
111
  title: "Get Leaderboard Around User",
75
- description: "Gets leaderboard entries around a specific user's position on horizOn.",
112
+ description: "Gets leaderboard entries around a specific user's position on a horizOn leaderboard. Pass leaderboardKey to target a specific board.",
76
113
  inputSchema: {
77
114
  userId: z.string().uuid().describe("User ID (UUID)"),
78
- range: z.number().int().min(1).max(50).default(10).describe("Number of entries around the user (1-50, default 10)"),
115
+ range: z
116
+ .number()
117
+ .int()
118
+ .min(1)
119
+ .max(50)
120
+ .default(10)
121
+ .describe("Number of entries around the user (1-50, default 10)"),
122
+ leaderboardKey: leaderboardKeySchema,
79
123
  },
80
- }, async ({ userId, range }) => {
124
+ }, async ({ userId, range, leaderboardKey }) => {
81
125
  const client = createApiClientFromEnv();
82
126
  if (!client)
83
127
  return noApiKeyResponse();
84
128
  try {
85
- const result = await client.get("/api/v1/app/leaderboard/around", {
129
+ const result = await client.get(aroundPath(leaderboardKey), {
86
130
  userId,
87
131
  range: String(range),
88
132
  });
@@ -1 +1 @@
1
- {"version":3,"file":"leaderboard.js","sourceRoot":"","sources":["../../src/tools/leaderboard.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"leaderboard.js","sourceRoot":"","sources":["../../src/tools/leaderboard.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "horizon-mcp",
3
- "version": "1.3.1",
3
+ "version": "1.4.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",