ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MCP/README
Revision: 1.10
Committed: Thu Nov 5 00:39:05 2026 UTC (8 hours, 7 minutes ago) by root
Branch: MAIN
CVS Tags: rel-0_81, rel-0_8, HEAD
Changes since 1.9: +149 -22 lines
Log Message:
*** empty log message ***

File Contents

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