gameye-mcp 0.3.1 → 0.3.2
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 +6 -3
- package/dist/skills.d.ts +8 -0
- package/dist/skills.js +31 -4
- package/dist/tools/skills.js +12 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Gameye MCP Server
|
|
2
2
|
|
|
3
|
+
[](https://discord.com/invite/QvJ3KH5max)
|
|
4
|
+
|
|
3
5
|
A [Model Context Protocol](https://modelcontextprotocol.io) server for the [Gameye](https://gameye.com) game server orchestration API. It lets an AI agent (Claude Code, Claude Desktop, Cursor, or any MCP client) launch and inspect game server sessions, check image tags and regions, and fetch logs and artifacts. You talk to it in plain language, and you don't have to leave your editor.
|
|
4
6
|
|
|
5
7
|
> **Status: beta** (`0.x`). Tools, inputs and outputs may change between releases, and there may be bugs. The server says so to every client that connects, on startup, and in `gameye_context`. It is published on npm as [`gameye-mcp`](https://www.npmjs.com/package/gameye-mcp), as a container image at `ghcr.io/gameye/gameye-mcp`, and in the [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.Gameye/gameye-mcp`; see the [changelog](https://github.com/Gameye/gameye-mcp/blob/main/CHANGELOG.md) for what changed in each release.
|
|
@@ -30,6 +32,7 @@ The environment is a property of the server process. No tool takes an environmen
|
|
|
30
32
|
| `GAMEYE_API_TOKEN` | **Yes** | — | Gameye API token. Use the least-privileged scopes you need (see below). |
|
|
31
33
|
| `GAMEYE_ENV` | No | `sandbox` | `sandbox` or `production`. Selects the API host. |
|
|
32
34
|
| `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. |
|
|
35
|
+
| `GAMEYE_ENABLE_SKILLS_UPDATE` | No | — | Set to `1` to let `gameye_update_skills` run the skills updaters with `apply: true`. Without it the tool only checks and lists the commands. |
|
|
33
36
|
| `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`. |
|
|
34
37
|
|
|
35
38
|
## Install
|
|
@@ -63,7 +66,7 @@ Most clients (Claude Desktop, Cursor, Windsurf and others) accept an `mcpServers
|
|
|
63
66
|
|
|
64
67
|
Restart the client after you change its configuration.
|
|
65
68
|
|
|
66
|
-
`npx -y gameye-mcp` runs the latest release. To stay on one version, name it: `npx -y gameye-mcp@0.3.
|
|
69
|
+
`npx -y gameye-mcp` runs the latest release. To stay on one version, name it: `npx -y gameye-mcp@0.3.2` (or `"args": ["-y", "gameye-mcp@0.3.2"]`).
|
|
67
70
|
|
|
68
71
|
### Windows
|
|
69
72
|
|
|
@@ -105,7 +108,7 @@ With Claude Code: `claude mcp add gameye --env GAMEYE_API_TOKEN=<your-token> --
|
|
|
105
108
|
|
|
106
109
|
- 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.
|
|
107
110
|
- Keep `-i` and never add `-t`: a terminal mangles the JSON-RPC messages on stdout.
|
|
108
|
-
- To stay on one version, use a version tag such as `ghcr.io/gameye/gameye-mcp:0.3.
|
|
111
|
+
- To stay on one version, use a version tag such as `ghcr.io/gameye/gameye-mcp:0.3.2`.
|
|
109
112
|
- Files the server writes stay inside the container, and `--rm` deletes them:
|
|
110
113
|
- `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.
|
|
111
114
|
- `gameye_create_token` writes to the `outputPath` you give it. Mount a directory the same way and pass an `outputPath` under `/out`.
|
|
@@ -172,7 +175,7 @@ The [Gameye skills](https://github.com/gameye/gameye-skills) change as the Gamey
|
|
|
172
175
|
- **skills CLI, this project:** the same, in `skills-lock.json` in the server's working directory.
|
|
173
176
|
- **Claude Code plugin:** `gameye@gameye` in `~/.claude/plugins/installed_plugins.json`.
|
|
174
177
|
|
|
175
|
-
Without `apply` it only reports. With `apply: true` it runs each outdated install's own updater: `npx -y skills update <the Gameye skills> -g -y` (or `-p -y`), or `claude plugin marketplace update gameye` then `claude plugin update gameye@gameye`. It only updates skills whose lock-file source is `gameye/gameye-skills`, and it never downloads or follows skill text itself. Each command runs with stdin closed and a 90-second limit. On Windows it prints the commands instead of running them. The running agent session keeps the skills it loaded; the next session uses the update. The `gameye` skill tells agents to run the check once per conversation and ask before applying.
|
|
178
|
+
Without `apply` it only reports. With `apply: true`, and only when the server was started with `GAMEYE_ENABLE_SKILLS_UPDATE=1`, it runs each outdated install's own updater: `npx -y skills@1.7.4 update <the Gameye skills> -g -y` (or `-p -y`), or `claude plugin marketplace update gameye` then `claude plugin update gameye@gameye`. Otherwise it lists those commands for you to run. The updaters get a minimal environment: paths, home, temp, locale, proxy and CA settings and npm and Claude config, never `GAMEYE_*` variables or anything named like a token, secret, password or key. It only updates skills whose lock-file source is `gameye/gameye-skills`, and it never downloads or follows skill text itself. Each command runs with stdin closed and a 90-second limit. On Windows it prints the commands instead of running them. The running agent session keeps the skills it loaded; the next session uses the update. The `gameye` skill tells agents to run the check once per conversation and ask before applying.
|
|
176
179
|
|
|
177
180
|
## Telemetry/attribution
|
|
178
181
|
|
package/dist/skills.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
/** Where the `gameye` skill's `Pack version:` line is published. */
|
|
2
2
|
export declare const LATEST_PACK_URL = "https://raw.githubusercontent.com/Gameye/gameye-skills/main/skills/gameye/SKILL.md";
|
|
3
|
+
/** The skills CLI the updater runs, pinned so `npx` never fetches whatever is newest. */
|
|
4
|
+
export declare const SKILLS_CLI = "skills@1.7.4";
|
|
5
|
+
/** Set to 1 to let `gameye_update_skills` run updaters; otherwise apply prints the commands. */
|
|
6
|
+
export declare const ENABLE_UPDATE_ENV = "GAMEYE_ENABLE_SKILLS_UPDATE";
|
|
7
|
+
/** The environment an updater runs with: the allowlist above, no Gameye variables, nothing that looks like a secret. */
|
|
8
|
+
export declare function childEnv(parent: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
3
9
|
/** How the Gameye skills were installed. Each kind updates differently. */
|
|
4
10
|
export type InstallKind = "skills-cli-global" | "skills-cli-project" | "claude-plugin";
|
|
5
11
|
export interface SkillsInstall {
|
|
@@ -14,6 +20,8 @@ export interface SkillsEnv {
|
|
|
14
20
|
home: string;
|
|
15
21
|
cwd: string;
|
|
16
22
|
platform: NodeJS.Platform;
|
|
23
|
+
/** The operator set GAMEYE_ENABLE_SKILLS_UPDATE=1: apply may run updaters. */
|
|
24
|
+
applyEnabled: boolean;
|
|
17
25
|
readText: (path: string) => Promise<string | undefined>;
|
|
18
26
|
fetchText: (url: string) => Promise<string>;
|
|
19
27
|
run: (cmd: string, args: string[], cwd: string) => Promise<string>;
|
package/dist/skills.js
CHANGED
|
@@ -8,11 +8,39 @@ const PACK_VERSION_RE = /^Pack version: (\d+\.\d+\.\d+)[ \t]*$/m;
|
|
|
8
8
|
const SKILLS_SOURCE_RE = /^(https:\/\/github\.com\/|git@github\.com:|github:)?gameye\/gameye-skills(\.git)?\/?$/i;
|
|
9
9
|
// Lock files can come from a cloned project, so a name must look like a skill name, never a CLI option.
|
|
10
10
|
const SKILL_NAME_RE = /^[a-z0-9][a-z0-9._-]{0,63}$/i;
|
|
11
|
+
/** The skills CLI the updater runs, pinned so `npx` never fetches whatever is newest. */
|
|
12
|
+
export const SKILLS_CLI = "skills@1.7.4";
|
|
13
|
+
/** Set to 1 to let `gameye_update_skills` run updaters; otherwise apply prints the commands. */
|
|
14
|
+
export const ENABLE_UPDATE_ENV = "GAMEYE_ENABLE_SKILLS_UPDATE";
|
|
15
|
+
// What an updater needs from the parent: where to find programs and home, temp dirs, locale,
|
|
16
|
+
// proxy and CA settings, npm and Claude config. Nothing else is passed, so the Gameye token stays here.
|
|
17
|
+
const CHILD_ENV_NAMES = new Set([
|
|
18
|
+
"PATH", "Path", "PATHEXT", "HOME", "USERPROFILE", "APPDATA", "LOCALAPPDATA", "HOMEDRIVE", "HOMEPATH",
|
|
19
|
+
"SystemRoot", "SYSTEMROOT", "ComSpec", "COMSPEC", "WINDIR", "TEMP", "TMP", "TMPDIR",
|
|
20
|
+
"USER", "LOGNAME", "SHELL", "LANG", "LC_ALL", "TERM",
|
|
21
|
+
"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY", "http_proxy", "https_proxy", "no_proxy",
|
|
22
|
+
"NODE_EXTRA_CA_CERTS", "SSL_CERT_FILE", "SSL_CERT_DIR", "CLAUDE_CONFIG_DIR",
|
|
23
|
+
]);
|
|
24
|
+
const CHILD_ENV_PREFIXES = ["XDG_", "npm_config_", "NPM_CONFIG_"];
|
|
25
|
+
// Never passed, even under an allowed prefix: an npm registry token is not the updater's business either.
|
|
26
|
+
const SECRET_NAME_RE = /token|secret|password|passwd|auth|key|credential/i;
|
|
27
|
+
/** The environment an updater runs with: the allowlist above, no Gameye variables, nothing that looks like a secret. */
|
|
28
|
+
export function childEnv(parent) {
|
|
29
|
+
const env = {};
|
|
30
|
+
for (const [name, value] of Object.entries(parent)) {
|
|
31
|
+
if (value === undefined || name.toUpperCase().startsWith("GAMEYE_") || SECRET_NAME_RE.test(name))
|
|
32
|
+
continue;
|
|
33
|
+
if (CHILD_ENV_NAMES.has(name) || CHILD_ENV_PREFIXES.some((p) => name.startsWith(p)))
|
|
34
|
+
env[name] = value;
|
|
35
|
+
}
|
|
36
|
+
return { ...env, NO_COLOR: "1", FORCE_COLOR: "0", CI: "1" };
|
|
37
|
+
}
|
|
11
38
|
export function defaultSkillsEnv() {
|
|
12
39
|
return {
|
|
13
40
|
home: homedir(),
|
|
14
41
|
cwd: process.cwd(),
|
|
15
42
|
platform: process.platform,
|
|
43
|
+
applyEnabled: process.env[ENABLE_UPDATE_ENV] === "1",
|
|
16
44
|
readText: (path) => readFile(path, "utf8").catch(() => undefined),
|
|
17
45
|
fetchText: async (url) => {
|
|
18
46
|
const res = await fetch(url, { signal: AbortSignal.timeout(5_000) });
|
|
@@ -21,8 +49,7 @@ export function defaultSkillsEnv() {
|
|
|
21
49
|
return res.text();
|
|
22
50
|
},
|
|
23
51
|
run: (cmd, args, cwd) => new Promise((resolve, reject) => {
|
|
24
|
-
const
|
|
25
|
-
const options = { cwd, env: childEnv, timeout: 90_000, killSignal: "SIGKILL", maxBuffer: 4 * 1024 * 1024 };
|
|
52
|
+
const options = { cwd, env: childEnv(process.env), timeout: 90_000, killSignal: "SIGKILL", maxBuffer: 4 * 1024 * 1024 };
|
|
26
53
|
const child = execFile(cmd, args, options, (err, stdout, stderr) => {
|
|
27
54
|
const out = stripAnsi(`${stdout}${stderr}`).trim();
|
|
28
55
|
if (err)
|
|
@@ -120,9 +147,9 @@ export function isOutdated(install, latest) {
|
|
|
120
147
|
export function updateCommands(install) {
|
|
121
148
|
switch (install.kind) {
|
|
122
149
|
case "skills-cli-global":
|
|
123
|
-
return [["npx", "-y",
|
|
150
|
+
return [["npx", "-y", SKILLS_CLI, "update", ...install.skills, "-g", "-y"]];
|
|
124
151
|
case "skills-cli-project":
|
|
125
|
-
return [["npx", "-y",
|
|
152
|
+
return [["npx", "-y", SKILLS_CLI, "update", ...install.skills, "-p", "-y"]];
|
|
126
153
|
case "claude-plugin":
|
|
127
154
|
return [
|
|
128
155
|
["claude", "plugin", "marketplace", "update", "gameye"],
|
package/dist/tools/skills.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { defineTool } from "./common.js";
|
|
3
|
-
import { compareVersions, defaultSkillsEnv, describeInstall, fetchLatestPackVersion, findSkillsInstalls, isOutdated, updateCommands, } from "../skills.js";
|
|
3
|
+
import { compareVersions, defaultSkillsEnv, describeInstall, ENABLE_UPDATE_ENV, fetchLatestPackVersion, findSkillsInstalls, isOutdated, updateCommands, } from "../skills.js";
|
|
4
4
|
const RELOAD_NOTE = "The running session keeps the skills it already loaded. Start a new session (in Claude Code, /reload-plugins also works for the plugin) to use the update.";
|
|
5
5
|
export function registerSkillsTools(server, ctx, env = defaultSkillsEnv()) {
|
|
6
6
|
defineTool(server, ctx, "gameye_update_skills", {
|
|
@@ -8,7 +8,8 @@ export function registerSkillsTools(server, ctx, env = defaultSkillsEnv()) {
|
|
|
8
8
|
description: "Compare the installed Gameye agent skills with the latest pack on GitHub, and update them. " +
|
|
9
9
|
"Finds installs made with the skills CLI (user-wide or in this project) and the Claude Code plugin gameye@gameye. " +
|
|
10
10
|
"Without apply it only checks and changes nothing. With apply=true it runs each outdated install's own updater " +
|
|
11
|
-
"(npx skills update for the Gameye skills only, or claude plugin update)
|
|
11
|
+
"(npx skills update for the Gameye skills only, or claude plugin update) when the operator set " +
|
|
12
|
+
`${ENABLE_UPDATE_ENV}=1; otherwise it lists the commands for the user to run. Ask the user before applying. ` +
|
|
12
13
|
"Updates come only through those package managers; this tool never downloads or follows skill text itself.",
|
|
13
14
|
inputSchema: {
|
|
14
15
|
apply: z
|
|
@@ -56,8 +57,15 @@ export function registerSkillsTools(server, ctx, env = defaultSkillsEnv()) {
|
|
|
56
57
|
if (outdated.length === 0)
|
|
57
58
|
return lines.join("\n");
|
|
58
59
|
const commands = outdated.flatMap(updateCommands);
|
|
59
|
-
if (!apply || env.platform === "win32") {
|
|
60
|
-
|
|
60
|
+
if (!apply || env.platform === "win32" || !env.applyEnabled) {
|
|
61
|
+
const why = !apply
|
|
62
|
+
? env.applyEnabled
|
|
63
|
+
? "Call again with apply=true to run:"
|
|
64
|
+
: "Run:"
|
|
65
|
+
: env.platform === "win32"
|
|
66
|
+
? "Updating from this server isn't supported on Windows. Run:"
|
|
67
|
+
: `Updating from this server is off (set ${ENABLE_UPDATE_ENV}=1 in the server's environment to allow it). Run:`;
|
|
68
|
+
lines.push("", why);
|
|
61
69
|
for (const cmd of commands)
|
|
62
70
|
lines.push(` ${cmd.join(" ")}`);
|
|
63
71
|
return lines.join("\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gameye-mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
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",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"type": "module",
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
51
|
+
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
52
52
|
"zod": "^4.3.6"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|