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