@evref-bl/pharo-mcp 3.0.0 → 3.1.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 (24) hide show
  1. package/README.md +5 -7
  2. package/package.json +1 -1
  3. package/templates/pharo-references/pharo-coding.md +105 -0
  4. package/templates/pharo-references/tool-reference.md +78 -158
  5. package/templates/pharo-skills/pharo-ci-repro/references/pharo-smalltalkci.md +4 -28
  6. package/templates/pharo-skills/pharo-code-profiling/SKILL.md +19 -38
  7. package/templates/pharo-skills/pharo-image-sync/SKILL.md +47 -0
  8. package/templates/pharo-skills/pharo-image-sync/agents/openai.yaml +4 -0
  9. package/templates/pharo-skills/pharo-mcp-recovery/SKILL.md +1 -1
  10. package/templates/pharo-skills/pharo-project-load/SKILL.md +2 -1
  11. package/templates/pharo.AGENTS.md +16 -14
  12. package/templates/pharo-references/building-on-mcp.md +0 -473
  13. package/templates/pharo-references/debugging.md +0 -70
  14. package/templates/pharo-references/getting-started.md +0 -151
  15. package/templates/pharo-references/pharo-coding-rules.md +0 -147
  16. package/templates/pharo-references/pharo-coding-style.md +0 -141
  17. package/templates/pharo-references/safety-and-ecosystem.md +0 -323
  18. package/templates/pharo-references/source-vs-live-image.md +0 -75
  19. package/templates/pharo-references/troubleshooting.md +0 -145
  20. package/templates/pharo-references/using-pharo-mcp.md +0 -86
  21. package/templates/pharo-skills/pharo-image-git-handoff/SKILL.md +0 -40
  22. package/templates/pharo-skills/pharo-image-git-handoff/agents/openai.yaml +0 -4
  23. package/templates/pharo-skills/pharo-version-compat/SKILL.md +0 -54
  24. package/templates/pharo-skills/pharo-version-compat/agents/openai.yaml +0 -4
@@ -1,38 +1,40 @@
1
1
  # Pharo MCP Agent Guide
2
2
 
3
3
  Use the configured `pharo` MCP server whenever a task depends on the running
4
- image. Preserve unrelated changes and report unavailable live checks instead of
5
- guessing from source.
4
+ image. Preserve unrelated changes, and say which live check you could not run
5
+ rather than letting source stand in for it.
6
6
 
7
7
  ## Read First
8
8
 
9
9
  - Inspect the tools and schemas exposed by the current client; do not rely on
10
- remembered names.
10
+ remembered names. `tool_search` finds what is not advertised, and `tool_get`
11
+ answers one tool's schema.
11
12
  - Prefer the least-mutating dedicated tool. Use `image_evaluate` only when no
12
13
  dedicated tool fits.
13
- - Treat image, Tonel, Iceberg, and Git state as separate.
14
+ - Treat image, Tonel, Iceberg, and Git state as separate. None of them proves
15
+ anything about the others.
16
+ - The image is one workspace. It has no branches and no worktrees, so two
17
+ agents working in it at once share every edit, and one export writes both
18
+ their changes into one diff. One writer at a time.
14
19
  - Tools change the running image but never save it; use a safe image boundary.
15
20
 
16
21
  ## Context Loading
17
22
 
18
23
  - Before Pharo source changes: read the project's Pharo coding and testing
19
24
  guidance. If none exists, use the local
20
- [coding rules](pharo-references/pharo-coding-rules.md) and
21
- [coding style](pharo-references/pharo-coding-style.md).
25
+ [Pharo coding](pharo-references/pharo-coding.md) reference.
26
+ - Before reading an answer closely, rewriting methods, or acting on a warning a
27
+ call came back with: read
28
+ [tool reference](pharo-references/tool-reference.md).
22
29
  - Before loading a project: use `skills/pharo-project-load/SKILL.md`.
23
- - Before cross-version work: use `skills/pharo-version-compat/SKILL.md`.
24
- - Before exporting image changes or changing Git state: use
25
- `skills/pharo-image-git-handoff/SKILL.md`.
30
+ - Before moving code between the image and its files: use
31
+ `skills/pharo-image-sync/SKILL.md`.
26
32
  - Before reproducing smalltalkCI or GitHub failures: use
27
33
  `skills/pharo-ci-repro/SKILL.md`.
28
34
  - Before profiling or optimizing Pharo code: use
29
35
  `skills/pharo-code-profiling/SKILL.md`.
30
36
  - Before recovering a stopped standalone image: use
31
37
  `skills/pharo-mcp-recovery/SKILL.md`.
32
- - Before debugger sessions or repairs: read the local
33
- [debugging guide](pharo-references/debugging.md).
34
- - Before giving a project MCP tools, resources or prompts of its own: read
35
- [building on MCP](pharo-references/building-on-mcp.md).
36
38
 
37
39
  ## Workflow
38
40
 
@@ -40,7 +42,7 @@ guessing from source.
40
42
  2. Preview or verify identity before risky mutation.
41
43
  3. Make the narrowest image-side change.
42
44
  4. Run focused SUnit tests and inspect the result.
43
- 5. Use the handoff skill before exporting or committing Tonel changes.
45
+ 5. Use the image-sync skill before exporting or committing Tonel changes.
44
46
 
45
47
  For repository work, verify repository identity before mutation and inspect the
46
48
  image-side diff before export or commit.
@@ -1,473 +0,0 @@
1
- # Building On MCP
2
-
3
- MCP is a server you can embed. Loading `Core` gives you the Streamable HTTP
4
- transport, the JSON-RPC and schema machinery and the catalog tools, and
5
- nothing that knows about Pharo code. Everything the server then offers a
6
- client — tools, resources, prompts — you write in a package of your own.
7
-
8
- A project doing this changes nothing in MCP. Its tools live in a package of
9
- its own, which it loads when it wants them served and leaves out when it does
10
- not.
11
-
12
- ## Load the server alone
13
-
14
- Depend on the baseline and ask for `Core`:
15
-
16
- ```smalltalk
17
- BaselineOfMyProject >> baseline: spec
18
-
19
- <baseline>
20
- spec for: #common do: [
21
- spec baseline: 'MCP' with: [
22
- spec
23
- repository: 'github://Evref-BL/MCP:vX.Y.Z/src'; "a release, not a branch"
24
- loads: #( 'Core' ) ].
25
- spec package: 'MyProject-MCP' with: [ spec requires: #( 'MyProject' 'MCP' ) ].
26
- spec group: 'Tools' with: #( 'MyProject-MCP' ).
27
- spec group: 'default' with: #( 'Core' 'Tests' ) ]
28
- ```
29
-
30
- Two things in it are worth copying. The group is named `Tools` rather than
31
- `MCP`, because Metacello refuses a group and a baseline that share one name.
32
- And it is left out of `default`: your project is useful without a server, and
33
- an image that does not serve MCP has no use for tools it cannot register.
34
-
35
- The other groups are `IDE`, MCP's own image tools for classes, methods,
36
- packages, tests, repositories, change history and debugging; `UI`,
37
- the world-menu server list; `Telemetry`, the OpenTelemetry backend; and
38
- `default`, which is `Core`, `IDE`, `UI` and their tests.
39
-
40
- ## The three things a server offers
41
-
42
- | Kind | What it is | Who reaches for it | Subclass of | Names itself with |
43
- | --- | --- | --- | --- | --- |
44
- | Tool | an action with arguments | the model, on its own | `MCPTool` | `toolName` |
45
- | Resource | a document to read | the host, for the user | `MCPResource` | `resourceUri` |
46
- | Prompt | a message template | the user, deliberately | `MCPPrompt` | `promptName` |
47
-
48
- They are independent. A server may have one of them, two, or all three.
49
-
50
- ## A tool
51
-
52
- Give your tools a common superclass. It is where the things they share live —
53
- the group they belong to, the icon they are drawn with, the helpers that talk
54
- to your project:
55
-
56
- ```smalltalk
57
- MCPTool << #MyProjectTool
58
- package: 'MyProject-MCP'
59
- ```
60
-
61
- ```smalltalk
62
- MyProjectTool class >> groupName
63
-
64
- ^ 'widgets'
65
- ```
66
-
67
- The base is not served, and needs to say nothing to stay out: it answers no
68
- `toolName`, so there is no tool there to register.
69
-
70
- Then one class per tool:
71
-
72
- ```smalltalk
73
- MyProjectTool << #MyProjectToolListWidgets
74
- package: 'MyProject-MCP'
75
- ```
76
-
77
- ```smalltalk
78
- MyProjectToolListWidgets class >> toolName
79
-
80
- ^ 'widget_list'
81
-
82
- MyProjectToolListWidgets >> title
83
-
84
- ^ 'List Widgets'
85
-
86
- MyProjectToolListWidgets >> description
87
-
88
- ^ 'List the widgets this image holds, optionally those whose name starts with a prefix. Use widget_get to read one.'
89
-
90
- MyProjectToolListWidgets >> additionalKeywords
91
-
92
- ^ #( 'widget' 'inventory' )
93
-
94
- MyProjectToolListWidgets >> annotations
95
-
96
- ^ MCPStructureToolAnnotations readOnly
97
-
98
- MyProjectToolListWidgets >> buildInputSchema
99
-
100
- ^ MCPStructureInputSchema new
101
- type: 'object';
102
- properties: { (self
103
- schemaPropertyNamed: 'prefix'
104
- type: 'string'
105
- description: 'Only answer widgets whose name starts with this. Defaults to all of them.') };
106
- required: #( );
107
- yourself
108
-
109
- MyProjectToolListWidgets >> executeWithRequest: request
110
-
111
- | prefix names |
112
- prefix := request stringArgumentNamed: 'prefix' default: ''.
113
- names := (MyProject widgetNames select: [ :each | each beginsWith: prefix ]) asArray sorted.
114
- ^ self
115
- successResultText: names size asString , ' widget(s): ' , (', ' join: names) , '.'
116
- data: { (#widgets -> names) } asDictionary
117
- ```
118
-
119
- `MyProject widgetNames` stands for your own code. What the rest is for:
120
-
121
- - **`toolName`** is the key in one catalog shared with every other tool the
122
- image has loaded, so pick a first word that is yours. `widget_list` is
123
- safe; `class_search` is taken.
124
- - **`description`** is read by a model deciding whether to call you. Say what
125
- the tool answers and name the tools that come next, the way the example
126
- points at `widget_get`.
127
- - **`additionalKeywords`** are the words `tool_search` matches besides the
128
- ones already in the name and title.
129
- - **`annotations`** tell a client what the tool does to the image.
130
- `MCPStructureToolAnnotations readOnly` promises it changes nothing;
131
- `mayModify` says otherwise. A host may require a confirmation for the
132
- second.
133
- - **`buildInputSchema`** is the contract the server validates an incoming
134
- call against before your code runs. `additionalProperties` defaults to
135
- false, so a caller that misspells an argument is told so instead of having
136
- it ignored. Every property takes a description; it is the only place the
137
- caller learns what the argument means.
138
-
139
- ## Being served
140
-
141
- A tool is served because its package was loaded, and naming itself is how a
142
- class says it is a tool. Nothing else is needed: load `MyProject-MCP` and
143
- every server in the image has `widget_list`.
144
-
145
- It is the tool's **own** name that serves it, not an inherited one. A
146
- subclass of a tool is a variation of that tool, so specialising one does not
147
- claim the name it already holds — give the subclass its own `toolName` when
148
- it is a tool of its own.
149
-
150
- A class that must stay out of every catalog says so itself:
151
-
152
- ```smalltalk
153
- MyProjectTestTool class >> shouldAutoRegister
154
-
155
- ^ false
156
- ```
157
-
158
- That is the right thing for a test fixture, which would otherwise be served
159
- by every server in the image whose tests are loaded.
160
-
161
- ## Reading arguments
162
-
163
- `executeWithRequest:` receives an `MCPToolRequest` whose arguments have
164
- already been validated against your schema. Read them with the typed
165
- accessors rather than by hand, so a missing or oddly typed value fails in one
166
- place:
167
-
168
- ```smalltalk
169
- request stringArgumentNamed: 'name'.
170
- request stringArgumentNamed: 'name' default: 'anything'.
171
- request stringArgumentNamed: 'side' in: #( 'instance' 'class' ) default: 'instance'.
172
- request booleanArgumentNamed: 'force' default: false.
173
- request nonNegativeIntegerArgumentNamed: 'offset' default: 0.
174
- request stringCollectionArgumentNamed: 'packages' default: #( ).
175
- request hasArgumentNamed: 'prefix'.
176
- ```
177
-
178
- ## Answering
179
-
180
- Two answers, both built by the tool:
181
-
182
- ```smalltalk
183
- self successResultText: 'Three widgets.' data: { (#widgets -> names) } asDictionary.
184
- self errorResultText: 'No widget named ' , name , '.' details: { (#known -> names) } asDictionary
185
- ```
186
-
187
- The text is what a model reads; the data is the same answer in a shape a
188
- program can use. Give both. A text that says only "Done." costs the caller
189
- another round trip to find out what happened.
190
-
191
- You do not have to catch to report a failure. An exception that escapes
192
- `executeWithRequest:` is answered as an error result naming your tool, the
193
- error class, the message and the frames of your own code; the server leaves
194
- its own frames out. Build an error result yourself when you know something
195
- the exception does not, such as what the caller should have asked for.
196
-
197
- Which of the two reaches the client is the server's choice, not the tool's.
198
- `toolResponseFields` defaults to `#content`, where the data is rendered into
199
- the text. `useContentAndStructuredContentToolResponses` sends both, and
200
- `useStructuredContentOnlyToolResponses` sends only the structured half. The
201
- structured half carries your text as `summary` and your dictionary as `data`.
202
-
203
- ### Answering a page
204
-
205
- A tool that answers a list answers one page of it, so a long result never
206
- arrives as one block a model has to read through. Three parts: the shared
207
- `offset` argument, how big a page is, and the slicing. The listing tool
208
- again, now that the list can be long:
209
-
210
- ```smalltalk
211
- MyProjectToolListWidgets >> buildInputSchema
212
-
213
- ^ MCPStructureInputSchema new
214
- type: 'object';
215
- properties: { self offsetInputProperty };
216
- required: #( );
217
- yourself
218
-
219
- MyProjectToolListWidgets >> defaultPageLimit
220
-
221
- ^ 25
222
-
223
- MyProjectToolListWidgets >> executeWithRequest: request
224
-
225
- | page |
226
- page := MCPPaginationResult
227
- fromEntries: MyProject widgetNames asArray sorted
228
- limit: self defaultPageLimit
229
- offset: (request nonNegativeIntegerArgumentNamed: 'offset' default: 0).
230
- ^ self
231
- successResultText: page returnedCount asString , ' widget(s).'
232
- data: (page asDictionaryWithEntriesKey: #widgets)
233
- ```
234
-
235
- `offsetInputProperty` is the same `offset` argument every paging tool takes,
236
- declared once so they all describe it the same way. `MCPPaginationResult`
237
- cuts the page and answers the shape MCP's own tools answer: your entries
238
- under the key you name, a `pagination` summary beside them, and `nextOffset`
239
- while entries remain — a caller asks again with that offset until it stops
240
- coming.
241
-
242
- Answering `defaultPageLimit` is what puts `pageSize` in your contract, so
243
- `tool_get` can tell a caller how large a page is before asking for one. A
244
- tool that answers a whole result rather than pages leaves it alone.
245
-
246
- ## Groups and icons
247
-
248
- `groupName` is how the catalog and the world-menu browser group related
249
- tools. Pick one for your project and answer it on the shared superclass.
250
-
251
- MCP reads an icon out of a tool name whose words it recognises — `class`,
252
- `method`, `search`, `create` — which is how its own tools stay consistent
253
- without anyone choosing. Your words are not in that vocabulary, so declare an
254
- icon:
255
-
256
- ```smalltalk
257
- MyProjectTool class >> toolIconSpec
258
-
259
- ^ MCPToolIconSpec baseIconNamed: #pharoHalfScale badgeIconNamed: #browse
260
- ```
261
-
262
- ## A resource
263
-
264
- A resource is a document the host can put in front of the model without the
265
- model asking. Where a tool answers a question, a resource is material:
266
-
267
- ```smalltalk
268
- MCPResource << #MyProjectWidgetResource
269
- package: 'MyProject-MCP'
270
- ```
271
-
272
- ```smalltalk
273
- MyProjectWidgetResource class >> resourceUri
274
-
275
- ^ 'myproject://widgets'
276
-
277
- MyProjectWidgetResource class >> resourceName
278
-
279
- ^ 'widgets'
280
-
281
- MyProjectWidgetResource >> title
282
-
283
- ^ 'Widget Inventory'
284
-
285
- MyProjectWidgetResource >> description
286
-
287
- ^ 'Every widget this image holds, as JSON.'
288
-
289
- MyProjectWidgetResource >> mimeType
290
-
291
- ^ 'application/json'
292
-
293
- MyProjectWidgetResource >> readContents
294
-
295
- ^ self textContents: (STONJSON toStringPretty: { (#widgets -> MyProject widgetNames) } asDictionary)
296
- ```
297
-
298
- The URI is the key in the registry, and the same rule applies: a resource
299
- that names itself is served.
300
-
301
- ### A family of resources
302
-
303
- When the document is one of many, named by something in the URI, subclass
304
- `MCPResourceTemplate`. It names itself with a `resourceUriTemplate` in RFC
305
- 6570 form, resolves one URI at a time through `resourceForUri:`, and may
306
- suggest values for its variables:
307
-
308
- ```smalltalk
309
- MyProjectWidgetTemplate class >> resourceUriTemplate
310
-
311
- ^ 'myproject://widget/{name}'
312
-
313
- MyProjectWidgetTemplate >> resourceForUri: aUri
314
-
315
- | name |
316
- (aUri beginsWith: MyProjectOneWidgetResource resourceUri) ifFalse: [ ^ nil ].
317
- name := aUri allButFirst: MyProjectOneWidgetResource resourceUri size.
318
- ^ name
319
- ifEmpty: [ nil ]
320
- ifNotEmpty: [ MyProjectOneWidgetResource named: name ]
321
-
322
- MyProjectWidgetTemplate >> completionsFor: aVariableName value: aPrefix context: aContextDictionary
323
-
324
- aVariableName = 'name' ifFalse: [ ^ #( ) ].
325
- ^ MyProject widgetNames select: [ :each | each beginsWith: aPrefix ]
326
- ```
327
-
328
- A template lists through `resources/templates/list` and never answers
329
- contents of its own.
330
-
331
- What it resolves to is an ordinary resource built per URI rather than
332
- registered. It carries the name it was built with, answers its own `uri`, and
333
- keeps itself out of the catalog, where one entry standing for the whole family
334
- would be wrong:
335
-
336
- ```smalltalk
337
- MyProjectOneWidgetResource class >> resourceUri
338
-
339
- ^ 'myproject://widget/'
340
-
341
- MyProjectOneWidgetResource class >> shouldAutoRegister
342
-
343
- ^ false
344
-
345
- MyProjectOneWidgetResource class >> named: aName
346
-
347
- ^ self new
348
- widgetName: aName;
349
- yourself
350
-
351
- MyProjectOneWidgetResource >> uri
352
-
353
- ^ self class resourceUri , self widgetName
354
-
355
- MyProjectOneWidgetResource >> name
356
-
357
- ^ self widgetName
358
-
359
- MyProjectOneWidgetResource >> readContents
360
-
361
- ^ self textContents: (MyProject describeWidgetNamed: self widgetName)
362
- ```
363
-
364
- ## A prompt
365
-
366
- A prompt is user-controlled where a tool is model-controlled: a client
367
- usually shows them as slash commands, so a prompt is something a person
368
- reaches for deliberately.
369
-
370
- ```smalltalk
371
- MyProjectReviewPrompt class >> promptName
372
-
373
- ^ 'review_widget'
374
-
375
- MyProjectReviewPrompt >> title
376
-
377
- ^ 'Review A Widget'
378
-
379
- MyProjectReviewPrompt >> description
380
-
381
- ^ 'Asks for a review of one widget.'
382
-
383
- MyProjectReviewPrompt >> arguments
384
-
385
- ^ { (MCPStructurePromptArgument name: 'widget' description: 'The widget to review.' required: true) }
386
-
387
- MyProjectReviewPrompt >> messagesFor: anArgumentDictionary
388
-
389
- ^ self userMessage: 'Review the widget named ' , (anArgumentDictionary at: 'widget')
390
- , ' and say what you would change.'
391
- ```
392
-
393
- Like a template, a prompt may answer `completionsFor:value:context:` for its
394
- own arguments.
395
-
396
- ## Shaping the server's surface
397
-
398
- Two words govern it. A **registered** tool is in the catalog: callable by
399
- name, and findable with `tool_search` and `tool_get`. An **advertised** tool
400
- is also in `tools/list`, which is the list a client shows a model up front.
401
- Advertising decides what is shown, not what may be called.
402
-
403
- A tool from outside MCP is registered and discoverable, not advertised, so it
404
- costs nothing in the client's context until something looks for it. Answer
405
- `'static'` from `defaultExposure` to be in `tools/list` from the start.
406
-
407
- Against that default, a server is configured directly:
408
-
409
- ```smalltalk
410
- mcp := MCP new.
411
- mcp addTool: MyProjectToolListWidgets. "or addTools: { A. B }"
412
- mcp removeTool: 'image_evaluate'.
413
- mcp advertiseTool: MyProjectToolListWidgets. "adds one to what is advertised"
414
- mcp advertiseTools: { MyProjectToolListWidgets }. "replaces the advertised set"
415
- mcp advertiseAllTools.
416
- mcp advertiseToolDefaults.
417
- mcp port: 4000.
418
- mcp start.
419
- ```
420
-
421
- `MCP startOnPort:` on the class side answers the server already on that port,
422
- or builds one with the default catalog. A server you configured is started
423
- through the instance, as above.
424
-
425
- For a server holding only your own tools:
426
-
427
- ```smalltalk
428
- mcp := MCP onlyTools: { MyProjectToolListWidgets. MyProjectToolGetWidget }.
429
- mcp port: 4000.
430
- mcp start.
431
- ```
432
-
433
- `onlyTools:` replaces the catalog with exactly those, advertises all of them,
434
- and discovers nothing afterwards. That includes the catalog tools: a server
435
- built this way has no `tool_search`, `tool_get` or `tool_call` unless you add
436
- them back. Add `MCPToolSearchTools`, `MCPToolGetTool` and `MCPToolCallTool`
437
- when you want a surface a model can explore, or build up from `MCP new` with
438
- `addTool:` instead.
439
-
440
- ## Testing what you serve
441
-
442
- A server answers its JSON-RPC methods as plain messages, so a test needs no
443
- socket and no port:
444
-
445
- ```smalltalk
446
- MyProjectToolTest >> testListingAnswersEveryWidget
447
-
448
- | result |
449
- result := (MCP new useContentAndStructuredContentToolResponses; yourself)
450
- rpcToolCall: 'widget_list' withParams: Dictionary new.
451
- self assert: (((result at: #structuredContent) at: #data) at: #widgets) equals: #( 'alpha' 'beta' 'gamma' ).
452
- self assert: (((result at: #content) first at: #text) beginsWith: '3 widget(s)')
453
- ```
454
-
455
- Assert on the data rather than on the whole text: under the default
456
- `#content`, the text a client receives is your summary with the data rendered
457
- underneath it, so an equality test on it breaks whenever either half changes.
458
-
459
- `rpcResourceRead:`, `rpcPromptGet:arguments:`, `rpcToolsList`,
460
- `rpcResourcesList` and `rpcPromptsList` are there for the same purpose.
461
-
462
- ## Things that bite
463
-
464
- - **A name already taken.** The catalog holds one tool per name. Prefix with
465
- a word that is yours.
466
- - **A subclass of an existing tool is not served** until it names itself.
467
- That is deliberate: it would otherwise claim its superclass's name and the
468
- two would race for the key.
469
- - **A fixture in a loaded test package is served** like anything else.
470
- Answer `false` from `shouldAutoRegister`.
471
- - **`onlyTools:` drops the catalog tools.** See above.
472
- - **Nothing is saved.** Tools change the running image and never write it to
473
- disk. `Smalltalk saveSession` is the caller's business, not the tool's.
@@ -1,70 +0,0 @@
1
- # Debugging Tools
2
-
3
- Applies when using MCP-Pharo to watch values while code runs, or to see what
4
- debuggers a person has open.
5
-
6
- ## Goal
7
-
8
- See what running code is doing without guessing from source and without driving
9
- the Morphic debugger by hand.
10
-
11
- Debugger tools are discoverable, not part of the default static surface.
12
-
13
- ## Discovery Flow
14
-
15
- 1. Use `tool_search` with a query such as `watch` or `debugger`.
16
- 2. Use `tool_get` for the exact schema of the tool you plan to call.
17
- 3. If the current client exposes a catalog bridge, use `tool_call` to invoke
18
- the selected tool by name. Otherwise use the callable form exposed by the
19
- current client.
20
-
21
- ## Tool Map
22
-
23
- | Tool | Use |
24
- | --- | --- |
25
- | `debug_watch` | Record what variables hold while an expression runs, without stopping it. |
26
- | `debug_search` | Answer the debuggers open in the image, read-only. |
27
-
28
- Neither tool keeps anything. No session is started, attached or registered, so
29
- there is no reference to carry between calls and nothing to clean up.
30
-
31
- ## Watching Values
32
-
33
- `debug_watch` is print debugging without editing the method. Name the methods to
34
- probe, the variables to record, and the expression to run. Every assignment to a
35
- named variable is recorded as it happens, the expression runs to completion, and
36
- the probes are removed before the call answers.
37
-
38
- Name no variable and each method's arguments are recorded as it is entered.
39
- Both `method` and `variable` take one value or a list, and a probe goes on every
40
- pair that exists, so a variable a method never assigns simply has no series there.
41
-
42
- Reach for it whenever the question is what a value became, rather than where to
43
- intervene.
44
-
45
- ## Seeing A Person's Debuggers
46
-
47
- `debug_search` answers the debuggers open in the image: each one's name, the
48
- exception it stopped on, and the frames nearest the stop with what those frames
49
- hold. Pass a `query` to keep only the debuggers whose name or exception matches.
50
-
51
- It is a query and nothing else. It attaches to nothing, changes nothing, and
52
- remembers nothing, so the picture it gives is whatever is open at that moment.
53
- Ask again for a fresh one.
54
-
55
- Act on what it shows with the ordinary tools: read the method with `method_get`,
56
- change it with `method_compile`, run something with `image_evaluate`. Stepping,
57
- resuming and repairing from inside a frame belong to the person at the debugger,
58
- not to the agent.
59
-
60
- ## To Debug Your Own Code
61
-
62
- Do not open a debugger for it. Call the tool that runs the code and read the
63
- failure it reports: it names the frames nearest the error and the values they
64
- held. When that is not enough, `debug_watch` shows how a value got there.
65
-
66
- ## Do Not
67
-
68
- - Do not drive debugger windows or mutate contexts through general
69
- `image_evaluate` code.
70
- - Do not resume, step or terminate a person's debugger. It is theirs.