@walkeros/mcp 4.7.0 → 4.7.1
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 +18 -12
- package/dist/index.d.ts +33 -5
- package/dist/index.js +328 -19873
- package/dist/index.js.map +1 -1
- package/dist/stdio.js +325 -19870
- package/dist/stdio.js.map +1 -1
- package/package.json +7 -5
- package/src/surface.json +370 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/mcp",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.1",
|
|
4
4
|
"description": "MCP server for walkerOS flow development - discover packages, scaffold configs, validate, bundle, simulate, and test event pipelines",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -14,13 +14,15 @@
|
|
|
14
14
|
"./stdio": {
|
|
15
15
|
"types": "./dist/stdio.d.ts",
|
|
16
16
|
"default": "./dist/stdio.js"
|
|
17
|
-
}
|
|
17
|
+
},
|
|
18
|
+
"./surface.json": "./src/surface.json"
|
|
18
19
|
},
|
|
19
20
|
"bin": {
|
|
20
21
|
"walkeros-mcp": "./dist/stdio.js"
|
|
21
22
|
},
|
|
22
23
|
"files": [
|
|
23
24
|
"dist/**",
|
|
25
|
+
"src/surface.json",
|
|
24
26
|
"README.md"
|
|
25
27
|
],
|
|
26
28
|
"scripts": {
|
|
@@ -35,15 +37,15 @@
|
|
|
35
37
|
},
|
|
36
38
|
"dependencies": {
|
|
37
39
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
38
|
-
"@walkeros/cli": "4.7.
|
|
39
|
-
"@walkeros/core": "4.7.
|
|
40
|
+
"@walkeros/cli": "4.7.1",
|
|
41
|
+
"@walkeros/core": "4.7.1"
|
|
40
42
|
},
|
|
41
43
|
"peerDependencies": {
|
|
42
44
|
"zod": "^4.0"
|
|
43
45
|
},
|
|
44
46
|
"devDependencies": {
|
|
45
47
|
"@types/node": "^25.9.1",
|
|
46
|
-
"@walkeros/config": "4.7.
|
|
48
|
+
"@walkeros/config": "4.7.1",
|
|
47
49
|
"msw": "^2.12.10"
|
|
48
50
|
},
|
|
49
51
|
"repository": {
|
package/src/surface.json
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Shipped as @walkeros/mcp/surface.json; the app asserts its hosted server registers this roster.",
|
|
3
|
+
"toolNames": [
|
|
4
|
+
"auth",
|
|
5
|
+
"deploy_manage",
|
|
6
|
+
"diagnostics",
|
|
7
|
+
"feedback",
|
|
8
|
+
"flow_bundle",
|
|
9
|
+
"flow_examples",
|
|
10
|
+
"flow_load",
|
|
11
|
+
"flow_manage",
|
|
12
|
+
"flow_push",
|
|
13
|
+
"flow_simulate",
|
|
14
|
+
"flow_validate",
|
|
15
|
+
"frame_manage",
|
|
16
|
+
"hub_manage",
|
|
17
|
+
"observe_journeys",
|
|
18
|
+
"observe_session",
|
|
19
|
+
"package_get",
|
|
20
|
+
"package_search",
|
|
21
|
+
"project_manage",
|
|
22
|
+
"secret_manage"
|
|
23
|
+
],
|
|
24
|
+
"links": {
|
|
25
|
+
"$comment": "Deep links the tools emit, under the response key named here. They land in chat transcripts and notes nobody can reach back into, so a route rename or a view-key rename in the app has to fail a test at edit time instead of rotting in someone's history. The builders live in walkerOS packages/mcps/mcp/src/links.ts; the app checks these against its real routes and its url-state registry in src/lib/mcp/__tests__/link-routes.test.ts. A route template names its params as the BUILDER names them, and the app's folder may spell the same segment differently ([id] for {flowId}), so a template is matched by shape and position, never by param name.",
|
|
26
|
+
"responseKey": "appUrl",
|
|
27
|
+
"viewParamKey": "view",
|
|
28
|
+
"routes": {
|
|
29
|
+
"flowPage": "/projects/{projectId}/flows/{flowId}",
|
|
30
|
+
"deploymentPage": "/projects/{projectId}/deployments/{deploymentId}"
|
|
31
|
+
},
|
|
32
|
+
"views": {
|
|
33
|
+
"contract": [],
|
|
34
|
+
"releases": [],
|
|
35
|
+
"step": ["flow", "step"]
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"observeSession": {
|
|
39
|
+
"name": "observe_session",
|
|
40
|
+
"title": "Observe Session",
|
|
41
|
+
"description": "Open, inspect, or end an Observe session: a time-boxed window on one flow that runtimes attach to as arms. A preview arm streams from a browser, a container arm runs server-side, and both feed ONE shared journeys feed. start opens the window (arms picks which runtimes attach), status reports per-arm state plus recordsReceived and expiresAt, stop ends the whole session including every arm. A flow has at most one session, so status/stop resolve it from flowId when sessionId is omitted. Read the events with observe_journeys; this tool never returns event data and never judges whether events are correct.",
|
|
42
|
+
"annotations": {
|
|
43
|
+
"readOnlyHint": false,
|
|
44
|
+
"destructiveHint": true,
|
|
45
|
+
"idempotentHint": false,
|
|
46
|
+
"openWorldHint": true
|
|
47
|
+
},
|
|
48
|
+
"inputSchema": {
|
|
49
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
50
|
+
"type": "object",
|
|
51
|
+
"properties": {
|
|
52
|
+
"action": {
|
|
53
|
+
"type": "string",
|
|
54
|
+
"enum": ["start", "status", "stop"],
|
|
55
|
+
"description": "start opens a session, status reports arm state, stop ends the whole session."
|
|
56
|
+
},
|
|
57
|
+
"flowId": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"description": "Flow the Observe session runs on."
|
|
60
|
+
},
|
|
61
|
+
"projectId": {
|
|
62
|
+
"description": "Project ID. Optional; falls back to the default project.",
|
|
63
|
+
"type": "string"
|
|
64
|
+
},
|
|
65
|
+
"sessionId": {
|
|
66
|
+
"description": "Session to act on for status/stop. Optional; the flow has at most one session and it is resolved for you.",
|
|
67
|
+
"type": "string"
|
|
68
|
+
},
|
|
69
|
+
"arms": {
|
|
70
|
+
"description": "Which runtimes attach. Omit to attach the default preview arm; a web settings that references a server flow brings its container arm with it.",
|
|
71
|
+
"type": "object",
|
|
72
|
+
"properties": {
|
|
73
|
+
"container": {
|
|
74
|
+
"description": "Pass true to attach the server container arm, which selects the flow's server settings when no preview arm is named. Only true is accepted: a web settings that references a server flow always brings its container arm along, so a container cannot be suppressed here.",
|
|
75
|
+
"type": "boolean",
|
|
76
|
+
"const": true
|
|
77
|
+
},
|
|
78
|
+
"preview": {
|
|
79
|
+
"description": "Name the flow settings this session observes. A web settings attaches the browser preview arm (plus the container arm of any server flow it references); a server settings attaches the container arm alone. Omit to use the flow's single web settings.",
|
|
80
|
+
"type": "string"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"additionalProperties": false
|
|
84
|
+
},
|
|
85
|
+
"origins": {
|
|
86
|
+
"description": "Bare https origins (https://host[:port]) the session may ingest web events from.",
|
|
87
|
+
"type": "array",
|
|
88
|
+
"items": {
|
|
89
|
+
"type": "string"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"level": {
|
|
93
|
+
"description": "Container observation verbosity. Defaults to the app's own.",
|
|
94
|
+
"type": "string",
|
|
95
|
+
"enum": ["off", "standard", "trace"]
|
|
96
|
+
},
|
|
97
|
+
"replace": {
|
|
98
|
+
"description": "Replace the flow's existing window instead of attaching to it. Re-provisions from the new config.",
|
|
99
|
+
"type": "boolean"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"required": ["action", "flowId"],
|
|
103
|
+
"additionalProperties": false
|
|
104
|
+
},
|
|
105
|
+
"hints": {
|
|
106
|
+
"SIMULATE_FIRST": "Simulate before preview: flow_simulate checks mapping with no browser.",
|
|
107
|
+
"PREVIEW_STREAMS": "Preview streams into this session: mint a link with flow_manage preview_regrant, then open it on your site.",
|
|
108
|
+
"READ": "Read with observe_journeys (flowId); it is the only read.",
|
|
109
|
+
"STOP": "End both arms with observe_session stop.",
|
|
110
|
+
"EMPTY_FEED": "recordsReceived is 0: nothing has reached the feed yet. Drive traffic on an attached arm.",
|
|
111
|
+
"ENDED": "Session ended and both arms detached. Start a new one with observe_session start.",
|
|
112
|
+
"NO_WINDOW": "No Observe session on this flow. Open one with observe_session start."
|
|
113
|
+
},
|
|
114
|
+
"hintOrder": {
|
|
115
|
+
"start": ["SIMULATE_FIRST", "PREVIEW_STREAMS", "READ"],
|
|
116
|
+
"statusWithRecords": ["READ", "STOP"],
|
|
117
|
+
"statusEmptyFeed": ["EMPTY_FEED", "READ", "STOP"],
|
|
118
|
+
"statusNoWindow": ["NO_WINDOW", "SIMULATE_FIRST"],
|
|
119
|
+
"stopEnded": ["ENDED"],
|
|
120
|
+
"stopNoWindow": ["NO_WINDOW"]
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"hubManage": {
|
|
124
|
+
"name": "hub_manage",
|
|
125
|
+
"title": "Release History and Rationale",
|
|
126
|
+
"description": "Read a flow’s release history and the reasoning behind it: what each release changed, and why. Actions: releases (lean index of a flow’s releases, newest first, no snapshots), release_get (one release in full: its rationale plus a server-computed diff against the release before it), step_history (which releases added, changed, or removed one step), rationale_set (write the human rationale for one release; additive, nothing is ever deleted), threads (the discussion anchored to one release, or every open discussion on the flow), note_add (add a message to a thread, or open a new one on a release), knowledge (read what people wrote on the marks of a page in Tag Mode: one page, one mark, or the whole project). Threads are resolved by a person in the app, never here: this tool can only add to a discussion. Knowledge is read-only here for the same reason, and is addressed by frame and mark rather than by flow. Steps are addressed as \"type.name\", the same form flow_simulate takes, for example \"destination.ga4\", \"transformer.router\", \"source.browser\", \"store.session\", or \"contract.checkout\" for a contract entry. This tool carries history only: use flow_manage for the current config and package_get for step schemas.",
|
|
127
|
+
"annotations": {
|
|
128
|
+
"readOnlyHint": false,
|
|
129
|
+
"destructiveHint": false,
|
|
130
|
+
"idempotentHint": false,
|
|
131
|
+
"openWorldHint": true
|
|
132
|
+
},
|
|
133
|
+
"inputSchema": {
|
|
134
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
135
|
+
"type": "object",
|
|
136
|
+
"properties": {
|
|
137
|
+
"action": {
|
|
138
|
+
"type": "string",
|
|
139
|
+
"enum": [
|
|
140
|
+
"releases",
|
|
141
|
+
"release_get",
|
|
142
|
+
"step_history",
|
|
143
|
+
"rationale_set",
|
|
144
|
+
"threads",
|
|
145
|
+
"note_add",
|
|
146
|
+
"knowledge"
|
|
147
|
+
],
|
|
148
|
+
"description": "Which part of the release history to read or write"
|
|
149
|
+
},
|
|
150
|
+
"projectId": {
|
|
151
|
+
"description": "Project ID. Optional: falls back to the default project when omitted.",
|
|
152
|
+
"type": "string"
|
|
153
|
+
},
|
|
154
|
+
"flowId": {
|
|
155
|
+
"description": "Flow ID (flow_...). Required for every action except \"knowledge\", which hangs on a page rather than a flow and refuses this field.",
|
|
156
|
+
"type": "string"
|
|
157
|
+
},
|
|
158
|
+
"versionId": {
|
|
159
|
+
"description": "Release version ID (ver_...) from action \"releases\". Addresses one release for release_get and rationale_set. Pass this or versionNumber.",
|
|
160
|
+
"type": "string",
|
|
161
|
+
"minLength": 1
|
|
162
|
+
},
|
|
163
|
+
"versionNumber": {
|
|
164
|
+
"description": "Spine release number for this flow, the `versionNumber` field of action \"releases\". Alternative to versionId. Not the same as a row's deploymentAttempt.",
|
|
165
|
+
"type": "integer",
|
|
166
|
+
"exclusiveMinimum": 0,
|
|
167
|
+
"maximum": 9007199254740991
|
|
168
|
+
},
|
|
169
|
+
"step": {
|
|
170
|
+
"description": "Step key as \"type.name\", e.g. \"destination.ga4\" or \"contract.checkout\". Required for step_history.",
|
|
171
|
+
"type": "string"
|
|
172
|
+
},
|
|
173
|
+
"flow": {
|
|
174
|
+
"description": "Named flow inside the config, e.g. \"web\" or \"server\". Optional for step_history: omit to scan every named flow. Ignored for contract steps, which are top-level.",
|
|
175
|
+
"type": "string"
|
|
176
|
+
},
|
|
177
|
+
"text": {
|
|
178
|
+
"description": "The text to write (1-4000 chars). Required for rationale_set and note_add. As rationale it replaces the note already on the release and never touches the machine summary; as a note it is appended to a thread and nothing is ever replaced.",
|
|
179
|
+
"type": "string",
|
|
180
|
+
"minLength": 1,
|
|
181
|
+
"maxLength": 4000
|
|
182
|
+
},
|
|
183
|
+
"limit": {
|
|
184
|
+
"description": "Page size. Releases to list for action \"releases\" (max 100), or releases to SCAN for step_history (max 50). For step_history this bounds releases, not entries: a step present in several named flows yields one entry per flow per release, and the scan stops at 200 entries with entriesTruncated set. Narrow with \"flow\" to avoid that. For threads it bounds threads, and a read that carries messages is held to 20 of them. Knowledge entries are bounded the same way.",
|
|
185
|
+
"type": "integer",
|
|
186
|
+
"exclusiveMinimum": 0,
|
|
187
|
+
"maximum": 9007199254740991
|
|
188
|
+
},
|
|
189
|
+
"offset": {
|
|
190
|
+
"description": "Releases to skip. Action \"releases\" only.",
|
|
191
|
+
"type": "integer",
|
|
192
|
+
"minimum": 0,
|
|
193
|
+
"maximum": 9007199254740991
|
|
194
|
+
},
|
|
195
|
+
"anchorType": {
|
|
196
|
+
"description": "What a thread hangs on. Defaults to \"release\", the only anchor the app writes today. Pair it with anchorKey; a key means a different thing under each type.",
|
|
197
|
+
"type": "string",
|
|
198
|
+
"enum": ["step", "entity_action", "release", "contract", "tag"]
|
|
199
|
+
},
|
|
200
|
+
"anchorKey": {
|
|
201
|
+
"description": "What the anchor addresses within its type: a release version ID (ver_...) for \"release\", a \"type.name\" step key for \"step\". For a release you can pass versionId or versionNumber instead. Omit entirely on action \"threads\" to read every thread on the flow.",
|
|
202
|
+
"type": "string",
|
|
203
|
+
"minLength": 1,
|
|
204
|
+
"maxLength": 255
|
|
205
|
+
},
|
|
206
|
+
"anchorLabel": {
|
|
207
|
+
"description": "How the anchor reads on screen, stored once when a thread is opened so a later rename leaves it readable. Derived for a release (\"v14\"); pass it only when opening a thread on another anchor type.",
|
|
208
|
+
"type": "string",
|
|
209
|
+
"minLength": 1,
|
|
210
|
+
"maxLength": 255
|
|
211
|
+
},
|
|
212
|
+
"threadId": {
|
|
213
|
+
"description": "Thread ID (thr_...) from action \"threads\". Pass it to note_add to reply in that thread; omit it to open a new thread on the anchor.",
|
|
214
|
+
"type": "string",
|
|
215
|
+
"minLength": 1
|
|
216
|
+
},
|
|
217
|
+
"status": {
|
|
218
|
+
"description": "Read only threads in this state. Action \"threads\" only; omit for both.",
|
|
219
|
+
"type": "string",
|
|
220
|
+
"enum": ["open", "resolved"]
|
|
221
|
+
},
|
|
222
|
+
"pageKey": {
|
|
223
|
+
"description": "The page a note was left on, as Tag Mode addressed it, usually the page URL. Narrows action \"knowledge\" to every frame that page holds, at any depth; omit it to read the whole project.",
|
|
224
|
+
"type": "string",
|
|
225
|
+
"minLength": 1,
|
|
226
|
+
"maxLength": 1024
|
|
227
|
+
},
|
|
228
|
+
"frameId": {
|
|
229
|
+
"description": "One frame (frm_...), the named rectangle a note hangs on. Action \"knowledge\" only. Narrower than pageKey, since a page holds several frames.",
|
|
230
|
+
"type": "string",
|
|
231
|
+
"pattern": "^frm_[A-Za-z0-9_-]{21}$"
|
|
232
|
+
},
|
|
233
|
+
"markId": {
|
|
234
|
+
"description": "One tag within \"frameId\", by its tag id (the id of an entry in frame_manage marks.tags). Action \"knowledge\" only, and refused without frameId, since a mark id alone addresses nothing. Naming a mark is also what attaches the message bodies.",
|
|
235
|
+
"type": "string",
|
|
236
|
+
"minLength": 1,
|
|
237
|
+
"maxLength": 200
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
"required": ["action"],
|
|
241
|
+
"additionalProperties": false
|
|
242
|
+
},
|
|
243
|
+
"denialHint": "The \"hub\" feature is not enabled for this project. Tell the person that \"hub\" needs a plan or project entitlement that unlocks it, which is changed in the app, not through this tool.",
|
|
244
|
+
"notFoundHint": "Use action \"releases\" to find version ids and action \"threads\" to find thread ids.",
|
|
245
|
+
"hints": {
|
|
246
|
+
"CONFIRM_INDEX": "Use action \"releases\" to confirm it appears in the index.",
|
|
247
|
+
"ENTRY_NAMES_FLOW": "An entry names the flow it was written against in flowId, and validity says which release was live at the time.",
|
|
248
|
+
"KEEP_ONE_THREAD": "Pass its threadId back to action \"note_add\" to keep the conversation in one place instead of opening another thread.",
|
|
249
|
+
"KNOWLEDGE_INDEX": "This is an index: message bodies are omitted. Pass markId with frameId to read one mark in full.",
|
|
250
|
+
"KNOWLEDGE_PAGE_CAPPED": "More knowledge matches than was returned. Narrow with pageKey, then frameId, then markId, rather than treating this as everything that was written.",
|
|
251
|
+
"KNOWLEDGE_READ_ONLY": "This tool only reads knowledge. Answering a note, and settling it, are done by a person in the app.",
|
|
252
|
+
"MASKED_ONLY": "The diff is empty because the only changes are inside masked values. Say that the change is not visible here rather than that nothing changed.",
|
|
253
|
+
"MESSAGES_TRUNCATED": "A thread here is marked hasMoreMessages: only its newest messages were returned. Say the discussion is longer than what you read rather than summarizing it as complete.",
|
|
254
|
+
"MESSAGE_VISIBLE": "The message is now visible in this thread in the app.",
|
|
255
|
+
"NOTHING_DISCUSSED": "Nothing is being discussed on this flow. Use action \"note_add\" with a versionId to start a thread on a release.",
|
|
256
|
+
"NOTHING_WRITTEN": "Nothing has been written here. Notes are left on the page in Tag Mode, not through this tool.",
|
|
257
|
+
"NO_MATCH": "No scanned release touched this step. Check the step key against knownSteps, or raise limit to scan further back.",
|
|
258
|
+
"NO_THREAD_ON_ANCHOR": "No thread hangs on this anchor yet. Use action \"note_add\" to open one.",
|
|
259
|
+
"OPEN_RELEASE": "Use action \"release_get\" on one of these versionIds to read the full diff and rationale.",
|
|
260
|
+
"RATIONALE_VISIBLE": "The rationale is now visible on this release in the app.",
|
|
261
|
+
"READ_BACK": "Use action \"threads\" to read the discussion back.",
|
|
262
|
+
"READ_FRAME": "Use frame_manage action \"get\" with the frameId to read the frame and its marks.",
|
|
263
|
+
"RELEASE_GET": "Use action \"release_get\" with a versionId or versionNumber to read one release in full, with its diff.",
|
|
264
|
+
"REPLY_OR_OPEN": "Use action \"note_add\" with a threadId to reply in one of these threads, or without one to open another.",
|
|
265
|
+
"RESOLVE_IN_APP": "Resolving a thread into a release is done by a person in the app, not through this tool.",
|
|
266
|
+
"ROWS_ARE_DEPLOYMENTS": "Rows are deployments, not releases: the same versionId on several rows is a redeploy of identical content, so count distinct versionId values, and note that total counts deployments.",
|
|
267
|
+
"SCAN_CAPPED": "The scan stopped at the entry cap, so older releases were not compared. Narrow with \"flow\" to see the whole history of one occurrence.",
|
|
268
|
+
"STAYS_RESOLVED": "This thread is resolved and stayed resolved: a reply never retracts the release link.",
|
|
269
|
+
"STEP_HISTORY": "Use action \"step_history\" to see which releases touched one step.",
|
|
270
|
+
"THREADS_INDEX": "This is an index: message bodies are omitted. Pass a versionId, or anchorType with anchorKey, to read one discussion in full.",
|
|
271
|
+
"THREADS_PAGE_CAPPED": "More threads match than were returned (the page is capped at 20 when messages are attached). Narrow with anchorType and anchorKey, or with status, rather than treating this as the complete list.",
|
|
272
|
+
"THREAD_OPEN": "The thread is now open on this anchor in the app.",
|
|
273
|
+
"TRACE_STEP": "Use action \"step_history\" to trace one step across releases.",
|
|
274
|
+
"WRITE_RATIONALE": "This release has no human rationale. Read the diff, then use action \"rationale_set\" to record why it changed."
|
|
275
|
+
},
|
|
276
|
+
"hintOrder": {
|
|
277
|
+
"releases": ["RELEASE_GET", "ROWS_ARE_DEPLOYMENTS", "STEP_HISTORY"],
|
|
278
|
+
"releaseGetMaskedOnly": ["MASKED_ONLY"],
|
|
279
|
+
"releaseGetWithRationale": ["TRACE_STEP"],
|
|
280
|
+
"releaseGetNoRationale": ["WRITE_RATIONALE"],
|
|
281
|
+
"stepHistoryCapped": ["SCAN_CAPPED"],
|
|
282
|
+
"stepHistoryEmpty": ["NO_MATCH"],
|
|
283
|
+
"stepHistoryMatched": ["OPEN_RELEASE"],
|
|
284
|
+
"rationaleSet": ["RATIONALE_VISIBLE", "CONFIRM_INDEX"],
|
|
285
|
+
"threadsIndexEmpty": ["NOTHING_DISCUSSED"],
|
|
286
|
+
"threadsAnchorEmpty": ["NO_THREAD_ON_ANCHOR"],
|
|
287
|
+
"threadsIndexCapped": ["THREADS_PAGE_CAPPED", "THREADS_INDEX"],
|
|
288
|
+
"threadsAnchorTruncated": [
|
|
289
|
+
"MESSAGES_TRUNCATED",
|
|
290
|
+
"REPLY_OR_OPEN",
|
|
291
|
+
"RESOLVE_IN_APP"
|
|
292
|
+
],
|
|
293
|
+
"noteAddReplyOpen": ["MESSAGE_VISIBLE", "READ_BACK"],
|
|
294
|
+
"noteAddReplyResolved": ["MESSAGE_VISIBLE", "STAYS_RESOLVED"],
|
|
295
|
+
"noteAddOpen": ["THREAD_OPEN", "KEEP_ONE_THREAD"],
|
|
296
|
+
"knowledgeEmpty": ["NOTHING_WRITTEN"],
|
|
297
|
+
"knowledgeIndexCapped": [
|
|
298
|
+
"KNOWLEDGE_PAGE_CAPPED",
|
|
299
|
+
"KNOWLEDGE_INDEX",
|
|
300
|
+
"ENTRY_NAMES_FLOW",
|
|
301
|
+
"KNOWLEDGE_READ_ONLY",
|
|
302
|
+
"READ_FRAME"
|
|
303
|
+
],
|
|
304
|
+
"knowledgeMarkTruncated": [
|
|
305
|
+
"MESSAGES_TRUNCATED",
|
|
306
|
+
"ENTRY_NAMES_FLOW",
|
|
307
|
+
"KNOWLEDGE_READ_ONLY",
|
|
308
|
+
"READ_FRAME"
|
|
309
|
+
]
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
"frameManage": {
|
|
313
|
+
"name": "frame_manage",
|
|
314
|
+
"title": "Frames",
|
|
315
|
+
"description": "Read the frames of a measurement plan: named rectangles with marks inside them, drawn in Tag Mode or in the app. Actions: list (every frame of the project, without marks), page (the frames of one page at any depth, with marks), get (one frame with its marks). Read-only: frames are drawn and edited in Tag Mode or the app, never here. A frame name is documentation; the marks inside it carry the meaning. A frame that extends another stores only what it adds, so its tags may carry only the fields they change. Marks are { tags, note }: tags is one flat list of tags, each with an id, a kind such as entity, property or action, a name, and a parentId naming the tag it sits under; note is the frame’s own description and thread. Use hub_manage action \"knowledge\" with a frameId or markId to read what people wrote on a frame. A markId is a tag id: a tag’s id, parentId and threadRef come back literal when they have the shape the app mints, so they can be passed straight back; every other string value in the marks is wrapped as data, and so is an object key that is not a plain identifier.",
|
|
316
|
+
"annotations": {
|
|
317
|
+
"readOnlyHint": true,
|
|
318
|
+
"destructiveHint": false,
|
|
319
|
+
"idempotentHint": true,
|
|
320
|
+
"openWorldHint": true
|
|
321
|
+
},
|
|
322
|
+
"inputSchema": {
|
|
323
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
324
|
+
"type": "object",
|
|
325
|
+
"properties": {
|
|
326
|
+
"action": {
|
|
327
|
+
"type": "string",
|
|
328
|
+
"enum": ["list", "page", "get"],
|
|
329
|
+
"description": "list the project’s frames, read one page with marks, or read one frame"
|
|
330
|
+
},
|
|
331
|
+
"projectId": {
|
|
332
|
+
"description": "Project ID. Optional: falls back to the default project when omitted.",
|
|
333
|
+
"type": "string"
|
|
334
|
+
},
|
|
335
|
+
"pageKey": {
|
|
336
|
+
"description": "The page as its frames address it (the `source.key` of a page frame, usually the page URL without query). Required for page.",
|
|
337
|
+
"type": "string",
|
|
338
|
+
"minLength": 1,
|
|
339
|
+
"maxLength": 1024
|
|
340
|
+
},
|
|
341
|
+
"frameId": {
|
|
342
|
+
"description": "Frame ID (frm_...). Required for get. Use action \"list\" or \"page\" to find one.",
|
|
343
|
+
"type": "string",
|
|
344
|
+
"pattern": "^frm_[A-Za-z0-9_-]{21}$"
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
"required": ["action"],
|
|
348
|
+
"additionalProperties": false
|
|
349
|
+
},
|
|
350
|
+
"denialHint": "The \"frames\" feature is not enabled for this project. Tell the person that \"frames\" needs a plan or project entitlement that unlocks it, which is changed in the app, not through this tool.",
|
|
351
|
+
"notFoundHint": "Use action \"list\" or \"page\" to find frame ids.",
|
|
352
|
+
"hints": {
|
|
353
|
+
"EXTENDS_BASE": "This frame extends another and stores only what it adds; read the base frame (extends) for the rest.",
|
|
354
|
+
"MARK_SPACE": "Tag geometry is fractional: a rect is 0..1 of its frame, and an at is 0..1 of its parent tag’s box, or of the frame for a root tag; a child frame sits inside its parent through placements[].rect.",
|
|
355
|
+
"NAMES_ARE_DOCUMENTATION": "Frame names are documentation; the marks inside a frame carry the meaning.",
|
|
356
|
+
"NONE_ON_PAGE": "No frames on this page. Check the pageKey against the source.key values from action \"list\".",
|
|
357
|
+
"NONE_YET": "This project has no frames yet. Frames are drawn in Tag Mode or the app, not through this tool.",
|
|
358
|
+
"OPEN_PAGE_OR_GET": "Use action \"page\" with a pageKey (a frame’s source.key) to read a page with marks, or action \"get\" with a frameId.",
|
|
359
|
+
"READ_KNOWLEDGE": "Use hub_manage action \"knowledge\" with frameId (and markId) to read what people wrote here. A markId is a tag id from these marks, and a tag’s threadRef is the id of its thread entry there."
|
|
360
|
+
},
|
|
361
|
+
"hintOrder": {
|
|
362
|
+
"list": ["OPEN_PAGE_OR_GET", "NAMES_ARE_DOCUMENTATION"],
|
|
363
|
+
"listEmpty": ["NONE_YET"],
|
|
364
|
+
"page": ["MARK_SPACE", "READ_KNOWLEDGE"],
|
|
365
|
+
"pageEmpty": ["NONE_ON_PAGE"],
|
|
366
|
+
"getVariation": ["EXTENDS_BASE", "READ_KNOWLEDGE"],
|
|
367
|
+
"getBase": ["READ_KNOWLEDGE"]
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|