@excaliwow/mcp 0.2.1 → 0.3.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.
Files changed (3) hide show
  1. package/README.md +26 -16
  2. package/dist/bin.js +53 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -8,9 +8,10 @@ client (Claude Desktop, Claude Code, etc.) can launch it with `npx`.
8
8
  ## Install
9
9
 
10
10
  First mint a Personal Access Token at https://excaliwow.com/app/settings
11
- (Settings → Developer / API tokens) with **`read` + `write`** capabilities — that
12
- is everything the server's tools need (see [Security notes](#security-notes)).
13
- Pass it as `EXCALIWOW_TOKEN`.
11
+ (Settings → Developer / API tokens) with **`read` + `write`** capabilities —
12
+ enough for five of the seven tools. Add **`delete`** only if you want the agent
13
+ to trash and restore diagrams (see [Security notes](#security-notes)). Pass it as
14
+ `EXCALIWOW_TOKEN`.
14
15
 
15
16
  ### Claude Code (CLI)
16
17
 
@@ -36,7 +37,7 @@ token to your account:
36
37
  "mcpServers": {
37
38
  "excaliwow": {
38
39
  "command": "npx",
39
- "args": ["-y", "@excaliwow/mcp@0.2.1"],
40
+ "args": ["-y", "@excaliwow/mcp@0.3.0"],
40
41
  "env": {
41
42
  "EXCALIWOW_TOKEN": "excw_pat_…"
42
43
  }
@@ -52,7 +53,7 @@ you've reviewed a new release.
52
53
 
53
54
  ## Troubleshooting
54
55
 
55
- **`npx -y @excaliwow/mcp@0.2.1` fails with `ENOENT … /@excaliwow/mcp@0.2.1/package.json`.**
56
+ **`npx -y @excaliwow/mcp@0.3.0` fails with `ENOENT … /@excaliwow/mcp@0.3.0/package.json`.**
56
57
  On some npm/Node versions, `npx` misreads a scoped package + `@version` spec as a
57
58
  local directory. It's an upstream npm bug (it reproduces with other scoped
58
59
  packages, e.g. `@modelcontextprotocol/server-filesystem@1.0.0`), not an Excaliwow one. Either
@@ -61,7 +62,7 @@ above does), or pin safely by installing once and pointing the client at the
61
62
  binary:
62
63
 
63
64
  ```sh
64
- npm i -g @excaliwow/mcp@0.2.1
65
+ npm i -g @excaliwow/mcp@0.3.0
65
66
  ```
66
67
 
67
68
  ```json
@@ -99,20 +100,26 @@ npx -y @excaliwow/mcp --health
99
100
 
100
101
  ## Tools
101
102
 
102
- Five tools, scoped to safe agent use:
103
+ Seven tools, scoped to safe agent use:
103
104
 
104
105
  | Tool | Capability | What it does |
105
106
  | ------------------ | ---------- | --------------------------------------------------------------------------- |
106
107
  | `generate_diagram` | `write` | Create a diagram from the high-level node/edge DSL; returns the editor URL. |
107
108
  | `read_diagram` | `read` | Compact summary (title + per-type element counts) **plus** a rendered PNG. |
108
- | `list_diagrams` | `read` | Page through your diagrams. |
109
+ | `list_diagrams` | `read` | Page through your diagrams (`filter: active \| trash`). |
109
110
  | `move_diagram` | `write` | Move a diagram to a folder (or to root). |
110
111
  | `edit_diagram` | `write` | Additively merge a DSL fragment (add nodes/edges, update node style/label). |
112
+ | `trash_diagram` | `delete` | Soft-delete a diagram to trash. **Reversible** (see `restore_diagram`). |
113
+ | `restore_diagram` | `delete` | Restore a trashed diagram, reopening it at its original id and URL. |
111
114
 
112
115
  `read_diagram` returns a summary + image, **never** the raw scene JSON, to keep
113
- context small. Making a diagram publicly shareable is deliberately **not** an
114
- agent tool so a misled agent can't be tricked into exposing your diagram. Use
115
- the dashboard or the CLI to publish.
116
+ context small. `trash_diagram` / `restore_diagram` are a **reversible** pair
117
+ gated on the `delete` capability registered always, they return a clean
118
+ `insufficient_scope` error (changing nothing) unless the token carries `delete`,
119
+ so a `read` + `write` token can't trash anything. Hard-delete/purge and making a
120
+ diagram publicly shareable are deliberately **not** agent tools — those are
121
+ irreversible, so a misled agent can't destroy or expose your diagram. Purge or
122
+ publish from the dashboard or the CLI.
116
123
 
117
124
  ### DSL discovery
118
125
 
@@ -134,11 +141,14 @@ resource at **`excaliwow://dsl/reference`**.
134
141
  project`) puts the token into git history. Use a user- or local-scoped config
135
142
  (`--scope local`), or reference an environment variable instead of pasting the
136
143
  literal token.
137
- - **Mint with only `read` + `write`.** Those are the only capabilities the five
138
- tools use (see the table above); none publish or delete. So a `read` + `write`
139
- PAT can neither expose your diagrams publicly nor delete them, even if the
140
- agent is misled. Pick those two capabilities specifically — the coarse
141
- `read-write` preset additionally grants `publish` and `delete`.
144
+ - **Mint with `read` + `write` (add `delete` only if you want trash/restore).**
145
+ Five of the seven tools need just `read` + `write`; a `read` + `write` PAT can
146
+ neither expose your diagrams publicly nor delete them, even if the agent is
147
+ misled (`trash_diagram` / `restore_diagram` simply return `insufficient_scope`
148
+ and do nothing). Add the `delete` capability only if you want the agent to be
149
+ able to soft-delete and restore — it's reversible, but it's still a capability
150
+ to grant deliberately. Pick capabilities specifically rather than the coarse
151
+ `read-write` preset, which additionally grants `publish` (and `delete`).
142
152
  - **Pin the version** in your client config rather than floating on `@latest`,
143
153
  and review release notes before bumping.
144
154
  - The token is a credential to your account. It lives only in your MCP client
package/dist/bin.js CHANGED
@@ -205,6 +205,24 @@ function moveDiagram(ctx, id, folderId) {
205
205
  fetchImpl: ctx.fetchImpl
206
206
  });
207
207
  }
208
+ function deleteDiagram(ctx, id) {
209
+ return request({
210
+ method: "DELETE",
211
+ path: `${PREFIX}/diagrams/${encodeURIComponent(id)}`,
212
+ token: ctx.token,
213
+ baseUrl: ctx.baseUrl,
214
+ fetchImpl: ctx.fetchImpl
215
+ });
216
+ }
217
+ function restoreDiagram(ctx, id) {
218
+ return request({
219
+ method: "POST",
220
+ path: `${PREFIX}/diagrams/${encodeURIComponent(id)}/restore`,
221
+ token: ctx.token,
222
+ baseUrl: ctx.baseUrl,
223
+ fetchImpl: ctx.fetchImpl
224
+ });
225
+ }
208
226
 
209
227
  // src/server.ts
210
228
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -427,7 +445,7 @@ var EditFragmentZ = z.object({
427
445
  });
428
446
 
429
447
  // src/version.ts
430
- var VERSION = "0.2.1";
448
+ var VERSION = "0.3.0";
431
449
 
432
450
  // src/server.ts
433
451
  function textResult(text) {
@@ -625,6 +643,40 @@ preview fidelity: ${png.quality} \u2014 faithful renderer unavailable; layout/fo
625
643
  }
626
644
  }
627
645
  );
646
+ server2.registerTool(
647
+ "trash_diagram",
648
+ {
649
+ title: "Trash a diagram (soft delete)",
650
+ description: "Soft-delete a diagram to trash. REVERSIBLE \u2014 restore_diagram brings it back, and it stays visible under list_diagrams with filter='trash'. Use this to clean up diagrams you no longer want (e.g. earlier drafts from iterating). Requires a Personal Access Token with the `delete` capability; without it the call returns a clean 'insufficient_scope' error and changes nothing. Idempotent on an already-trashed id.",
651
+ inputSchema: { id: z2.string() }
652
+ },
653
+ async ({ id }) => {
654
+ try {
655
+ const ctx = buildCtx(deps);
656
+ await deleteDiagram(ctx, id);
657
+ return textResult(JSON.stringify({ id, trashed: true }));
658
+ } catch (err) {
659
+ return toErrorResult(err);
660
+ }
661
+ }
662
+ );
663
+ server2.registerTool(
664
+ "restore_diagram",
665
+ {
666
+ title: "Restore a diagram from trash",
667
+ description: "Restore a soft-deleted diagram from trash, reopening it in the editor at its original id and url. The inverse of trash_diagram. Requires a Personal Access Token with the `delete` capability; without it the call returns a clean 'insufficient_scope' error and changes nothing. Idempotent on an already-active id.",
668
+ inputSchema: { id: z2.string() }
669
+ },
670
+ async ({ id }) => {
671
+ try {
672
+ const ctx = buildCtx(deps);
673
+ await restoreDiagram(ctx, id);
674
+ return textResult(JSON.stringify({ id, restored: true }));
675
+ } catch (err) {
676
+ return toErrorResult(err);
677
+ }
678
+ }
679
+ );
628
680
  server2.registerResource(
629
681
  "dsl-reference",
630
682
  DSL_REFERENCE_URI,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@excaliwow/mcp",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Excaliwow Model Context Protocol (MCP) server — lets AI agents create, read, render, and edit Excaliwow diagrams over the public REST API, via stdio.",
5
5
  "private": false,
6
6
  "publishConfig": {