slima-mcp 0.3.0 → 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 CHANGED
@@ -137,19 +137,41 @@ Get your token from [Slima Settings](https://app.slima.ai/settings/api-tokens) o
137
137
  gemini mcp add slima --command "npx -y slima-mcp@0"
138
138
  ```
139
139
 
140
- > **Why `slima-mcp@0` instead of `slima-mcp` / `slima-mcp@latest`?** Using `@0` pins to the current major version — npx still fetches new `0.x.y` releases automatically (so you get features + bug fixes), but when we ship `1.0.0` with breaking changes you won't silently pick it up without updating your config. We'll announce the `@1` switch in the release notes.
140
+ > **Why `slima-mcp@0` instead of `slima-mcp` / `slima-mcp@latest`?** Using `@0` pins to the current major version — npx fetches new `0.x.y` releases automatically (so you get features + bug fixes), but when we ship `1.0.0` with breaking changes you won't silently pick it up without updating your config. We'll announce the `@1` switch in the release notes.
141
+ >
142
+ > ⚠️ **This only holds if you do not also have a global `slima-mcp` install.** `npx pkg@<range>`
143
+ > will happily satisfy the range from a package already on your `PATH` and never contact the
144
+ > registry at all. Measured on 2026-09-09 with a global `0.2.0` present and `0.3.0` on npm:
145
+ >
146
+ > | command | resolved |
147
+ > |---|---|
148
+ > | `npx -y slima-mcp@0` | **0.2.0** — used the global install |
149
+ > | `npx -y slima-mcp` | **0.2.0** — same |
150
+ > | `npx -y slima-mcp@latest` | 0.3.0 — a dist-tag forces a registry lookup |
151
+ > | `npx -y slima-mcp@0.3.0` | 0.3.0 — the global can't satisfy an exact newer version |
152
+ >
153
+ > So a stale global install makes the npx form silently stop upgrading, while the server keeps
154
+ > telling you to upgrade. Remove it — see below.
141
155
 
142
156
  #### Migrating from a global install
143
157
 
144
158
  If you already installed globally with `npm install -g slima-mcp`:
145
159
 
146
160
  ```bash
147
- # Remove the old global install (optional but cleaner)
161
+ # Remove the old global install — REQUIRED, not just tidiness.
162
+ # Leaving it in place makes `npx -y slima-mcp@0` resolve to the old global copy
163
+ # forever (see the warning above), so you'd stay outdated while being told to upgrade.
148
164
  npm uninstall -g slima-mcp
149
165
 
150
- # Change your config `command` from "slima-mcp" to the npx form above, and restart the client.
166
+ # Then change your config `command` from "slima-mcp" to the npx form above, and restart the client.
167
+ # Verify: `npx -y slima-mcp@0 --version` must print the version shown by `npm view slima-mcp version`.
151
168
  ```
152
169
 
170
+ ⚠️ Check **every** place you may have installed it. A global install can exist per Node version
171
+ manager environment and per OS — on WSL setups it is common to have one under `nvm` *and* one
172
+ under Windows' `AppData/Roaming/npm`, at two different versions, with only one of them on the
173
+ `PATH` your MCP client actually uses.
174
+
153
175
  Or, if you want to stay on a global install, remember to periodically run:
154
176
 
155
177
  ```bash
@@ -303,8 +325,8 @@ npm run dev:worker
303
325
  # Deploy to Cloudflare
304
326
  npm run deploy:worker
305
327
 
306
- # Deploy to preview environment
307
- npm run deploy:worker:preview
328
+ # Deploy to the test environment (test-mcp.slima.ai)
329
+ npm run deploy:worker:test
308
330
  ```
309
331
 
310
332
  ### Project Structure
@@ -352,13 +374,33 @@ git checkout main && git merge dev && git push
352
374
 
353
375
  ### Cloudflare Worker (Manual)
354
376
 
355
- Worker deployment is separate from npm. Deploy after code changes:
377
+ **Worker deployment is separate from npm, and nothing triggers it automatically.**
378
+ Publishing to npm does NOT update `mcp.slima.ai`. Remote clients (claude.ai /
379
+ ChatGPT connectors) talk to the Worker, so they keep running the old tool set
380
+ until someone runs this by hand:
356
381
 
357
382
  ```bash
358
- npm run deploy:worker # Production (mcp.slima.ai)
359
- npm run deploy:worker:preview # Staging
383
+ npm run deploy:worker:test # Test (test-mcp.slima.ai -> test-api.slima.ai)
384
+ npm run deploy:worker # Prod (mcp.slima.ai -> api.slima.ai)
360
385
  ```
361
386
 
387
+ Deploy test first and check `curl https://test-mcp.slima.ai/ | jq .version`
388
+ before doing prod; the same one-liner against `mcp.slima.ai` is how you tell
389
+ whether the Worker is behind npm at all.
390
+
391
+ > 2026-09-09: the Worker sat on 0.2.0 for four and a half months — it was last
392
+ > deployed the same day npm 0.2.0 shipped, so every change after that reached
393
+ > npm users and no connector users. There is no alarm for this; the version
394
+ > endpoint is the only signal.
395
+
396
+ > There used to be a `deploy:worker:preview` script pointing at an `[env.preview]`
397
+ > block. It was removed on 2026-09-09: its KV id was the literal placeholder
398
+ > string, `staging-api.slima.ai` does not resolve, and — worst — it defined no
399
+ > `routes`. `routes` is an *inheritable* key in wrangler, so that command would
400
+ > have inherited the top-level `mcp.slima.ai` custom domain and pointed
401
+ > **production's hostname** at the preview Worker. The real staging environment
402
+ > is `[env.test]`.
403
+
362
404
  ### MCP Registry (Manual)
363
405
 
364
406
  To publish/update the server listing on the [MCP Registry](https://registry.modelcontextprotocol.io/):
package/dist/index.js CHANGED
@@ -170,7 +170,7 @@ var SlimaApiClient = class {
170
170
  headers: {
171
171
  Authorization: `Bearer ${token}`,
172
172
  "Content-Type": "application/json",
173
- "User-Agent": `slima-mcp-server/${"0.3.0"}`
173
+ "User-Agent": `slima-mcp-server/${"0.3.2"}`
174
174
  },
175
175
  body: body ? JSON.stringify(body) : void 0,
176
176
  signal: controller.signal
@@ -723,7 +723,7 @@ You can now add files using create_file with book_token: ${book.token}`
723
723
  };
724
724
  }
725
725
  const formatted = books.map((book) => {
726
- const words = book.totalWordCount?.toLocaleString() || "0";
726
+ const words = book.manuscriptWordCount?.toLocaleString() || "0";
727
727
  return `- **${book.title}** (${book.token}) \u2014 ${studioLabel(book)}
728
728
  Author: ${book.authorName || "N/A"} | Words: ${words}`;
729
729
  }).join("\n\n");
@@ -767,7 +767,7 @@ _\u{1F4DD} Script Studio books have write restrictions via MCP (see \`get_book\`
767
767
  - **Author**: ${book.authorName || "N/A"}
768
768
  - **Description**: ${book.description || "N/A"}
769
769
  - **Language**: ${book.language || "N/A"}
770
- - **Total Words**: ${book.totalWordCount?.toLocaleString() || "0"}
770
+ - **Total Words**: ${book.wordCount?.toLocaleString() || "0"}
771
771
  - **Manuscript Words**: ${book.manuscriptWordCount?.toLocaleString() || "0"}
772
772
  - **Reference Words**: ${book.referenceWordCount?.toLocaleString() || "0"}
773
773
  - **Created**: ${book.createdAt}
@@ -851,7 +851,7 @@ figures are account-level and are not exposed here.`,
851
851
  const book = await client.getBook(book_token);
852
852
  const text2 = `# Writing Stats: ${book.title}
853
853
 
854
- - **Total Words**: ${book.totalWordCount?.toLocaleString() || "0"}
854
+ - **Total Words**: ${book.wordCount?.toLocaleString() || "0"}
855
855
  - **Manuscript Words**: ${book.manuscriptWordCount?.toLocaleString() || "0"} (the book itself \u2014 what counts toward the author's word count)
856
856
  - **Reference Words**: ${book.referenceWordCount?.toLocaleString() || "0"} (notes, worldbuilding \u2014 never counted)
857
857
  - **Language**: ${book.language || "N/A"}
@@ -1525,6 +1525,7 @@ var AI_WRITE_POLICY_NOTE = `
1525
1525
  **Not every file type takes a generic write.**
1526
1526
  - Field-level tools only: ${Object.entries(AI_STRUCTURED_TOOLS).map(([ext, tool]) => `\`${ext}\` \u2192 \`${tool}\``).join(", ")}
1527
1527
  - Not writable at all: ${AI_READONLY_EXTENSIONS.map((e) => `\`${e}\``).join(", ")}
1528
+ - \`.map\` is the character relationship graph (\u95DC\u4FC2\u5716) \u2014 not a geographic map; \`.geomap\` is the world map (\u5730\u5716).
1528
1529
 
1529
1530
  A refusal names the file type and what to do instead \u2014 it is information, not
1530
1531
  an obstacle to route around. Call \`get_capabilities\` for the authoritative
@@ -1798,7 +1799,7 @@ Use this instead of \`read_file\` for \`.map\` files: their raw JSON is node ids
1798
1799
  The summary lists every character, every relationship ("A \u2014childhood friends\u2192 B") and any faction groups,
1799
1800
  so it is useful even in clients that do not display images.
1800
1801
 
1801
- \`.map\` files are read-only to AI \u2014 describe changes you recommend in words; the author edits them in the map editor.`,
1802
+ To change one, use \`update_relationship_map\` (one field at a time). A \`.map\` is the relationship graph (\u95DC\u4FC2\u5716), not a geographic map \u2014 that is \`.geomap\`.`,
1802
1803
  {
1803
1804
  book_token: z4.string().describe("Book token (e.g., bk_abc123)"),
1804
1805
  path: z4.string().describe('Path to a .map file (e.g., "world/relations.map")')
@@ -1961,6 +1962,7 @@ var TYPES = [
1961
1962
  tool: "update_relationship_map",
1962
1963
  extension: ".map",
1963
1964
  noun: "relationship map",
1965
+ what: "**This is the character relationship graph (\u95DC\u4FC2\u5716) \u2014 not a geographic map.** A world map\n(\u5730\u5716) is `.geomap`, changed with `update_world_map`.",
1964
1966
  ops: "add_node, update_node, move_node, remove_node, add_edge, update_edge, remove_edge, add_group, update_group, remove_group, set_meta",
1965
1967
  example: '{"op": "add_node", "label": "Lin Shuang", "op_ref": "N1", "position": {"near_id": "<id of Shen Yan>", "direction": "right"}}, {"op": "add_edge", "source_id": "<id of Shen Yan>", "target_id": "@N1", "label": "mentor"}',
1966
1968
  extra: '**Position is content here, not layout.** `update_node` will not move anything \u2014 that is\n`move_node`, so that "I moved her next to him" is its own reviewable change. Prefer\n`{near_id, direction}` over computing numbers. Existing nodes never move; the final\ncoordinates come back in the notes. Group boxes are computed from `member_ids` \u2014 never\nsend x/y/width/height. Removing a node removes its edges, and you are told so.'
@@ -1969,6 +1971,7 @@ var TYPES = [
1969
1971
  tool: "update_world_map",
1970
1972
  extension: ".geomap",
1971
1973
  noun: "world map",
1974
+ what: "**This is the geographic world map (\u5730\u5716).** A character relationship graph (\u95DC\u4FC2\u5716) is\n`.map`, changed with `update_relationship_map`.",
1972
1975
  ops: "add_place, update_place, add_label, update_label, remove_element, add_river, add_border, paint_region, set_meta",
1973
1976
  example: '{"op": "add_place", "x": 210, "y": 96, "name": "Starhaven", "tier": "port"}, {"op": "add_label", "x": 240, "y": 60, "text": "The Cold Sea", "size": "large"}',
1974
1977
  extra: "**Coordinates are grid cells, not pixels**: x 0-519, y 0-363. `read_file` gives you the\nmap with its three terrain grids replaced by a note \u2014 they are machine-encoded and you\ndo not need them; `paint_region` works in cells. `remove_element` takes any element id\n(`pl_` place, `lb_` label, `rv_` river, `bd_` border). Terrain has no undo: paint over it\ninstead. Move a place with `update_place`, never by removing and re-adding it. An unknown\nplace `tier` is refused with the full list of real ones \u2014 read the error, do not guess."
@@ -1994,7 +1997,9 @@ you never have to work out how far it got.
1994
1997
  lands in the author's version history immediately. Say what you changed, not
1995
1998
  "please confirm it".`;
1996
1999
  function describe(type) {
1997
- return `Change a Slima ${type.noun} (\`${type.extension}\`) one field at a time.
2000
+ return `Change a Slima ${type.noun} (\`${type.extension}\`) one field at a time.${type.what ? `
2001
+
2002
+ ${type.what}` : ""}
1998
2003
 
1999
2004
  This is the ONLY way to write this file type \u2014 \`write_file\` and \`edit_file\`
2000
2005
  are refused for it, because a whole-file write would drop the parts of the
@@ -2568,7 +2573,7 @@ function createSlimaServer(config) {
2568
2573
  const server = new McpServer(
2569
2574
  {
2570
2575
  name: "slima",
2571
- version: "0.3.0"
2576
+ version: "0.3.2"
2572
2577
  },
2573
2578
  {
2574
2579
  instructions: SERVER_INSTRUCTIONS
@@ -3029,7 +3034,7 @@ async function runStatus() {
3029
3034
  }
3030
3035
 
3031
3036
  // src/cli/index.ts
3032
- var VERSION = "0.3.0";
3037
+ var VERSION = "0.3.2";
3033
3038
  function showHelp() {
3034
3039
  console.log(`
3035
3040
  Slima MCP v${VERSION}