gameye-mcp 0.1.3 → 0.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 CHANGED
@@ -30,7 +30,6 @@ The environment is a property of the server process. No tool takes an environmen
30
30
  | `GAMEYE_API_TOKEN` | **Yes** | — | Gameye API token. Use the least-privileged scopes you need (see below). |
31
31
  | `GAMEYE_ENV` | No | `sandbox` | `sandbox` or `production`. Selects the API host. |
32
32
  | `GAMEYE_API_URL` | No | — | Overrides the host, for testing only. Must be `https`. If it equals one of the two known hosts, it must match `GAMEYE_ENV` or the server refuses to start. Any other URL is labelled `custom` in every tool result. |
33
- | `GAMEYE_ENABLE_ADMIN_TOOLS` | No | unset | Set to `1` to register the admin tools (create or edit applications, create tokens). They stay off when this is unset. |
34
33
  | `GAMEYE_TIMEOUT_MS` | No | `30000` | Per-request timeout in milliseconds, a positive whole number. Log snapshots get at least 60 s and artifact downloads at least 120 s. A request that runs out of time comes back as a tool error: `Request to <host> timed out after <n>s`. |
35
34
 
36
35
  ## Install
@@ -64,7 +63,7 @@ Most clients (Claude Desktop, Cursor, Windsurf and others) accept an `mcpServers
64
63
 
65
64
  Restart the client after you change its configuration.
66
65
 
67
- `npx -y gameye-mcp` runs the latest release. To stay on one version, name it: `npx -y gameye-mcp@0.1.3` (or `"args": ["-y", "gameye-mcp@0.1.3"]`).
66
+ `npx -y gameye-mcp` runs the latest release. To stay on one version, name it: `npx -y gameye-mcp@0.2.0` (or `"args": ["-y", "gameye-mcp@0.2.0"]`).
68
67
 
69
68
  ### Docker
70
69
 
@@ -89,10 +88,10 @@ With Claude Code: `claude mcp add gameye --env GAMEYE_API_TOKEN=<your-token> --
89
88
 
90
89
  - Pass each variable with `-e NAME` (no value), so Docker copies it from the client's environment and the token never appears in the command line.
91
90
  - Keep `-i` and never add `-t`: a terminal mangles the JSON-RPC messages on stdout.
92
- - To stay on one version, use a version tag such as `ghcr.io/gameye/gameye-mcp:0.1.3`.
91
+ - To stay on one version, use a version tag such as `ghcr.io/gameye/gameye-mcp:0.2.0`.
93
92
  - Files the server writes stay inside the container, and `--rm` deletes them:
94
93
  - `gameye_get_artifacts` saves its download under the temp directory. To keep it, mount a directory and point the temp directory at it: `-v /absolute/dir:/out -e TMPDIR=/out`. The path the tool reports is the container path; the file is in `/absolute/dir` on the host.
95
- - `gameye_create_token` (admin tools only) writes to the `outputPath` you give it. Mount a directory the same way and pass an `outputPath` under `/out`.
94
+ - `gameye_create_token` writes to the `outputPath` you give it. Mount a directory the same way and pass an `outputPath` under `/out`.
96
95
  - The server runs as uid 1000, so on Linux the mounted directory must be writable by that user.
97
96
 
98
97
  ## Token scopes
@@ -103,7 +102,8 @@ Give the server a token with only the scopes it needs.
103
102
  |---|---|---|
104
103
  | Observer | `session:read` `logs:read` `artifact:read` `regions:read` `region:read` `application:read` | Inspect sessions, logs, artifacts, regions and applications. No changes. |
105
104
  | Operator | Observer + `session:start` `session:stop` `session:write` | Also launch and stop sessions and update session state. |
106
- | Admin tools | Operator + `application:write` `token:write` | Also create or edit applications and create tokens. Requires `GAMEYE_ENABLE_ADMIN_TOOLS=1`. |
105
+ | Deployer | Operator + `application:write` | Also create and edit applications, so the agent can set up a deployment end to end. |
106
+ | Token admin | Deployer + `token:write` | Also create API tokens. |
107
107
 
108
108
  **Never pass your Gameye API token into a game server's environment.** A game server doesn't need it, and anything inside the container can read it.
109
109
 
@@ -113,7 +113,7 @@ Every tool result starts with the environment and host it used, for example `[sa
113
113
 
114
114
  | Tool | Kind | Description |
115
115
  |---|---|---|
116
- | `gameye_context` | read | Show the environment, host and server version this server targets, whether admin tools are enabled, and the guardrail defaults (session TTL, `launched-by` label, token expiry) |
116
+ | `gameye_context` | read | Show the environment, host and server version this server targets, and the guardrail defaults (session TTL, `launched-by` label, token expiry) |
117
117
  | `gameye_launch_session` | write, `dryRun` | Start a containerized game server (billable). Default TTL and agent label applied; see [Guardrails](#guardrails) |
118
118
  | `gameye_list_sessions` | read | List running sessions (filterable; `all=true` for every status) |
119
119
  | `gameye_describe_session` | read | Get session details, ports and players |
@@ -128,9 +128,9 @@ Every tool result starts with the environment and host it used, for example `[sa
128
128
  | `gameye_enable_tag` | write, `dryRun` | Enable an image tag for an application so Gameye preloads it |
129
129
  | `gameye_get_logs` | read | Fetch session logs |
130
130
  | `gameye_get_artifacts` | read | Download a file or directory from a session container as a tar archive |
131
- | `gameye_create_application` | admin, `dryRun` | Create an application. Only with `GAMEYE_ENABLE_ADMIN_TOOLS=1` |
132
- | `gameye_edit_application` | admin, destructive, `dryRun` | Change an application; omitted fields stay unchanged. Only with `GAMEYE_ENABLE_ADMIN_TOOLS=1` |
133
- | `gameye_create_token` | admin, `dryRun` | Create an API token and write it to a file. Only with `GAMEYE_ENABLE_ADMIN_TOOLS=1` |
131
+ | `gameye_create_application` | write, `dryRun` | Create an application |
132
+ | `gameye_edit_application` | destructive, `dryRun` | Change an application; omitted fields stay unchanged |
133
+ | `gameye_create_token` | write, `dryRun` | Create an API token and write it to a file |
134
134
 
135
135
  Every tool carries MCP annotations: read tools set `readOnlyHint`, `gameye_stop_session` and `gameye_edit_application` set `destructiveHint`, and every tool that calls the Gameye API sets `openWorldHint`.
136
136
 
@@ -140,7 +140,7 @@ The tool set covers every operation in the Gameye client API. `tests/parity.test
140
140
 
141
141
  These behave the same on sandbox and production, because sandbox runs live matches for self-serve customers.
142
142
 
143
- - **Dry run.** `gameye_launch_session`, `gameye_stop_session`, `gameye_enable_tag` and the admin tools accept `dryRun: true`. The tool returns the exact request (method, host, path and body) with the API token masked, and sends nothing.
143
+ - **Dry run.** `gameye_launch_session`, `gameye_stop_session`, `gameye_enable_tag` and the application and token tools accept `dryRun: true`. The tool returns the exact request (method, host, path and body) with the API token masked, and sends nothing.
144
144
  - **Bounded sessions.** A launch without `ttl` gets a `30m` TTL, and the result says the default was applied. Every launch sends the label `launched-by: gameye-mcp`, replacing any `launched-by` value the caller passes, so agent-launched sessions can be found with `gameye_list_sessions` and `filter: { "launched-by": "gameye-mcp" }`. When a warm pool serves the image and region, the Gameye API ignores request labels (and env and args), so warm-pool sessions do not carry this label.
145
145
  - **No token in game servers.** A launch is refused, with nothing sent, if any env value or name, arg, or label key or value contains this server's Gameye API token. Env values are never shown in results.
146
146
  - **No token in results.** Every tool result, including errors, has this server's API token replaced with `***`, in case log output, labels or an error message echo it.
@@ -150,9 +150,9 @@ These behave the same on sandbox and production, because sandbox runs live match
150
150
 
151
151
  Every request to the Gameye API sends `User-Agent: gameye-mcp/<version>`, plus the MCP client's name once it has connected, e.g. `gameye-mcp/0.1.0 (claude-code)`, so Gameye can count MCP usage. Only this server's version and the client name are sent, nothing else: no token, env values, paths or other data. There is no other telemetry.
152
152
 
153
- ## Admin tools
153
+ ## Application and token tools
154
154
 
155
- `gameye_create_application`, `gameye_edit_application` and `gameye_create_token` are registered only when the server starts with `GAMEYE_ENABLE_ADMIN_TOOLS=1`. Without it, they don't appear in the tool list at all. They need a token with `application:write` or `token:write`.
155
+ `gameye_create_application`, `gameye_edit_application` and `gameye_create_token` are always registered. What the agent can actually do is set by the token's scopes: they need `application:write` or `token:write`, and a token without them gets a 403 naming the missing scope. To keep an agent from changing applications or minting tokens, give it a token without those scopes.
156
156
 
157
157
  `gameye_create_token` never returns the new token. It writes the token to the file you name in `outputPath` and returns only the path, the scopes and the expiry:
158
158
 
@@ -185,6 +185,14 @@ npm run build
185
185
 
186
186
  `spec/client.yaml` is a snapshot of the public sandbox `/openapi.yaml`, and `spec/overrides.yaml` holds the MCP tool name for each operation: the `tools:` map from [gameye-skills](https://github.com/gameye/gameye-skills)' `spec/overrides.yaml`, reduced by `scripts/reduce-overrides.mjs` (gameye-skills keeps the full file, which records where the server differs from the spec). Refresh both with `npm run sync-spec [path-or-url-to-overrides.yaml]`. `npm run check-spec` exits 1 when either snapshot has drifted.
187
187
 
188
+ ## About Gameye
189
+
190
+ [Gameye](https://gameye.com/?utm_source=github&utm_medium=readme&utm_campaign=gameye-mcp) is a managed hosting platform for multiplayer game servers. You bring a container image, and Gameye starts a dedicated server for each match through one API.
191
+
192
+ - Session API docs: [gameye.com/docs/api-v2](https://gameye.com/docs/api-v2/?utm_source=github&utm_medium=readme&utm_campaign=gameye-mcp)
193
+ - Gameye docs: [gameye.com/docs](https://gameye.com/docs/?utm_source=github&utm_medium=readme&utm_campaign=gameye-mcp)
194
+ - Try it free: [trial.gameye.com](https://trial.gameye.com/?utm_source=github&utm_medium=readme&utm_campaign=gameye-mcp)
195
+
188
196
  ## Security
189
197
 
190
198
  Please report vulnerabilities privately. See [SECURITY.md](SECURITY.md).
package/dist/env.d.ts CHANGED
@@ -34,9 +34,3 @@ export declare function resultPrefix(config: {
34
34
  environment: EnvironmentLabel;
35
35
  host: string;
36
36
  }): string;
37
- /**
38
- * Admin tools (create/edit application, create token) register only when
39
- * GAMEYE_ENABLE_ADMIN_TOOLS is exactly `1`, so credential- and config-changing
40
- * tools are invisible unless the operator opts in.
41
- */
42
- export declare function adminToolsEnabled(env: Record<string, string | undefined>): boolean;
package/dist/env.js CHANGED
@@ -112,11 +112,3 @@ export function loadConfigOrExit(env = process.env) {
112
112
  export function resultPrefix(config) {
113
113
  return `[${config.environment} · ${config.host}]`;
114
114
  }
115
- /**
116
- * Admin tools (create/edit application, create token) register only when
117
- * GAMEYE_ENABLE_ADMIN_TOOLS is exactly `1`, so credential- and config-changing
118
- * tools are invisible unless the operator opts in.
119
- */
120
- export function adminToolsEnabled(env) {
121
- return env.GAMEYE_ENABLE_ADMIN_TOOLS?.trim() === "1";
122
- }
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
3
  import { GameyeClient } from "./client.js";
4
- import { adminToolsEnabled, loadConfigOrExit } from "./env.js";
4
+ import { loadConfigOrExit } from "./env.js";
5
5
  import { registerAllTools } from "./tools/register.js";
6
6
  import { createServer } from "./server.js";
7
7
  import { BETA_NOTICE } from "./beta.js";
@@ -16,11 +16,10 @@ const ctx = {
16
16
  mask: (text) => client.maskToken(text),
17
17
  };
18
18
  const server = createServer(version);
19
- const admin = adminToolsEnabled(process.env);
20
- registerAllTools(server, client, ctx, { admin });
19
+ registerAllTools(server, client, ctx);
21
20
  // Attribute API traffic to the MCP client (name only) once it has introduced itself.
22
21
  server.server.oninitialized = () => client.setClientName(server.server.getClientVersion()?.name);
23
22
  const transport = new StdioServerTransport();
24
23
  await server.connect(transport);
25
- console.error(`Gameye MCP server ${version} running on stdio [${ctx.environment} · ${ctx.host}]${admin ? " with admin tools enabled" : ""}`);
24
+ console.error(`Gameye MCP server ${version} running on stdio [${ctx.environment} · ${ctx.host}]`);
26
25
  console.error(BETA_NOTICE);
@@ -1,4 +1,4 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { GameyeClient } from "../client.js";
3
- import { type RegisterOptions, type ServerContext } from "./common.js";
4
- export declare function registerApplicationTools(server: McpServer, client: GameyeClient, ctx: ServerContext, opts: RegisterOptions): void;
3
+ import { type ServerContext } from "./common.js";
4
+ export declare function registerApplicationTools(server: McpServer, client: GameyeClient, ctx: ServerContext): void;
@@ -49,7 +49,7 @@ function formatApplication(a) {
49
49
  ` ports: ${formatPortBindings(a.ports) || "(none)"}`,
50
50
  ].join("\n");
51
51
  }
52
- export function registerApplicationTools(server, client, ctx, opts) {
52
+ export function registerApplicationTools(server, client, ctx) {
53
53
  // ─── List applications ───────────────────────────────────────────────────────
54
54
  defineTool(server, ctx, "gameye_list_applications", {
55
55
  title: "List applications",
@@ -97,9 +97,7 @@ export function registerApplicationTools(server, client, ctx, opts) {
97
97
  await client.enableTag(name, tag);
98
98
  return `Tag ${tag} enabled for ${name}. Preloading can take a while; use gameye_check_tag to confirm it is available in a region.`;
99
99
  });
100
- if (!opts.admin)
101
- return;
102
- // ─── Create application (admin) ──────────────────────────────────────────────
100
+ // ─── Create application ──────────────────────────────────────────────────────
103
101
  defineTool(server, ctx, "gameye_create_application", {
104
102
  title: "Create application",
105
103
  description: "Admin tool. Create a new application (an image Gameye can run). " +
@@ -117,7 +115,7 @@ export function registerApplicationTools(server, client, ctx, opts) {
117
115
  await client.createApplication(body);
118
116
  return `Application ${body.name} created.`;
119
117
  });
120
- // ─── Edit application (admin) ────────────────────────────────────────────────
118
+ // ─── Edit application ────────────────────────────────────────────────────────
121
119
  defineTool(server, ctx, "gameye_edit_application", {
122
120
  title: "Edit application",
123
121
  description: "Admin tool. Change an existing application with PUT /application/{name}. Fields you omit stay unchanged; regions and ports, when given, replace the whole list. " +
@@ -5,11 +5,6 @@ import { GameyeError } from "../client.js";
5
5
  import { type EnvironmentLabel } from "../env.js";
6
6
  /** Shared `dryRun` input for every tool that sends a write. */
7
7
  export declare const dryRunInput: z.ZodOptional<z.ZodBoolean>;
8
- /** Tool registration options. Admin tools only when GAMEYE_ENABLE_ADMIN_TOOLS=1. */
9
- export interface RegisterOptions {
10
- /** Register admin tools (create/edit application, create token). */
11
- admin: boolean;
12
- }
13
8
  /** What every tool needs to know about the server it runs in. Never holds the token. */
14
9
  export interface ServerContext {
15
10
  environment: EnvironmentLabel;
@@ -1,3 +1,3 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- import { type RegisterOptions, type ServerContext } from "./common.js";
3
- export declare function registerContextTool(server: McpServer, ctx: ServerContext, opts: RegisterOptions): void;
2
+ import { type ServerContext } from "./common.js";
3
+ export declare function registerContextTool(server: McpServer, ctx: ServerContext): void;
@@ -1,10 +1,10 @@
1
1
  import { AGENT_LABEL_KEY, AGENT_LABEL_VALUE, DEFAULT_SESSION_TTL, DEFAULT_TOKEN_EXPIRY } from "../guards.js";
2
2
  import { defineTool } from "./common.js";
3
3
  import { BETA_NOTICE } from "../beta.js";
4
- export function registerContextTool(server, ctx, opts) {
4
+ export function registerContextTool(server, ctx) {
5
5
  defineTool(server, ctx, "gameye_context", {
6
6
  title: "Server context",
7
- description: "Show which Gameye environment and host this server targets, the server version, whether admin tools are enabled, and the guardrail defaults. The environment is fixed when the server starts (GAMEYE_ENV / GAMEYE_API_URL) and cannot be changed by a tool call.",
7
+ description: "Show which Gameye environment and host this server targets, the server version and the guardrail defaults. The environment is fixed when the server starts (GAMEYE_ENV / GAMEYE_API_URL) and cannot be changed by a tool call.",
8
8
  inputSchema: {},
9
9
  annotations: { readOnlyHint: true, openWorldHint: false },
10
10
  }, async () => [
@@ -13,7 +13,6 @@ export function registerContextTool(server, ctx, opts) {
13
13
  `Host: ${ctx.host}`,
14
14
  `Base URL: ${ctx.baseUrl}`,
15
15
  `Server version: gameye-mcp ${ctx.version}`,
16
- `Admin tools: ${opts.admin ? "enabled" : "disabled (set GAMEYE_ENABLE_ADMIN_TOOLS=1 to enable)"}`,
17
16
  "",
18
17
  "Guardrail defaults:",
19
18
  ` Session TTL: ${DEFAULT_SESSION_TTL} when a launch gives no ttl`,
@@ -1,6 +1,5 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import type { GameyeClient } from "../client.js";
3
- import type { RegisterOptions, ServerContext } from "./common.js";
4
- export type { RegisterOptions };
5
- /** Register every tool. Admin tools only when `opts.admin` is true. */
6
- export declare function registerAllTools(server: McpServer, client: GameyeClient, ctx: ServerContext, opts: RegisterOptions): void;
3
+ import type { ServerContext } from "./common.js";
4
+ /** Register every tool. */
5
+ export declare function registerAllTools(server: McpServer, client: GameyeClient, ctx: ServerContext): void;
@@ -8,17 +8,16 @@ import { registerApplicationTools } from "./applications.js";
8
8
  import { registerTokenTools } from "./tokens.js";
9
9
  import { registerLogTools } from "./logs.js";
10
10
  import { registerArtifactTools } from "./artifacts.js";
11
- /** Register every tool. Admin tools only when `opts.admin` is true. */
12
- export function registerAllTools(server, client, ctx, opts) {
13
- registerContextTool(server, ctx, opts);
11
+ /** Register every tool. */
12
+ export function registerAllTools(server, client, ctx) {
13
+ registerContextTool(server, ctx);
14
14
  registerSessionTools(server, client, ctx);
15
15
  registerPlayerTools(server, client, ctx);
16
16
  registerLocationTools(server, client, ctx);
17
17
  registerRegionTools(server, client, ctx);
18
18
  registerTagTools(server, client, ctx);
19
- registerApplicationTools(server, client, ctx, opts);
19
+ registerApplicationTools(server, client, ctx);
20
20
  registerLogTools(server, client, ctx);
21
21
  registerArtifactTools(server, client, ctx);
22
- if (opts.admin)
23
- registerTokenTools(server, client, ctx);
22
+ registerTokenTools(server, client, ctx);
24
23
  }
@@ -1,5 +1,4 @@
1
1
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { GameyeClient } from "../client.js";
3
3
  import { type ServerContext } from "./common.js";
4
- /** Admin tool. Register only when GAMEYE_ENABLE_ADMIN_TOOLS=1. */
5
4
  export declare function registerTokenTools(server: McpServer, client: GameyeClient, ctx: ServerContext): void;
@@ -2,7 +2,6 @@ import { z } from "zod";
2
2
  import { GameyeClient } from "../client.js";
3
3
  import { DEFAULT_TOKEN_EXPIRY, GuardError, checkTokenOutputPath, formatDryRun, reserveTokenFile } from "../guards.js";
4
4
  import { defineTool } from "./common.js";
5
- /** Admin tool. Register only when GAMEYE_ENABLE_ADMIN_TOOLS=1. */
6
5
  export function registerTokenTools(server, client, ctx) {
7
6
  defineTool(server, ctx, "gameye_create_token", {
8
7
  title: "Create API token",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gameye-mcp",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "mcpName": "io.github.Gameye/gameye-mcp",
5
5
  "description": "MCP server for the Gameye game server orchestration API: launch and inspect sessions, check image tags, fetch logs and artifacts from any MCP client",
6
6
  "main": "dist/index.js",