ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MCP/README
Revision: 1.13
Committed: Tue Nov 10 16:22:20 2026 UTC (15 hours, 50 minutes ago) by root
Branch: MAIN
CVS Tags: rel-0_9, HEAD
Changes since 1.12: +25 -12 lines
Log Message:
0.9

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