@chessceo/mcp 0.49.2 → 0.49.4

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
@@ -6,7 +6,7 @@ Player/game lookups need no API key or auth. Cloud engines and prep-file tools n
6
6
 
7
7
  ## What it can do
8
8
 
9
- 50 tools as of v0.49.2, mirroring the `chess.ceo` API surface. A few of the most-used:
9
+ 51 tools as of v0.49.3, mirroring the `chess.ceo` API surface. A few of the most-used:
10
10
 
11
11
  | Tool | What it answers |
12
12
  |---|---|
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ import { getNodeByPath, resolveFromNodeOrFen, storeEvalOnNode, } from "./analysi
29
29
  import { findPositionInCourses, readCourseAtPosition, runSfEval } from "./courses.js";
30
30
  import { applyBatchMutations, applyMutation, argNodeId, } from "./prep/mutations.js";
31
31
  import { listNodes, listTranspositions, readPrepFile, } from "./prep/read.js";
32
- import { createCollection, createPrepFile, findPositionInFiles, listCollections, listPrepFiles, renameCollection, searchPrepFiles, } from "./prep/library.js";
32
+ import { createCollection, createPrepFile, findPositionInFiles, listCollections, listPrepFiles, renameCollection, searchPrepFiles, setCollectionFolder, } from "./prep/library.js";
33
33
  import { convertAvailableMovesToSAN, normalizeSourceForBackend, stripPositionResponse, trimGamesMovetext, } from "./response_transforms.js";
34
34
  // Tools that require an MCP token — cloud engine + prep-file tools
35
35
  // operate on the caller's own account so we can't service them
@@ -44,6 +44,7 @@ const AUTHED_TOOLS = new Set([
44
44
  "list_collections",
45
45
  "create_collection",
46
46
  "rename_collection",
47
+ "set_collection_folder",
47
48
  "list_prep_files",
48
49
  "search_prep_files",
49
50
  "find_position_in_files",
@@ -371,6 +372,7 @@ async function callToolInner(name, args) {
371
372
  case "start_cloud_engine":
372
373
  return authedRequest("POST", "/api/agent/cloud-engines", {
373
374
  machineType: String(args.machine_type),
375
+ ...(typeof args.engine_type === "string" ? { engineType: args.engine_type } : {}),
374
376
  });
375
377
  case "list_cloud_engines":
376
378
  return authedRequest("GET", "/api/agent/cloud-engines");
@@ -443,6 +445,8 @@ async function callToolInner(name, args) {
443
445
  return createCollection(args);
444
446
  case "rename_collection":
445
447
  return renameCollection(args);
448
+ case "set_collection_folder":
449
+ return setCollectionFolder(args);
446
450
  case "list_prep_files":
447
451
  return listPrepFiles(args);
448
452
  case "search_prep_files":
@@ -102,6 +102,18 @@ export async function renameCollection(args) {
102
102
  const collection = unwrap(raw);
103
103
  return { ok: true, id: collection.id, title: collection.title };
104
104
  }
105
+ export async function setCollectionFolder(args) {
106
+ const id = typeof args.id === "string" ? args.id.trim() : "";
107
+ if (!id)
108
+ throw new Error("id is required");
109
+ if (typeof args.folder_path !== "string") {
110
+ throw new Error("folder_path is required (pass an empty string to move the collection to root)");
111
+ }
112
+ const folderPath = args.folder_path.trim();
113
+ const raw = await authedRequest("PUT", `${PGN_BASE}/${encodeURIComponent(id)}`, { folderPath });
114
+ const collection = unwrap(raw);
115
+ return { ok: true, id: collection.id, folder_path: collection.folderPath };
116
+ }
105
117
  export async function createPrepFile(args) {
106
118
  const collectionId = typeof args.collection_id === "string" ? args.collection_id.trim() : "";
107
119
  if (!collectionId) {
package/dist/tools.js CHANGED
@@ -258,20 +258,25 @@ export const TOOLS = [
258
258
  },
259
259
  {
260
260
  name: "list_cloud_machine_options",
261
- description: "Returns the catalog of combo cloud-engine machine types the user can start (SKU, human display name, cost per hour, availability). ALWAYS call this before start_cloud_engine — SKU strings like 'rtx-5090-64' do not match the display names ('Stockfish 32 CPUs + Lc0 1× RTX 5090') and are NOT guessable. Present the user the display names + prices; pass the SKU to start_cloud_engine.",
261
+ description: "Returns the catalog of cloud-engine machine types the user can start — every engine shape (stockfish-only, lc0-only, and combo) they're entitled to, same visibility rules as the chess.ceo app (SKU, which engine(s) it runs, human display name, cost per hour, availability). ALWAYS call this before start_cloud_engine — SKU strings like 'rtx-5090-64' do not match the display names ('Stockfish 32 CPUs + Lc0 1× RTX 5090') and are NOT guessable, and a given SKU only supports the engine(s) shown in its `engine` field (a stockfish-only SKU cannot be started as lc0 or combo). Present the user the display names + prices; pass the SKU to start_cloud_engine.",
262
262
  inputSchema: { type: "object", properties: {} },
263
263
  },
264
264
  {
265
265
  name: "start_cloud_engine",
266
- description: "Rent a combo GPU instance (Stockfish + Lc0 in the same container) on the user's chess.ceo account. Real money — billed per second while running.\n\n" +
267
- "CRITICAL: `machine_type` must be an exact SKU from `list_cloud_machine_options` (e.g. 'rtx-5090-64', NOT 'rtx-5090'). Guessing SKUs will fail. Call list_cloud_machine_options first, show the user the display names + prices, get their confirmation, then pass the SKU here.\n\n" +
268
- "Use list_cloud_engines first to check if the user already has one running; don't start a second combo unless the user asked for it. Requires an MCP token with agent access.",
266
+ description: "Rent a GPU/CPU instance on the user's chess.ceo account — stockfish-only, lc0-only, or combo (both in one container), whichever the chosen SKU provides. Real money — billed per second while running.\n\n" +
267
+ "CRITICAL: `machine_type` must be an exact SKU from `list_cloud_machine_options` (e.g. 'rtx-5090-64', NOT 'rtx-5090'). Guessing SKUs will fail. Call list_cloud_machine_options first, show the user the display names + prices, get their confirmation, then pass the SKU here. `engine_type` must match what that SKU actually provides (its `engine` field from the catalog) — omit it to default to whatever the SKU is (a combo SKU defaults to \"combo\").\n\n" +
268
+ "Use list_cloud_engines first to check if the user already has one running; don't start a second instance unless the user asked for it. Requires an MCP token with agent access.",
269
269
  inputSchema: {
270
270
  type: "object",
271
271
  properties: {
272
272
  machine_type: {
273
273
  type: "string",
274
- description: "SKU from list_cloud_machine_options (e.g. 'rtx-5090-64', 'rtx-5090-dual-64'). MUST be the exact SKU, not the display name and not a guess.",
274
+ description: "SKU from list_cloud_machine_options (e.g. 'rtx-5090-64', 'rtx-5090', 'epyc-256'). MUST be the exact SKU, not the display name and not a guess.",
275
+ },
276
+ engine_type: {
277
+ type: "string",
278
+ enum: ["stockfish", "lc0", "combo"],
279
+ description: "Which engine(s) to run. Must match the SKU's own `engine` field from list_cloud_machine_options — e.g. a stockfish-only SKU can only be started as \"stockfish\". Optional; defaults to \"combo\".",
275
280
  },
276
281
  },
277
282
  required: ["machine_type"],
@@ -499,6 +504,18 @@ export const TOOLS = [
499
504
  required: ["id", "title"],
500
505
  },
501
506
  },
507
+ {
508
+ name: "set_collection_folder",
509
+ description: "Move a collection to a different virtual folder — changes only folder_path, not title or contents. Pass an empty string to move it to root (no folder). folder_path is just a string field on each collection, not a real directory: this moves one collection at a time, it does not rename/merge a folder across every collection under it.",
510
+ inputSchema: {
511
+ type: "object",
512
+ properties: {
513
+ id: { type: "string", description: "Collection id, from list_collections." },
514
+ folder_path: { type: "string", description: "New virtual folder path, e.g. '/Openings/Sicilian'. Empty string moves the collection to root." },
515
+ },
516
+ required: ["id", "folder_path"],
517
+ },
518
+ },
502
519
  {
503
520
  name: "create_prep_file",
504
521
  description: "Create a new (empty) prep file in the specified collection. `name` becomes the Event PGN tag. You then extend it with mutation tools (add_move, set_comment, …).\n\n" +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chessceo/mcp",
3
- "version": "0.49.2",
3
+ "version": "0.49.4",
4
4
  "description": "Model Context Protocol server for chess.ceo — 11.7M+ games, ~1.5M FIDE player profiles, opening preparation, live broadcasts.",
5
5
  "type": "module",
6
6
  "bin": {