ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/AnyEvent-MCP/lib/AnyEvent/MCP/Intro.pod
Revision: 1.26
Committed: Fri Oct 30 16:11:22 2026 UTC (5 days, 6 hours ago) by root
Branch: MAIN
CVS Tags: rel-0_71
Changes since 1.25: +5 -3 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3 root 1.5 AnyEvent::MCP::Intro - using MCP servers, clients and permissions
4 root 1.1
5     =head1 DESCRIPTION
6    
7 root 1.5 You can use the servers in this distribution without writing any Perl.
8     This walkthrough starts with one filesystem server, connects it to an MCP
9     client, and makes a useful request. Once that works, it explains persistent
10     configuration, permissions and combining several servers.
11 root 1.1
12 root 1.5 If you want to write a small server yourself, continue with
13     L<AnyEvent::MCP::Server::Simple/TUTORIAL>. Applications needing their own
14     connection management or dispatch can use the modules described in
15     L<AnyEvent::MCP/MODULES>.
16 root 1.1
17 root 1.5 The examples use C</home/alice/src/project> as an existing project directory.
18     Replace it with your own absolute path. Commands shown here are commands
19     for you to run; requests addressed to the LLM are shown separately.
20    
21     =head1 INSTALLATION
22    
23     Install the Perl distribution and the external programs used by the
24     servers. Installing one does not install the other.
25    
26     For mcp-fs, install Linux bubblewrap and the filesystem utilities. On
27     Debian or Ubuntu, for example:
28    
29     sudo apt install bubblewrap findutils grep patch sed perl yad
30    
31     C<yad> is optional: it supplies graphical permission dialogs.
32     Without a usable YAD dialog, the helper tries C</dev/tty>; if neither is
33     available, it denies the request. Bubblewrap's executable is C<bwrap>.
34     The machine must allow the unprivileged user namespaces it needs.
35    
36     mcp-fs detects its utilities at startup and omits tools whose utilities
37     are unavailable or unsuitable. It requires bubblewrap by default.
38     See L<mcp-fs/TRUSTED CONFIGURATION> for explicit utility paths and
39     L<mcp-fs/LIMITATIONS> for the sandbox's limits.
40    
41     If you have an unpacked distribution or source checkout, run these commands
42     in its top-level directory:
43    
44     perl Makefile.PL
45     make
46     make test
47     make install
48    
49     C<perl Makefile.PL> reports missing Perl dependencies. Install those with
50     your usual package manager or CPAN client before continuing. For example,
51     the main non-core dependencies can be installed with:
52    
53 root 1.24 cpan AnyEvent AnyEvent::HTTP common::sense JSON::XS
54    
55     C<mcp-webbrowser> requires C<AnyEvent::WebSocket::Server> and
56     C<AnyEvent::WebSocket::Message>. C<mcp-vim> needs them only for browser
57     connections, not for ordinary Vim clients. Both modules are recommended
58     rather than required by the distribution.
59 root 1.5
60     Use the same Perl installation for dependency installation, building and
61     running the servers. A module installed for the system Perl might not be
62     available to a Perl installed under C</opt>. C<make install> needs write
63     access to the selected Perl's installation directories; use an appropriate
64     local Perl installation or run that final step with the required privileges.
65    
66 root 1.15 Installation puts C<mcp-fs>, C<mcp-multibroker>, C<mcp-vim>, C<mcp-webbrowser>,
67 root 1.5 C<mcp-ask-user>, C<anyevent-mcp> and C<anyevent-mcp-askpermission> in the
68     selected executable directory. Make that directory available in the
69     environment of your MCP client, or configure absolute executable paths.
70     A desktop application need not have the same C<PATH> as your shell.
71    
72     To try an uninstalled source tree after installing its dependencies, you
73     can run a program with the source library path:
74    
75     perl -Ilib bin/mcp-fs --stdio --name code /home/alice/src/project
76    
77     Do this from the distribution directory. When configuring a client to
78     start such a command, account for the client's working directory or use
79     absolute paths to Perl, C<lib> and the script. An installed executable
80     avoids that extra setup.
81    
82 root 1.19 =head1 PICK A SERVER
83 root 1.15
84 root 1.19 For a local MCP client, configure it to launch the server that provides
85     the tools you want:
86 root 1.15
87 root 1.19 mcp-fs --stdio /home/alice/src/project
88     mcp-vim --stdio
89 root 1.15 mcp-webbrowser --stdio
90 root 1.19 mcp-ask-user --stdio
91    
92     C<--stdio> means the MCP client launches the process. Do not start a
93     separate copy in a terminal. For HTTP clients, use a running server and
94     its C<--print-url> instead, as explained below.
95    
96     C<mcp-fs> reads, searches and changes files and runs commands in a sandbox.
97     The first walkthrough below uses this server.
98    
99     C<mcp-vim> reads and edits live Vim buffers. Install the companion Vim plugin
100     and connect the editor to its listener; see L</Add a live Vim editor> and
101     L<mcp-vim/VIM PLUGIN INSTALLATION>.
102 root 1.15
103 root 1.19 C<mcp-webbrowser> works with explicitly approved browser tabs. Install
104     its companion userscript and connect each tab you want to expose; see
105     L</CONNECTED BROWSER PAGES>.
106 root 1.16
107 root 1.19 C<mcp-ask-user> lets the assistant ask you questions through a local
108     YAD or terminal dialog, or through the client's native form UI; see
109     L</Ask the client's human a question>.
110 root 1.15
111 root 1.20 To offer several servers over one MCP connection, use C<mcp-multibroker>.
112     It combines these servers with each other or with third-party MCP servers,
113     whether started locally over stdio or reached over HTTP. Their tools
114     appear under separate name prefixes; see L</COMBINING SERVERS> and
115     L<mcp-multibroker> for the full command syntax.
116 root 1.15
117 root 1.5 =head1 YOUR FIRST FILESYSTEM SERVER
118    
119     Start with one project and one connection. You do not need a multibroker,
120     a hand-written configuration file or saved permission rules yet.
121    
122     =head2 Choose stdio or HTTP
123    
124     Use B<stdio> when your MCP client runs on the same machine and can launch
125     a server process. Configure the client to start the following command:
126    
127     mcp-fs --stdio --name code /home/alice/src/project
128    
129     The client starts this process and uses its stdin/stdout for MCP.
130     You do not start a second copy in a terminal, and there is no listener
131     URL or HTTP token to configure. Diagnostics go to stderr.
132    
133     Clients that take a command and an argument array need these values:
134    
135     command: mcp-fs
136     arguments: --stdio, --name, code, /home/alice/src/project
137    
138     These describe separate arguments, not one shell command string.
139     Use an absolute executable path if the client cannot find C<mcp-fs>.
140     See L</CLIENT EXAMPLES> for examples of particular clients.
141    
142     Use B<HTTP> when the client connects to an already-running server, or when
143     it cannot launch a local process. Start this in a terminal on the server
144     machine and leave it running:
145    
146     mcp-fs --name code --bind :31741 /home/alice/src/project
147    
148     In another terminal, obtain the matching connection URL:
149    
150     mcp-fs --name code --bind :31741 --print-url
151    
152     The second command prints a credential-bearing URL and exits without
153     opening a listener. Configure that URL in the client. The default address
154     is IPv4 loopback, so this example is reachable from the same machine only.
155     A hosted client needs a suitable tunnel or reachable endpoint; its own
156     C<localhost> is not your computer.
157    
158     Repeat the same name and listener overrides when printing the URL.
159     Both commands must use the same user and configuration directory.
160     Port zero chooses an ephemeral port, which C<--print-url> cannot predict;
161     use an explicit port for this walkthrough.
162    
163     The HTTP server generates and saves its private master secret when needed.
164     You can initialize it explicitly with C<anyevent-mcp init>, but that
165     command is unnecessary when configuration already exists and will refuse
166     to replace it. Keep the printed URL private: possession of its token
167     authenticates a client.
168    
169     =head2 Make a useful request
170    
171     Once your client reports that the server is connected, ask the LLM:
172    
173     Show me the configured workdirs. List the top-level files in the
174 root 1.19 project, then read its README if it has one. Do not modify files
175     or run commands.
176 root 1.5
177     C<workdirs> returns the configured paths, sandbox grants, trusted mounts
178     and runtime paths. Listing names requests C<inspect> permission; reading
179     contents requests C<read> permission. Expect a permission prompt when
180     there is no saved rule allowing the operation.
181    
182     Choose C<Allow once> for the first operation. The worker then runs with
183     the requested sandbox grants. A denial is a tool failure that the LLM
184     should report, rather than an empty file or a disconnected server.
185    
186     For a slightly larger task, ask:
187    
188     Find TODO comments in this project and explain the three that look
189     most useful to address next. Do not modify files or run commands.
190    
191     This can use C<find>, C<grep> and C<read-lines>. You need not write MCP
192     requests yourself. If a client offers its own tool-approval prompt, that
193     is an additional client policy; it does not replace mcp-fs's permissions.
194    
195 root 1.19 =head2 Give the server a purpose
196    
197     To explain why an instance exists, provide a short purpose:
198    
199     mcp-fs --stdio --name memory \
200     --custom-instructions 'Use this server to retrieve and store persistent memory.' \
201     /home/alice/memory
202    
203     For persistent configuration, use C<custom_instructions> in the global
204     configuration's C<[program mcp-fs]> or C<[instance memory]> section. Instance
205     settings override program settings; the command line overrides both.
206     This purpose appears first in the advertised MCP instructions so a model can
207     decide whether to discover the server's tools.
208    
209     Servers using C<AnyEvent::MCP::Server::Simple> also expose the instance
210     purpose and complete operating instructions as a C<meta-instructions> tool
211     description. Calling that tool returns the complete text when a client
212     truncates descriptions. Clients that understand MCP server instructions
213     still receive a short purpose or routing hint at discovery time, followed
214     by an automatic pointer to the full instructions in the tool description.
215    
216 root 1.5 =head2 Understand the workdir
217    
218     The directory passed at startup tells mcp-fs which workdir to expose.
219     It does not grant permission for every operation in that directory.
220     Each operation still requests its action and sandbox grants.
221    
222     With one workdir, tools can omit the C<workdir> argument. With several:
223    
224     mcp-fs --stdio --name code /home/alice/src/project /home/alice/notes
225    
226 root 1.14 tools select one using a persistent positive integer ID, a numeric string
227     or an exact configured/resolved path returned by C<workdirs>. The
228     C<workdirs> and C<resolved_workdirs> objects use these IDs as keys.
229     Relative tool paths are relative to that selection. Permission rules
230     continue to use the configured path, not its numeric ID.
231    
232     IDs are shared across filesystem servers in
233     C<$XDG_CONFIG_HOME/anyevent-mcp/fs-workdir-ids.json>, or under
234     C<$HOME/.config> by default. They identify resolved absolute paths and
235 root 1.15 survive restarts and argument reordering. Startup resolves IDs once and
236     reserves new allocations under the lock. A timer runs immediately and every
237     5.25 days to reread the registry and refresh the server's fixed assignments.
238     Other entries expire after seven days and their IDs may be reused. Restart
239     servers after manually changing the registry.
240 root 1.5
241     C<workdir-read> exposes the selected workdir read-only.
242     C<workdir-write> makes it writable and implies read access.
243     A path in another configured workdir requires all-workdirs authority;
244     a path elsewhere requires suitable home/world or shared-tmp authority.
245     A symlink cannot make an unmounted target appear inside the sandbox.
246    
247     Prefer separate, non-overlapping workdirs. Overlapping mounts have
248     unspecified access effects. See L<mcp-fs/SANDBOX GRANTS> before granting
249     access beyond the selected workdir.
250    
251 root 1.6 =head2 Inspect version-control changes
252    
253     For a Git, SVN, CVS or Mercurial working copy, ask the LLM to use
254     C<vcs-diff> and C<vcs-status>, with C<backend> set to C<git>, C<svn>, C<cvs>
255     or C<hg>. C<workdirs> reports the available clients. These tools accept
256     filenames and construct the command themselves; no shell pipeline or arbitrary
257     VCS options need to be approved.
258    
259     For example:
260    
261     Show the CVS diff for this project, limited to 200 lines.
262     Then show its status, keeping stdout lines matching "File:|Status:".
263    
264     These operations have their own permission actions. They request read access
265 root 1.19 to the selected workdir. CVS additionally requests the C<ssh-agent> grant,
266     which includes network access, the agent socket and C<known_hosts>, but not
267     general home-directory access. Read permission for ordinary file tools does
268     not automatically authorize a VCS operation.
269 root 1.6
270     For arbitrary C<exec> commands, the same output options are available:
271     C<grep> filters stdout using PCRE, C<max_lines> limits matching stdout lines,
272     and C<max_bytes> bounds returned bytes per stream. Prefer these options to a
273     shell wrapper that mixes execution and output processing. Stderr is unfiltered,
274     and exit status still describes the original command.
275    
276     Defaults return at most 2000 stdout lines and 64 KiB per stream. Raw capture
277     has a separate 1 MiB limit per stream. A true C<capture_truncated> means
278     output was omitted before filtering or collection ended on timeout, so absent
279     matches do not prove the omitted output had none. See L<mcp-fs/Command output>
280     for all result flags and limits.
281    
282 root 1.5 =head1 CONFIGURING YOUR SETUP
283    
284     There are three different things to configure: how the client connects,
285     how the server runs, and which operations the user allows. Changing one
286     does not necessarily change the other two.
287    
288     =head2 Where each setting belongs
289 root 1.1
290     =over
291    
292 root 1.5 =item Directories to expose
293    
294     Pass workdirs on the mcp-fs startup command. For a stdio server, that
295     command belongs in the client's server configuration. For an HTTP server,
296     it belongs in the command used to run the service.
297 root 1.1
298 root 1.5 =item Connection transport
299 root 1.1
300 root 1.5 The client launches a command for stdio or connects to a URL for HTTP.
301     C<--stdio> selects the former for mcp-fs and the multibroker.
302 root 1.1
303 root 1.5 =item Listener address, port and tokens
304 root 1.1
305 root 1.5 Use C<[instance NAME]> in the global configuration or command-line
306     C<--bind> and C<--token> overrides.
307 root 1.1
308 root 1.5 =item Trusted mounts and utility paths
309    
310     For mcp-fs, use C<[program NAME]> defaults and C<[instance NAME]>
311     overrides in the global configuration.
312    
313     =item Allowed operations and sandbox grants
314    
315     Use the permission rules file, normally created through approval dialogs.
316     This file is separate from the global configuration.
317    
318     =item Location of permission prompts
319    
320 root 1.12 Use C<--ask helper>, C<--ask tty>, C<--ask yad>, C<--ask auto> or C<--ask mcp>, or set
321 root 1.5 C<PERL_ANYEVENT_MCP_PERMISSION_ASK> in the server's environment.
322    
323     =item Combined server connections
324    
325     Put prefix/server pairs on the multibroker startup command. HTTP child
326     credentials can also use C<[client PREFIX]> in the global configuration.
327 root 1.1
328     =back
329    
330 root 1.5 =head2 One complete named configuration
331    
332     The global file is C<$XDG_CONFIG_HOME/anyevent-mcp/global.ini>, falling
333     back to C<$HOME/.config/anyevent-mcp/global.ini>. Settings are UTF-8
334     C<key = value> lines; values are unquoted. Whole-line C<#> and C<;>
335     comments are allowed. See L<AnyEvent::MCP/GLOBAL CONFIGURATION> for the
336     complete format.
337    
338     Start with the existing file, preserving its C<[global]> secret.
339     If you have no file yet, C<anyevent-mcp init> creates it privately.
340 root 1.19 Add this section:
341 root 1.5
342     [instance code]
343     bind = 127.0.0.1:31741
344    
345     Now start:
346    
347     mcp-fs --name code /home/alice/src/project
348    
349     and retrieve its URL with:
350    
351     mcp-fs --name code --print-url
352    
353     Both use C<[instance code]>. No explicit token is needed: the server
354     derives one from its name and the existing master secret.
355    
356     For this setup:
357    
358     instance settings: [instance code]
359     selected workdir: /home/alice/src/project
360 root 1.8 permission file: ~/.config/anyevent-mcp/rules/fs-code.ini
361 root 1.5 rule-manager profile: fs-code
362    
363     The permission pathname above assumes the default configuration directory.
364     C<anyevent-mcp manage-rules fs-code> opens the graphical rule manager;
365     C<anyevent-mcp edit-rules fs-code> opens the file in your editor.
366    
367 root 1.19 Settings shared by all mcp-fs instances go in C<[program mcp-fs]>.
368     Instance settings override program settings.
369    
370 root 1.22 File ownership and permissions are under the user's control. The global
371     configuration contains a master authentication secret, so take care when
372     sharing it. C<--config FILE> on C<anyevent-mcp init>
373 root 1.5 selects that command's output file; it does not make the servers use an
374     arbitrary alternate file. Use the same C<HOME>/C<XDG_CONFIG_HOME>
375     environment when running the server and its management commands.
376    
377     =head2 Names, prefixes and profiles
378    
379     C<--name code> selects instance settings, derived HTTP credentials and
380 root 1.8 mcp-fs's C<rules/fs-code.ini>. Without C<--name>, mcp-fs uses C<default>,
381     giving profile C<fs-default>. Two processes with the same program, name and
382 root 1.5 configuration share credentials and rules, even if their workdirs differ.
383    
384     A multibroker prefix, such as C<files>, only routes tools: C<grep> becomes
385     C<files.grep>. It does not rename the child server or select its rules.
386     For example:
387    
388     mcp-multibroker files \
389     'stdio:mcp-fs --name code /home/alice/src/project'
390    
391     The tools are C<files.*>, but the child still uses instance C<code>
392     and rule-manager profile C<fs-code>. The multibroker's own C<--name>
393     selects its upstream listener settings.
394 root 1.1
395 root 1.5 =head2 Configuration changes and restarts
396 root 1.1
397 root 1.5 Command-line listener options override the named global settings.
398     For mcp-fs trusted settings, an instance entry overrides the corresponding
399     program entry; an empty instance mount value suppresses the inherited mount.
400 root 1.1
401 root 1.5 Workdirs, mounts, utility paths, listener settings and tokens are read at
402     startup. Change the file or startup command, then restart the affected
403     server. The multibroker also needs restarting to change its prefix/server
404     pairs; refreshing discovery does not change those pairs.
405    
406     Permission rules are reread on permission checks, so editing them does
407     not require a restart. A client's displayed tool list can still be cached.
408     After restarting a child, refresh tool discovery or reconnect the client
409     as described in L</COMBINING SERVERS>.
410    
411     =head1 PERMISSIONS IN PRACTICE
412    
413     HTTP authentication establishes that the client may connect.
414     Permission checks decide whether a tool may perform an operation.
415     A correct token therefore does not prevent permission prompts.
416    
417     =head2 What the prompt means
418    
419     The prompt describes an action, paths or command, a reason and sandbox
420     grants. For filesystem tools, the actions are:
421    
422 root 1.6 inspect stat, list, find
423     read file-read, read-lines, grep
424     write file-write, file-patch
425     manage path-op
426     exec arbitrary command execution
427     vcs-diff working-copy differences
428     vcs-status working-copy status
429 root 1.5
430     The action and grants are independent. Allowing C<read> does not allow
431     C<write>, even if a worker grant permits both kinds of filesystem access.
432     C<exec> runs arbitrary commands; it is not a classification of supposedly
433     safe command prefixes.
434    
435     Choose allow/deny once, or always. Closing the dialog denies once.
436     An optional denial reason is returned with the error; it is not added to
437 root 1.13 successful tool results. An always choice opens a rule editor. Choose an
438     indefinite lifetime (the default), 900 seconds or 16 hours. Finite lifetimes
439     are stored as C<expires> Unix timestamps. Expired rules disappear on every
440     read; the next ordinary save removes them from disk. Expiry affects future
441     permission checks, not operations already authorized.
442 root 1.5 Filesystem allow rules can select grants and the selected workdir when
443     the authority depends on it. Deny rules can also select an exact affected
444     path. Exec offers persistent command/argv subjects.
445    
446     For exec, C<View stdin...> lets you inspect supplied input without closing
447 root 1.9 the approval dialog. Filesystem and Vim patch tools similarly offer
448     C<View patch...>, including the target file or editor and buffer. Longer
449     text is shown as an explicitly incomplete preview. These are YAD button
450     labels; other interfaces can show the details inline.
451     That input is display-only: an exec allow rule does
452 root 1.5 not constrain future stdin. Allowing an interpreter command can therefore
453     allow a different script on its next invocation.
454    
455     A worker accessing several paths requests their combined sandbox authority
456     once. If the chosen grants are insufficient, it fails before starting.
457    
458     =head2 Save a useful read-only policy
459    
460     After trying individual operations, you might want the LLM to inspect and
461     read the project without asking each time, while keeping changes subject
462 root 1.8 to approval. Put these rules in C<rules/fs-code.ini>, or create equivalent
463 root 1.5 allow rules through the prompt:
464    
465     [rule]
466     decision=allow
467     action=inspect
468 root 1.25 match.workdir=/home/alice/src/project
469 root 1.5 sandbox-grants=workdir-read
470    
471     [rule]
472     decision=allow
473     action=read
474 root 1.25 match.workdir=/home/alice/src/project
475 root 1.5 sandbox-grants=workdir-read
476    
477     [rule]
478     decision=deny
479     action=exec
480 root 1.1
481 root 1.5 Use the exact workdir spelling passed at server startup. Absolute startup
482 root 1.22 paths make this easier. Rule-file permissions follow the usual Unix filesystem
483     rules; any user who can edit the file can change the server's approval policy.
484    
485     Without matching rules, write and manage operations still ask. The final rule
486     denies command execution outright; omit it if you want execution to ask instead.
487 root 1.1
488 root 1.5 Rules run in order, stopping at the first match. An allow rule matches only
489     when its grants cover the request, including implications.
490     C<workdir-write> implies C<workdir-read>; C<network> remains independent.
491 root 1.25 Action and C<match.NAME> match exactly unless beginning with C<^>, which
492     selects a Perl regular expression; workdir scopes use the same mechanism.
493 root 1.5 An explicit C<ask> rule can override later allow rules.
494    
495     These allow rules authorize sandbox access to the selected workdir.
496     They cannot confine authority to one file or a subtree inside it.
497     Filesystem operations do not offer persistent path subjects.
498     An exact C<path> matcher is available for deny rules only.
499     Trusted runtime and configured mounts remain baseline access independently
500     of these grants. See L<mcp-fs/TRUSTED CONFIGURATION>.
501    
502     =head2 Change or remove saved rules
503    
504     Use:
505    
506     anyevent-mcp manage-rules fs-code
507     anyevent-mcp edit-rules fs-code
508    
509     The first command lets you delete and reorder rules in YAD.
510     The second uses C<$VISUAL>, C<$EDITOR>, C<sensible-editor> or C<vi>.
511     An earlier deny or ask rule can explain why adding a later allow rule
512     does not change the result.
513    
514     For a custom application with another rule pathname, use:
515    
516     anyevent-mcp manage-rules-file /path/to/rules.ini
517     anyevent-mcp edit-rules-file /path/to/rules.ini
518    
519     A failed attempt to save a permanent rule is an error, not a successful
520 root 1.22 permanent approval. The file mode is preserved when saved through these
521     commands. For full syntax and programming interfaces, see
522 root 1.5 L<AnyEvent::MCP::Server::Permissions>.
523    
524     =head2 Choose where to ask
525    
526     The default C<helper> mode runs C<anyevent-mcp-askpermission> on the server
527     machine. It tries YAD, then C</dev/tty>, then denies if neither can be used.
528     The helper inherits the server's display environment.
529 root 1.12 C<--ask tty> and C<--ask yad> instead force the built-in terminal or YAD
530     interface. They ignore custom helper settings and never try another
531     interface. These modes work for permission prompts and ordinary forms,
532     including forms handled by a multibroker.
533 root 1.5 C<PERL_ANYEVENT_MCP_PERMISSION_HELPER> selects a different executable.
534    
535     For a modern client supporting MCP form elicitation, you can instead use:
536    
537     mcp-fs --stdio --name code --ask auto /home/alice/src/project
538    
539     C<auto> uses the client's form support when advertised for that request,
540     otherwise the local helper. C<mcp> requires that support and fails when
541     unavailable. It does not silently fall back. Use client-side permission
542     approval only when that client is a trusted authority to grant access.
543    
544     To set the default for servers using the shared permission engine:
545    
546     PERL_ANYEVENT_MCP_PERMISSION_ASK=auto \
547     mcp-fs --stdio --name code /home/alice/src/project
548    
549     An explicit application C<ask> setting or C<--ask> overrides the environment.
550 root 1.26 The multibroker sets this default to C<mcp> for spawned stdio children,
551     regardless of its own asking mode. Children delegate permission prompts to
552     their calling MCP client; the multibroker handles or forwards those prompts
553     according to its own C<--ask> mode. An explicit child C<--ask> still overrides
554     this default. Independently running HTTP servers keep their own configuration.
555 root 1.5
556 root 1.7 The multibroker can handle form elicitation locally for both stdio and HTTP
557     children. C<--ask helper> selects local dialogs even if the upstream client
558     advertises native forms; C<--ask mcp> forwards forms upstream, and C<auto>
559     uses native forms when advertised. If a client claims support but silently
560     declines questions, use C<helper>. A decline never causes a fallback prompt.
561    
562     Standalone C<mcp-ask-user> also supports these modes and defaults to the
563     local helper. A question is different from an approval: answering it does
564     not grant a filesystem worker any authority.
565 root 1.5
566     =head1 COMBINING SERVERS
567    
568 root 1.20 Once the first connection works, C<mcp-multibroker> lets you give the
569     client one connection for several MCP servers. It works with the servers
570     in this distribution and with third-party MCP servers, including ones
571     written in other languages. Each downstream server can be a local
572     subprocess communicating over stdio or an existing HTTP endpoint; you
573     can mix both in one broker. The broker discovers their tools and
574     forwards calls to the appropriate server without changing how that
575     server implements its tools.
576    
577     For example, combine two filesystem instances:
578 root 1.5
579     mcp-multibroker --name tools --bind :31740 \
580     code 'stdio:mcp-fs --name code /home/alice/src/project' \
581     notes 'stdio:mcp-fs --name notes /home/alice/notes'
582    
583     Quote each C<stdio:> shell command as one argument.
584     The broker supplies the child's stdio environment and starts ordinary
585     children lazily, on first use. The explicit child names give them separate
586     permission profiles C<fs-code> and C<fs-notes>.
587    
588     Obtain the upstream HTTP URL with:
589    
590     mcp-multibroker --name tools --bind :31740 --print-url
591    
592     Configure this URL in place of the client's old direct connection.
593     The client can now see C<code.grep>, C<code.read-lines>, C<notes.find>
594     and other prefixed tools. It does not need a separate connection to each
595     child.
596    
597     For a client launching the multibroker locally, configure:
598    
599     mcp-multibroker --stdio --name tools \
600     code 'stdio:mcp-fs --name code /home/alice/src/project' \
601     notes 'stdio:mcp-fs --name notes /home/alice/notes'
602    
603     C<--stdio> selects the upstream connection. The child commands still use
604     C<stdio:>; that selects each downstream connection independently.
605     No upstream HTTP URL is needed in this case.
606    
607 root 1.20 The same setup can include Vim, browser pages, a third-party stdio
608     server or a remote HTTP service. See L</Add an HTTP child> for an
609     example mixing local and remote servers, and L<mcp-multibroker/DOWNSTREAM
610     SERVERS> for the complete syntax, including direct argv execution,
611     credentials and per-child options.
612    
613 root 1.5 =head2 Discover and refresh tools
614    
615     Ask the LLM:
616    
617     Call discover-brokers and list-tools, then show me which servers
618     are available and what each is for.
619    
620 root 1.17 C<discover-brokers> returns advertised instructions (which may be short),
621     no instructions, or an error for each configured server.
622     C<list-tools> requests current tool definitions, including any prefixed
623     C<meta-instructions> tools and their full instruction descriptions;
624 root 1.5 unreachable servers are omitted. A reachable server can still fail later.
625    
626     If the client still has an old direct tool list, C<call-tool> can invoke
627     an exact prefixed name found by C<list-tools>. Refresh the client's MCP
628     connection if it continues to hide newly available tools.
629    
630 root 1.15 Discovery queries configured servers and currently registered reverse
631     connections. Changing the static downstream command still requires a restart.
632    
633     =head2 Let a server connect to the multibroker
634    
635     To add independently started servers without editing the multibroker command,
636     keep its HTTP/extension listener active alongside stdio:
637    
638     mcp-multibroker --stdio --listen --bind 127.0.0.1:31740
639     mcp-multibroker --bind 127.0.0.1:31740 --print-url
640    
641     Append an alias to the returned credential-bearing URL:
642    
643     mcp-fs --connect http://127.0.0.1:31740/TOKEN/files /home/alice/project
644    
645     The filesystem server initiates the TCP connection but remains the MCP server.
646     The multibroker authenticates the same token used for HTTP, registers the
647     alias and discovers the tools. A configured or connected alias cannot be
648     replaced. After disconnecting, the server retries once per second for sixty
649     attempts. Pending calls fail and are never replayed. Remote registration does
650     not grant the multibroker spawned-child shutdown authority.
651    
652     The hello is a raw JSON line, followed by ordinary MCP JSONL on the same socket;
653     the HTTP-shaped URL is an address and credential, not an HTTP request.
654     The bundled connector supports plain C<http://> endpoints. An HTTP listener is
655     already active by default when the upstream connection is HTTP.
656 root 1.5
657     =head2 Add an HTTP child
658    
659 root 1.20 A broker can mix spawned stdio servers and existing HTTP endpoints,
660     including independently implemented third-party servers:
661 root 1.5
662     mcp-multibroker --stdio \
663     code 'stdio:mcp-fs --name code /home/alice/src/project' \
664     remote https://example.org/mcp/ --bearer TOKEN
665    
666     C<--bearer> immediately after the HTTP pair belongs to that child.
667     C<--token> before all pairs configures the multibroker's own HTTP listener.
668     They authenticate different connections.
669    
670     To avoid putting a child's bearer token in the startup command, add:
671    
672     [client remote]
673     bearer = TOKEN
674     timeout = 300
675    
676     to the private global configuration, and omit C<--bearer> from the command.
677     The prefix C<remote> selects these client defaults. The command-line URL
678     still chooses the endpoint. Use the actual credential accepted by that
679     server, not the literal placeholder C<TOKEN>.
680    
681     A token already present in a child's URL needs no separate bearer option.
682     The bundled servers use static URL-safe tokens; they do not validate
683     OAuth access tokens or implement HTTP Basic authentication.
684     Use TLS or an appropriate tunnel when credentials cross untrusted networks.
685    
686     The multibroker does not put every child inside the mcp-fs sandbox.
687     Each process or remote service has its own authority and enforcement.
688    
689     =head2 Add a live Vim editor
690    
691     Install the Vim plugin using L<mcp-vim/VIM PLUGIN INSTALLATION>. It is
692     included in the source distribution but is not installed by Perl's
693     C<make install>.
694    
695 root 1.19 Without a multibroker, configure the MCP client to launch:
696    
697     mcp-vim --stdio --name editor
698    
699     Even in stdio mode, mcp-vim listens separately for editor connections.
700     If using a multibroker, start its child eagerly so Vim can connect
701     before the first MCP tool call:
702 root 1.5
703     mcp-multibroker --stdio \
704     code 'stdio:mcp-fs --name code /home/alice/src/project' \
705     vim 'stdio:mcp-vim --name editor' --eager
706    
707 root 1.19 In another terminal, obtain the editor broker's URL prefix:
708 root 1.5
709     mcp-vim --name editor --print-url
710    
711     Append the desired target name in Vim:
712    
713     :Mcp http://HOST:PORT/TOKEN/my-editor
714    
715     Use the actual printed prefix in place of C<http://HOST:PORT/TOKEN/>.
716 root 1.19 Ask the LLM to call C<targets>, then C<state> before reading or editing
717     buffers (C<vim.targets> and C<vim.state> through the multibroker).
718     These tools see live, possibly unsaved buffers. Edits require a current
719     changedtick and do not save files to disk.
720 root 1.5
721 root 1.13 To pass arguments directly, use C<PREFIX --- PROGRAM ARG... --->:
722    
723     mcp-multibroker --stdio \
724     vim --- mcp-vim --name editor --bind :: --- --eager \
725     code --- mcp-fs --name code '/home/alice/project with spaces' ---
726    
727     Only the invoking shell processes quoting. The broker passes all arguments
728     between the delimiters unchanged, including empty arguments and child options.
729     Use C<stdio:COMMAND> for shell syntax or a literal C<---> child argument.
730     An empty command or missing closing delimiter is an error.
731    
732     C<--eager> belongs immediately after its stdio URL or closing C<--->.
733 root 1.5 An eager connection failure is logged; the broker does not continuously
734     restart the child. Later tool use can try connecting again.
735    
736     =head2 Ask the client's human a question
737    
738 root 1.19 To let the assistant ask you questions, configure its MCP client to launch:
739    
740     mcp-ask-user --stdio
741    
742     Or add the question server to a multibroker:
743 root 1.5
744     mcp-multibroker --stdio \
745     code 'stdio:mcp-fs --name code /home/alice/src/project' \
746     questions 'stdio:mcp-ask-user'
747    
748 root 1.19 The LLM can call C<ask-user> (C<questions.ask-user> through the multibroker)
749     with a question, up to three suggested answers and room for free text.
750     For example, tell it to use that tool if choosing among several possible
751     tasks needs your input. For several fields or other value types,
752     C<ask-form> (C<questions.ask-form> through the multibroker) accepts
753 root 1.10 C<message> and C<requestedSchema> directly and returns the standard
754     elicitation response. Both tools use the same configured presentation mode.
755 root 1.5 Decline and cancel are distinct results; neither supplies an answer.
756    
757 root 1.7 By default the multibroker displays questions locally, using YAD or a terminal.
758     Add C<--ask mcp> before the broker entries to use the client's native forms,
759     or C<--ask auto> to select by advertised capability. This also works with
760     C<mcp-ask-user> started separately: give that server C<--ask mcp> so it
761     delegates presentation to its connecting multibroker.
762    
763     C<anyevent-mcp-form-elicitation> is the standalone form renderer. It reads standard MCP
764     form parameters as UTF-8 JSON on stdin and writes an accept/decline/cancel
765     response as JSON on stdout. C<PERL_ANYEVENT_MCP_ELICITATION_HELPER> selects
766     a replacement executable. See L<anyevent-mcp-form-elicitation> for supported fields
767     and L<mcp-ask-user> for question arguments and result fields.
768 root 1.5
769 root 1.19 =head1 CONNECTED BROWSER PAGES
770    
771     C<mcp-webbrowser> is the browser-page counterpart to C<mcp-vim>. It exposes
772     only tabs explicitly allowed by the browser user. Configure your MCP client
773     to launch:
774    
775     mcp-webbrowser --stdio
776    
777     The broker keeps its own HTTP/WebSocket listener active even in stdio mode;
778     the userscript connects to that listener, not to MCP's stdio stream.
779     In a separate terminal, obtain its URL:
780    
781     mcp-webbrowser --print-url
782    
783     Use the same instance name and configuration as the broker. Keep this
784     credential-bearing URL private.
785     Install the companion userscript from
786     C<webbrowser/mcp-webbrowser.user.js> in the source distribution or from
787     L<https://dist.schmorp.de/mcp-webbrowser/1/mcp-webbrowser.user.js>.
788     Chromium with ScriptCat has been tested. On a tab you want to expose,
789     choose B<Allow MCP access to this tab> from the userscript menu and enter
790     the printed URL when prompted. Other tabs remain unexposed.
791    
792 root 1.21 The broker supplies C<tabs>, C<execute> and C<add-element> tools, permission
793 root 1.19 prompts, cancellation and execution timeouts. See
794     L<mcp-webbrowser/USERSCRIPT INSTALLATION AND USE> for setup, compatibility
795     and the current ScriptCat discarded-tab limitation.
796    
797     If the multibroker launches the browser broker, keep that child running
798     from startup so browser tabs can connect:
799    
800     mcp-multibroker --stdio browser --- mcp-webbrowser --- --eager
801    
802 root 1.5 =head1 HTTP TOKENS AND SERVER IDENTITY
803    
804     For the ordinary bundled HTTP endpoints, a client can present an accepted
805     token in either of these ways:
806    
807     POST /TOKEN/
808     POST / Authorization: Bearer TOKEN
809    
810     URL tokens are path components, not browser cookies.
811     For another configured endpoint, C</TOKEN> prefixes that endpoint path.
812 root 1.23 The HTTP server also accepts C</TOKEN> and the corresponding bare path
813     without the final slash when the endpoint is configured with one. This
814     works around clients (observed with Claude) that drop the final slash
815     from a configured URL.
816 root 1.5 All accepted tokens authenticate the same operations; they are not separate
817     users or permission levels. Permissions still govern the tool operation.
818    
819     By default, the master secret and server name determine one stable token
820     and a port in 16384..32767. Changing a server's name changes its derived
821     credentials and default port. Changing or losing the master secret changes
822     all derived credentials. Keep an existing C<[global]> secret when editing
823     other configuration.
824    
825     To configure explicit tokens:
826    
827     [instance code]
828     tokens = first-secret,second-secret
829 root 1.1
830 root 1.5 Replace those placeholders with actual unguessable URL-safe tokens.
831     Repeated C<--token> options replace the whole configured list and the
832     derived default. The first token appears in C<--print-url>; all are accepted.
833     mcp-vim also accepts its token set for Vim and browser WebSocket connections.
834    
835     If C<--print-url> disagrees with the client's URL, compare the name,
836     command-line overrides, user and configuration environment with the running
837     process. The command resolves configuration; it does not ask the running
838     server which URL it uses. A changed file needs a server restart.
839    
840     An Origin allowlist restricts browser origins; it does not authenticate
841     clients. A CORS preflight can succeed without a token, while the MCP POST
842     still requires one. See L<AnyEvent::MCP::Server::HTTP/AUTHENTICATION> for
843     the low-level server interface.
844    
845     =head1 CLIENT EXAMPLES
846    
847     Client settings and command syntax evolve independently of this distribution.
848     These examples show the connection choices; consult the linked client
849     documentation if its interface differs. Replace illustrative paths and
850     credentials with your own.
851 root 1.1
852 root 1.5 =head2 OpenAI Codex CLI
853 root 1.1
854 root 1.5 For the first direct filesystem connection:
855 root 1.1
856 root 1.5 codex mcp add code -- \
857     mcp-fs --stdio --name code /home/alice/src/project
858 root 1.1 codex mcp list
859    
860 root 1.5 For a multibroker connection:
861    
862     codex mcp add mytools -- \
863     mcp-multibroker --stdio \
864     code 'stdio:mcp-fs --name code /home/alice/src/project'
865    
866 root 1.1 Use C</mcp> within Codex to inspect connections.
867     See L<Codex MCP documentation|https://learn.chatgpt.com/docs/extend/mcp>.
868    
869 root 1.5 =head2 Anthropic Claude Code
870 root 1.1
871 root 1.5 For the direct connection:
872 root 1.1
873 root 1.5 claude mcp add --transport stdio --scope user code -- \
874     mcp-fs --stdio --name code /home/alice/src/project
875 root 1.1 claude mcp list
876    
877 root 1.5 Replace the launched command with the multibroker command above when you
878     want several servers. Use C</mcp> for connection status. See
879 root 1.1 L<Claude Code MCP documentation|https://code.claude.com/docs/en/mcp>.
880    
881 root 1.5 =head2 Google Gemini CLI
882 root 1.1
883 root 1.5 Merge a direct server entry into C<~/.gemini/settings.json>:
884 root 1.1
885     {
886     "mcpServers": {
887 root 1.5 "code": {
888     "command": "mcp-fs",
889 root 1.1 "args": [
890 root 1.5 "--stdio", "--name", "code", "/home/alice/src/project"
891     ]
892 root 1.1 }
893     }
894     }
895    
896 root 1.5 For a combined connection, use C<mcp-multibroker> as the command and its
897     C<--stdio> and prefix/server pairs as the argument array.
898     Use C</mcp> to inspect the connection. See
899     L<Gemini CLI MCP documentation|https://geminicli.com/docs/tools/mcp-server/>.
900    
901     =head2 Hosted clients, including ChatGPT web
902    
903     A hosted client cannot spawn your local stdio command or reach your
904 root 1.21 machine's loopback address directly. A Secure MCP Tunnel runs locally,
905     connects out to OpenAI, and forwards MCP requests to a local stdio command
906     or HTTP URL. No public listener or inbound firewall port is needed.
907    
908     First create a tunnel in OpenAI Platform tunnel settings and obtain its
909     C<tunnel_...> ID and a runtime API key. Arrange for
910     C<CONTROL_PLANE_API_KEY> to be set securely in the tunnel client's
911     environment; do not put a real key in a script, command line or example.
912     Associate the tunnel with the ChatGPT workspace where you want to use it.
913    
914     For B<stdio>, put the server startup command in a small executable wrapper,
915     for example C</home/alice/bin/my-mcp>:
916    
917     #!/bin/sh
918     exec mcp-multibroker --stdio \
919     code --- mcp-fs --name code /home/alice/src/project --- \
920     questions --- mcp-ask-user ---
921    
922     With a tunnel installation providing C<tunnel-client-runtime>, run:
923    
924     tunnel-client-runtime run \
925     --log.format=struct-text \
926     --log.level=warn \
927     --control-plane.tunnel-id=tunnel_... \
928     --mcp.connection-max-ttl=120s \
929     --mcp.command=/home/alice/bin/my-mcp
930    
931     The tunnel starts the wrapper as its stdio MCP server. Do not start a
932     separate copy yourself. Make the wrapper executable and ensure its
933     programs and Perl modules are on the tunnel process's C<PATH>.
934 root 1.5
935 root 1.21 For B<HTTP>, instead start the server or multibroker separately:
936    
937     mcp-multibroker --name tools --bind 127.0.0.1:16586 \
938     code 'stdio:mcp-fs --name code /home/alice/src/project'
939    
940     Obtain the matching credential-bearing URL:
941    
942     mcp-multibroker --name tools --bind 127.0.0.1:16586 --print-url
943    
944     Then point the tunnel runtime at that URL, rather than a command:
945    
946     tunnel-client-runtime run \
947     --log.format=struct-text \
948     --log.level=warn \
949     --control-plane.tunnel-id=tunnel_... \
950     --mcp.connection-max-ttl=120s \
951     --mcp.server-url=http://127.0.0.1:16586/TOKEN/
952    
953     Replace C<TOKEN> with the actual URL path printed above, and keep it
954     private. In this mode, the multibroker must remain running separately;
955     the tunnel only connects to it. Both modes require the tunnel runtime
956     to remain active while the hosted client uses the server. Use B<one>
957     of C<--mcp.command> and C<--mcp.server-url>, not both.
958    
959     In ChatGPT, add a custom MCP server using a Tunnel connection and select
960     the tunnel ID. Creation and visibility depend on the Platform and ChatGPT
961     workspace permissions. The tunnel client's CLI and supported configuration
962     forms can vary between releases; the examples above use the direct runtime
963     CLI rather than its optional profile setup. See
964     L<Secure MCP Tunnel|https://developers.openai.com/api/docs/guides/secure-mcp-tunnels>
965     for obtaining a tunnel, runtime, credentials and connecting it to ChatGPT.
966 root 1.5
967     =head1 TROUBLESHOOTING
968    
969     =head2 The server does not start
970    
971     Read stderr or the client's server log. Missing Perl modules, a missing
972     workdir, unsuitable utilities or an unavailable bubblewrap executable can
973     fail startup. Confirm that the client launches the same executable and
974     arguments you intended, with the expected C<PATH> and Perl installation.
975    
976     For a local sandbox check, run from the project directory:
977    
978     mcp-fs --exec-cmd workdir-read -- ls
979 root 1.1
980 root 1.5 This runs C<ls> with the named grants and trusted baseline mounts, without
981     MCP or saved permission rules. A failure here can identify a bubblewrap
982     or runtime problem. It does not test the client connection or approval UI.
983     C<--sandbox none> disables isolation and changes worker authority; it is
984     not a fix that preserves the same permission boundary.
985 root 1.1
986 root 1.5 =head2 The client cannot connect
987    
988     For stdio, configure a command the client launches, rather than a URL.
989     A separately running stdio process is not the client's connection.
990     Do not put banners or diagnostics on stdout.
991    
992     For HTTP, leave the server running and check its address and port.
993     C<--print-url> exits without starting it. Loopback binds accept local
994     connections only; hosted or remote clients need the appropriate route or
995     tunnel. An occupied port causes a listener error, so check the server log.
996    
997     =head2 Authentication fails
998    
999     Obtain the URL with the same name, bind/token overrides and configuration
1000 root 1.23 environment as the running process. Use the complete path; the final
1001     slash is optional for endpoints whose configured path ends in one.
1002     A clean URL needs an accepted bearer token.
1003 root 1.5
1004     A multibroker child credential is not necessarily the upstream listener's
1005     credential. C<--bearer> after a child pair and C<--token> before the pairs
1006     configure different sides of the connection.
1007    
1008     If the server warns that it cannot save the master secret, another process
1009 root 1.22 may derive a different token. Check write access to the global configuration.
1010     Do not replace an existing secret simply to add a setting.
1011 root 1.5
1012     =head2 Connected, but there are no tools
1013    
1014     Inspect the server's stderr for omitted utilities. mcp-fs's C<workdirs>
1015     tool reports configuration even when a utility-dependent tool is absent.
1016     For a multibroker, call C<discover-brokers> to see individual connection
1017     errors, then C<list-tools> to refresh definitions.
1018    
1019     A third-party child might require initialization or features this client
1020     implementation does not support. See L<AnyEvent::MCP::Client> and its
1021     transport documentation for limitations.
1022    
1023     =head2 There is no approval dialog
1024    
1025     First check whether the tool was denied by a saved rule or is waiting for
1026     the client's own approval. An allowed operation needs no server prompt.
1027    
1028     The default helper runs on the server machine. A background service may
1029     have neither a usable display nor C</dev/tty>, even though your interactive
1030     shell has both. Supply the appropriate display environment, a usable helper,
1031     or C<--ask auto> with a modern client supporting form elicitation.
1032     C<--ask mcp> reports an error if that support is absent.
1033    
1034     Setting an asking mode cannot make an unsupported client display a form.
1035     Check stderr and the tool error instead of assuming a missing dialog is
1036     an approval.
1037    
1038     =head2 It asks again after I chose allow
1039 root 1.1
1040 root 1.5 Allow-once covers one tool invocation, including its permission retries.
1041     The next invocation asks again. Use allow-always to save a rule.
1042 root 1.1
1043 root 1.5 Inspect the saved rule's action, workdir and grants. Listing names and
1044     reading contents are different actions. A rule for one exact workdir
1045     spelling will not match a differently spelled startup argument.
1046     A request for extra authority, such as networking, does not match a
1047     workdir-read-only allow rule. Earlier ask or deny rules take precedence.
1048 root 1.1
1049 root 1.5 Confirm that the prompt's permanent rule was successfully saved and that
1050     you are editing the rules for the actual child name, not merely its
1051     multibroker prefix.
1052 root 1.1
1053 root 1.5 =head2 The worker cannot see a directory or executable
1054 root 1.1
1055 root 1.5 The worker sees granted mounts and trusted baseline mounts, not everything
1056     the server process can see. Check C<workdirs> for the selected path, mounts
1057     and runtime paths. A symlink target outside those mounts is unavailable.
1058 root 1.1
1059 root 1.19 The ordinary sandbox runtime includes C</usr>, C</bin> and system libraries,
1060     but not C</opt>. For tools or libraries under C</opt>, add this to
1061     C<[program mcp-fs]> in the private global configuration:
1062    
1063     mount.opt = ro:/opt
1064    
1065     This assumes C</opt> exists. Restart mcp-fs after changing trusted mounts.
1066     If your worker Perl is C</opt/bin/perl>, you can also set
1067     C<executable.perl = /opt/bin/perl> in that program section. Supply the
1068     actual executable path: selecting it does not itself mount the
1069     executable or its dependencies inside the worker.
1070    
1071 root 1.5 A trusted mount supplies baseline access to every worker using it; a
1072     writable mount likewise supplies baseline write authority.
1073 root 1.1
1074 root 1.5 An arbitrary command might also need its user's configuration or repository
1075     credentials under HOME, or network access. Request the corresponding grants
1076     when needed; do not assume C<workdir-read> includes them.
1077 root 1.7 For example, CVS over SSH can use C<workdir-read> and C<ssh-agent>.
1078     The latter includes network access, the agent socket and C<~/.ssh/known_hosts>,
1079     without exposing private key files or the rest of HOME. The broker must
1080     inherit C<SSH_AUTH_SOCK> from your environment. User-configured helpers
1081     outside the runtime mounts need an explicit trusted mount.
1082     An explicit exec grant array replaces the default rather than adding to it.
1083 root 1.1
1084 root 1.5 =head2 My configuration change seems to be ignored
1085 root 1.1
1086 root 1.5 Check which file and section the process actually selects. Global settings
1087     use the server user's C<HOME>/C<XDG_CONFIG_HOME>. Instance names, program
1088     basenames and multibroker prefixes serve different purposes.
1089 root 1.1
1090 root 1.5 Restart after changing startup settings, mounts or utilities. Permission
1091     rules need no restart, but their order still matters. Refresh discovery
1092     after a child restart; reconnect a client that retains an old tool list.
1093     C<--print-url> reads the current configuration, which can differ from an
1094     older running process.
1095 root 1.1
1096 root 1.5 =head2 The command failed, but the MCP request succeeded
1097 root 1.1
1098 root 1.5 C<exec> reports exit status, signal or timeout as a normal tool result.
1099     A successful MCP exchange is not a successful Unix command.
1100     Conversely, a transport failure does not prove a command did nothing:
1101     it may have completed before the connection was lost. Calls are not
1102     automatically replayed after a transport failure.
1103 root 1.1
1104 root 1.11 =head1 TESTING
1105    
1106     The default test level is 0. It checks protocol behaviour, permissions,
1107     validation and ordinary process operation, including worker cancellation
1108     and reaping. Watchdogs allow slow machines time to finish; they do not
1109     make successful tests wait for the whole timeout.
1110    
1111     prove -Ilib t
1112    
1113     Set C<PERL_ANYEVENT_MCP_TESTS> to 1 to include the extended tests:
1114    
1115     PERL_ANYEVENT_MCP_TESTS=1 prove -Ilib t
1116    
1117     Level 1 adds GNU find/grep/sed/patch operations, real Vim scripting, browser
1118     transfer integration, short idle-lifetime tests, a helper descendant holding
1119     a pipe open, and tests which deliberately wait for a command timeout or
1120     cancel a form helper across several processes. Run this level before releases.
1121     Values greater than 1 currently select the same tests as level 1.
1122    
1123     Missing GNU utilities or required Vim functions cause explicit skips even
1124     at level 1. The permission and form UI tests use a YAD stand-in: neither
1125     level requires YAD, X11 or an interactive display. The filesystem tests
1126     use a bubblewrap stand-in and check arguments and worker behaviour; they
1127     do not test kernel isolation. The browser tests use simulated peers.
1128    
1129 root 1.5 =head1 WHERE TO GO NEXT
1130 root 1.1
1131 root 1.5 For available tools and server-specific options:
1132 root 1.1
1133     perldoc mcp-fs
1134     perldoc mcp-multibroker
1135 root 1.5 perldoc mcp-vim
1136     perldoc mcp-ask-user
1137 root 1.1 perldoc anyevent-mcp
1138    
1139 root 1.5 For a complete first Perl server, options, replies, permission checks and
1140     asynchronous work, see L<AnyEvent::MCP::Server::Simple/TUTORIAL>.
1141     For the module map and shared configuration reference, see L<AnyEvent::MCP>.
1142     For permission rule details, see L<AnyEvent::MCP::Server::Permissions>.
1143 root 1.1
1144     =head1 SEE ALSO
1145    
1146     L<AnyEvent::MCP>, L<AnyEvent::MCP::Server::Simple>,
1147 root 1.5 L<mcp-fs>, L<mcp-multibroker>, L<mcp-vim>, L<mcp-ask-user>,
1148     L<AnyEvent::MCP::Server::Permissions>
1149 root 1.1
1150     =cut