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 +50 -8
- package/dist/index.js +13 -8
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
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
|
|
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
|
|
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
|
-
#
|
|
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
|
|
307
|
-
npm run deploy:worker:
|
|
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
|
|
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
|
|
359
|
-
npm run deploy:worker
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
3037
|
+
var VERSION = "0.3.2";
|
|
3033
3038
|
function showHelp() {
|
|
3034
3039
|
console.log(`
|
|
3035
3040
|
Slima MCP v${VERSION}
|