ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MCP/lib/AnyEvent/MCP/Intro.pod
Revision: 1.5
Committed: Tue Oct 13 22:54:21 2026 UTC (2 weeks, 3 days ago) by root
Branch: MAIN
Changes since 1.4: +759 -345 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3 root 1.5 AnyEvent::MCP::Intro - using MCP servers, clients and permissions
4 root 1.1
5     =head1 DESCRIPTION
6    
7 root 1.5 You can use the servers in this distribution without writing any Perl.
8     This walkthrough starts with one filesystem server, connects it to an MCP
9     client, and makes a useful request. Once that works, it explains persistent
10     configuration, permissions and combining several servers.
11 root 1.1
12 root 1.5 If you want to write a small server yourself, continue with
13     L<AnyEvent::MCP::Server::Simple/TUTORIAL>. Applications needing their own
14     connection management or dispatch can use the modules described in
15     L<AnyEvent::MCP/MODULES>.
16 root 1.1
17 root 1.5 The examples use C</home/alice/src/project> as an existing project directory.
18     Replace it with your own absolute path. Commands shown here are commands
19     for you to run; requests addressed to the LLM are shown separately.
20    
21     =head1 INSTALLATION
22    
23     Install the Perl distribution and the external programs used by the
24     servers. Installing one does not install the other.
25    
26     For mcp-fs, install Linux bubblewrap and the filesystem utilities. On
27     Debian or Ubuntu, for example:
28    
29     sudo apt install bubblewrap findutils grep patch sed perl yad
30    
31     C<yad> is optional: it supplies graphical permission dialogs.
32     Without a usable YAD dialog, the helper tries C</dev/tty>; if neither is
33     available, it denies the request. Bubblewrap's executable is C<bwrap>.
34     The machine must allow the unprivileged user namespaces it needs.
35    
36     mcp-fs detects its utilities at startup and omits tools whose utilities
37     are unavailable or unsuitable. It requires bubblewrap by default.
38     See L<mcp-fs/TRUSTED CONFIGURATION> for explicit utility paths and
39     L<mcp-fs/LIMITATIONS> for the sandbox's limits.
40    
41     If you have an unpacked distribution or source checkout, run these commands
42     in its top-level directory:
43    
44     perl Makefile.PL
45     make
46     make test
47     make install
48    
49     C<perl Makefile.PL> reports missing Perl dependencies. Install those with
50     your usual package manager or CPAN client before continuing. For example,
51     the main non-core dependencies can be installed with:
52    
53     cpan AnyEvent AnyEvent::HTTP common::sense JSON::XS
54    
55     Use the same Perl installation for dependency installation, building and
56     running the servers. A module installed for the system Perl might not be
57     available to a Perl installed under C</opt>. C<make install> needs write
58     access to the selected Perl's installation directories; use an appropriate
59     local Perl installation or run that final step with the required privileges.
60    
61     Installation puts C<mcp-fs>, C<mcp-multibroker>, C<mcp-vim>,
62     C<mcp-ask-user>, C<anyevent-mcp> and C<anyevent-mcp-askpermission> in the
63     selected executable directory. Make that directory available in the
64     environment of your MCP client, or configure absolute executable paths.
65     A desktop application need not have the same C<PATH> as your shell.
66    
67     To try an uninstalled source tree after installing its dependencies, you
68     can run a program with the source library path:
69    
70     perl -Ilib bin/mcp-fs --stdio --name code /home/alice/src/project
71    
72     Do this from the distribution directory. When configuring a client to
73     start such a command, account for the client's working directory or use
74     absolute paths to Perl, C<lib> and the script. An installed executable
75     avoids that extra setup.
76    
77     =head1 YOUR FIRST FILESYSTEM SERVER
78    
79     Start with one project and one connection. You do not need a multibroker,
80     a hand-written configuration file or saved permission rules yet.
81    
82     =head2 Choose stdio or HTTP
83    
84     Use B<stdio> when your MCP client runs on the same machine and can launch
85     a server process. Configure the client to start the following command:
86    
87     mcp-fs --stdio --name code /home/alice/src/project
88    
89     The client starts this process and uses its stdin/stdout for MCP.
90     You do not start a second copy in a terminal, and there is no listener
91     URL or HTTP token to configure. Diagnostics go to stderr.
92    
93     Clients that take a command and an argument array need these values:
94    
95     command: mcp-fs
96     arguments: --stdio, --name, code, /home/alice/src/project
97    
98     These describe separate arguments, not one shell command string.
99     Use an absolute executable path if the client cannot find C<mcp-fs>.
100     See L</CLIENT EXAMPLES> for examples of particular clients.
101    
102     Use B<HTTP> when the client connects to an already-running server, or when
103     it cannot launch a local process. Start this in a terminal on the server
104     machine and leave it running:
105    
106     mcp-fs --name code --bind :31741 /home/alice/src/project
107    
108     In another terminal, obtain the matching connection URL:
109    
110     mcp-fs --name code --bind :31741 --print-url
111    
112     The second command prints a credential-bearing URL and exits without
113     opening a listener. Configure that URL in the client. The default address
114     is IPv4 loopback, so this example is reachable from the same machine only.
115     A hosted client needs a suitable tunnel or reachable endpoint; its own
116     C<localhost> is not your computer.
117    
118     Repeat the same name and listener overrides when printing the URL.
119     Both commands must use the same user and configuration directory.
120     Port zero chooses an ephemeral port, which C<--print-url> cannot predict;
121     use an explicit port for this walkthrough.
122    
123     The HTTP server generates and saves its private master secret when needed.
124     You can initialize it explicitly with C<anyevent-mcp init>, but that
125     command is unnecessary when configuration already exists and will refuse
126     to replace it. Keep the printed URL private: possession of its token
127     authenticates a client.
128    
129     =head2 Make a useful request
130    
131     Once your client reports that the server is connected, ask the LLM:
132    
133     Show me the configured workdirs. List the top-level files in the
134     project, then read its README. Do not modify files or run commands.
135    
136     C<workdirs> returns the configured paths, sandbox grants, trusted mounts
137     and runtime paths. Listing names requests C<inspect> permission; reading
138     contents requests C<read> permission. Expect a permission prompt when
139     there is no saved rule allowing the operation.
140    
141     Choose C<Allow once> for the first operation. The worker then runs with
142     the requested sandbox grants. A denial is a tool failure that the LLM
143     should report, rather than an empty file or a disconnected server.
144    
145     For a slightly larger task, ask:
146    
147     Find TODO comments in this project and explain the three that look
148     most useful to address next. Do not modify files or run commands.
149    
150     This can use C<find>, C<grep> and C<read-lines>. You need not write MCP
151     requests yourself. If a client offers its own tool-approval prompt, that
152     is an additional client policy; it does not replace mcp-fs's permissions.
153    
154     =head2 Understand the workdir
155    
156     The directory passed at startup tells mcp-fs which workdir to expose.
157     It does not grant permission for every operation in that directory.
158     Each operation still requests its action and sandbox grants.
159    
160     With one workdir, tools can omit the C<workdir> argument. With several:
161    
162     mcp-fs --stdio --name code /home/alice/src/project /home/alice/notes
163    
164     tools select one using a zero-based index, a numeric string or an exact
165     configured/resolved path returned by C<workdirs>. Relative tool paths
166     are relative to that selection. The tool index C<0> is not a name you
167     put in permission rules.
168    
169     C<workdir-read> exposes the selected workdir read-only.
170     C<workdir-write> makes it writable and implies read access.
171     A path in another configured workdir requires all-workdirs authority;
172     a path elsewhere requires suitable home/world or shared-tmp authority.
173     A symlink cannot make an unmounted target appear inside the sandbox.
174    
175     Prefer separate, non-overlapping workdirs. Overlapping mounts have
176     unspecified access effects. See L<mcp-fs/SANDBOX GRANTS> before granting
177     access beyond the selected workdir.
178    
179     =head1 CONFIGURING YOUR SETUP
180    
181     There are three different things to configure: how the client connects,
182     how the server runs, and which operations the user allows. Changing one
183     does not necessarily change the other two.
184    
185     =head2 Where each setting belongs
186 root 1.1
187     =over
188    
189 root 1.5 =item Directories to expose
190    
191     Pass workdirs on the mcp-fs startup command. For a stdio server, that
192     command belongs in the client's server configuration. For an HTTP server,
193     it belongs in the command used to run the service.
194 root 1.1
195 root 1.5 =item Connection transport
196 root 1.1
197 root 1.5 The client launches a command for stdio or connects to a URL for HTTP.
198     C<--stdio> selects the former for mcp-fs and the multibroker.
199 root 1.1
200 root 1.5 =item Listener address, port and tokens
201 root 1.1
202 root 1.5 Use C<[instance NAME]> in the global configuration or command-line
203     C<--bind> and C<--token> overrides.
204 root 1.1
205 root 1.5 =item Trusted mounts and utility paths
206    
207     For mcp-fs, use C<[program NAME]> defaults and C<[instance NAME]>
208     overrides in the global configuration.
209    
210     =item Allowed operations and sandbox grants
211    
212     Use the permission rules file, normally created through approval dialogs.
213     This file is separate from the global configuration.
214    
215     =item Location of permission prompts
216    
217     Use C<--ask helper>, C<--ask auto> or C<--ask mcp>, or set
218     C<PERL_ANYEVENT_MCP_PERMISSION_ASK> in the server's environment.
219    
220     =item Combined server connections
221    
222     Put prefix/server pairs on the multibroker startup command. HTTP child
223     credentials can also use C<[client PREFIX]> in the global configuration.
224 root 1.1
225     =back
226    
227 root 1.5 =head2 One complete named configuration
228    
229     The global file is C<$XDG_CONFIG_HOME/anyevent-mcp/global.ini>, falling
230     back to C<$HOME/.config/anyevent-mcp/global.ini>. Settings are UTF-8
231     C<key = value> lines; values are unquoted. Whole-line C<#> and C<;>
232     comments are allowed. See L<AnyEvent::MCP/GLOBAL CONFIGURATION> for the
233     complete format.
234    
235     Start with the existing file, preserving its C<[global]> secret.
236     If you have no file yet, C<anyevent-mcp init> creates it privately.
237     Add the following sections:
238    
239     [program mcp-fs]
240     mount.opt = ro:/opt
241    
242     [instance code]
243     bind = 127.0.0.1:31741
244    
245     The optional C<mount.opt> line assumes C</opt> exists and contains tools
246     or libraries your workers need. Omit it if you do not need that access.
247     The ordinary sandbox runtime includes C</usr>, C</bin> and system
248     libraries, but not C</opt>. If your worker Perl is C</opt/bin/perl>, you
249     can additionally put C<executable.perl = /opt/bin/perl> in that program
250     section. Supply the actual executable path; selecting it does not itself
251     mount its files or libraries.
252    
253     Now start:
254    
255     mcp-fs --name code /home/alice/src/project
256    
257     and retrieve its URL with:
258    
259     mcp-fs --name code --print-url
260    
261     Both use C<[instance code]>. No explicit token is needed: the server
262     derives one from its name and the existing master secret.
263    
264     For this setup:
265    
266     program defaults: [program mcp-fs]
267     instance settings: [instance code]
268     selected workdir: /home/alice/src/project
269     permission file: ~/.config/anyevent-mcp/rules-fs-code.ini
270     rule-manager profile: fs-code
271    
272     The permission pathname above assumes the default configuration directory.
273     C<anyevent-mcp manage-rules fs-code> opens the graphical rule manager;
274     C<anyevent-mcp edit-rules fs-code> opens the file in your editor.
275    
276     Keep global configuration and rule files owned by the server user and
277     private, normally mode 0600. C<--config FILE> on C<anyevent-mcp init>
278     selects that command's output file; it does not make the servers use an
279     arbitrary alternate file. Use the same C<HOME>/C<XDG_CONFIG_HOME>
280     environment when running the server and its management commands.
281    
282     =head2 Names, prefixes and profiles
283    
284     C<--name code> selects instance settings, derived HTTP credentials and
285     mcp-fs's C<rules-fs-code.ini>. Without C<--name>, mcp-fs uses C<mcp-fs>,
286     giving profile C<fs-mcp-fs>. Two processes with the same name and
287     configuration share credentials and rules, even if their workdirs differ.
288    
289     A multibroker prefix, such as C<files>, only routes tools: C<grep> becomes
290     C<files.grep>. It does not rename the child server or select its rules.
291     For example:
292    
293     mcp-multibroker files \
294     'stdio:mcp-fs --name code /home/alice/src/project'
295    
296     The tools are C<files.*>, but the child still uses instance C<code>
297     and rule-manager profile C<fs-code>. The multibroker's own C<--name>
298     selects its upstream listener settings.
299 root 1.1
300 root 1.5 =head2 Configuration changes and restarts
301 root 1.1
302 root 1.5 Command-line listener options override the named global settings.
303     For mcp-fs trusted settings, an instance entry overrides the corresponding
304     program entry; an empty instance mount value suppresses the inherited mount.
305 root 1.1
306 root 1.5 Workdirs, mounts, utility paths, listener settings and tokens are read at
307     startup. Change the file or startup command, then restart the affected
308     server. The multibroker also needs restarting to change its prefix/server
309     pairs; refreshing discovery does not change those pairs.
310    
311     Permission rules are reread on permission checks, so editing them does
312     not require a restart. A client's displayed tool list can still be cached.
313     After restarting a child, refresh tool discovery or reconnect the client
314     as described in L</COMBINING SERVERS>.
315    
316     =head1 PERMISSIONS IN PRACTICE
317    
318     HTTP authentication establishes that the client may connect.
319     Permission checks decide whether a tool may perform an operation.
320     A correct token therefore does not prevent permission prompts.
321    
322     =head2 What the prompt means
323    
324     The prompt describes an action, paths or command, a reason and sandbox
325     grants. For filesystem tools, the actions are:
326    
327     inspect stat, list, find
328     read file-read, read-lines, grep
329     write file-write, file-patch
330     manage path-op
331     exec command execution
332    
333     The action and grants are independent. Allowing C<read> does not allow
334     C<write>, even if a worker grant permits both kinds of filesystem access.
335     C<exec> runs arbitrary commands; it is not a classification of supposedly
336     safe command prefixes.
337    
338     Choose allow/deny once, or always. Closing the dialog denies once.
339     An optional denial reason is returned with the error; it is not added to
340     successful tool results. An always choice opens a rule editor.
341     Filesystem allow rules can select grants and the selected workdir when
342     the authority depends on it. Deny rules can also select an exact affected
343     path. Exec offers persistent command/argv subjects.
344    
345     For exec, C<View stdin...> lets you inspect supplied input without closing
346     the approval dialog. That input is display-only: an exec allow rule does
347     not constrain future stdin. Allowing an interpreter command can therefore
348     allow a different script on its next invocation.
349    
350     A worker accessing several paths requests their combined sandbox authority
351     once. If the chosen grants are insufficient, it fails before starting.
352    
353     =head2 Save a useful read-only policy
354    
355     After trying individual operations, you might want the LLM to inspect and
356     read the project without asking each time, while keeping changes subject
357     to approval. Put these rules in C<rules-fs-code.ini>, or create equivalent
358     allow rules through the prompt:
359    
360     [rule]
361     decision=allow
362     action=inspect
363     workdir=/home/alice/src/project
364     sandbox-grants=workdir-read
365    
366     [rule]
367     decision=allow
368     action=read
369     workdir=/home/alice/src/project
370     sandbox-grants=workdir-read
371    
372     [rule]
373     decision=deny
374     action=exec
375 root 1.1
376 root 1.5 Use the exact workdir spelling passed at server startup. Absolute startup
377     paths make this easier. If creating the rules file manually, ensure it
378     belongs to the server user and is private before making another request.
379     For the default configuration directory:
380 root 1.1
381 root 1.5 chmod 600 ~/.config/anyevent-mcp/rules-fs-code.ini
382 root 1.1
383 root 1.5 Use the corresponding XDG path when configured. Without matching rules, write and manage operations
384     still ask. The final rule denies command execution outright; omit it if you
385     want execution to ask instead.
386 root 1.1
387 root 1.5 Rules run in order, stopping at the first match. An allow rule matches only
388     when its grants cover the request, including implications.
389     C<workdir-write> implies C<workdir-read>; C<network> remains independent.
390     Action and subject match exactly unless beginning with C<^>, which selects
391     a Perl regular expression. Workdir matching is always exact.
392     An explicit C<ask> rule can override later allow rules.
393    
394     These allow rules authorize sandbox access to the selected workdir.
395     They cannot confine authority to one file or a subtree inside it.
396     Filesystem operations do not offer persistent path subjects.
397     An exact C<path> matcher is available for deny rules only.
398     Trusted runtime and configured mounts remain baseline access independently
399     of these grants. See L<mcp-fs/TRUSTED CONFIGURATION>.
400    
401     =head2 Change or remove saved rules
402    
403     Use:
404    
405     anyevent-mcp manage-rules fs-code
406     anyevent-mcp edit-rules fs-code
407    
408     The first command lets you delete and reorder rules in YAD.
409     The second uses C<$VISUAL>, C<$EDITOR>, C<sensible-editor> or C<vi>.
410     An earlier deny or ask rule can explain why adding a later allow rule
411     does not change the result.
412    
413     For a custom application with another rule pathname, use:
414    
415     anyevent-mcp manage-rules-file /path/to/rules.ini
416     anyevent-mcp edit-rules-file /path/to/rules.ini
417    
418     A failed attempt to save a permanent rule is an error, not a successful
419     permanent approval. The file must remain private and owned by the server
420     user. For full syntax and programming interfaces, see
421     L<AnyEvent::MCP::Server::Permissions>.
422    
423     =head2 Choose where to ask
424    
425     The default C<helper> mode runs C<anyevent-mcp-askpermission> on the server
426     machine. It tries YAD, then C</dev/tty>, then denies if neither can be used.
427     The helper inherits the server's display environment.
428     C<PERL_ANYEVENT_MCP_PERMISSION_HELPER> selects a different executable.
429    
430     For a modern client supporting MCP form elicitation, you can instead use:
431    
432     mcp-fs --stdio --name code --ask auto /home/alice/src/project
433    
434     C<auto> uses the client's form support when advertised for that request,
435     otherwise the local helper. C<mcp> requires that support and fails when
436     unavailable. It does not silently fall back. Use client-side permission
437     approval only when that client is a trusted authority to grant access.
438    
439     To set the default for servers using the shared permission engine:
440    
441     PERL_ANYEVENT_MCP_PERMISSION_ASK=auto \
442     mcp-fs --stdio --name code /home/alice/src/project
443    
444     An explicit application C<ask> setting or C<--ask> overrides the environment.
445     For spawned stdio children, C<mcp-multibroker --ask auto> passes this
446     default to them. It cannot change the environment of an independently
447     running HTTP server.
448    
449     These settings choose where to ask; they cannot add elicitation support
450     to a client. C<mcp-ask-user> always requires client form support and has
451     no local helper fallback. A question is also different from an approval:
452     answering it does not grant a filesystem worker any authority.
453    
454     =head1 COMBINING SERVERS
455    
456     Once the first connection works, use the multibroker to give a client
457     one connection for several servers:
458    
459     mcp-multibroker --name tools --bind :31740 \
460     code 'stdio:mcp-fs --name code /home/alice/src/project' \
461     notes 'stdio:mcp-fs --name notes /home/alice/notes'
462    
463     Quote each C<stdio:> shell command as one argument.
464     The broker supplies the child's stdio environment and starts ordinary
465     children lazily, on first use. The explicit child names give them separate
466     permission profiles C<fs-code> and C<fs-notes>.
467    
468     Obtain the upstream HTTP URL with:
469    
470     mcp-multibroker --name tools --bind :31740 --print-url
471    
472     Configure this URL in place of the client's old direct connection.
473     The client can now see C<code.grep>, C<code.read-lines>, C<notes.find>
474     and other prefixed tools. It does not need a separate connection to each
475     child.
476    
477     For a client launching the multibroker locally, configure:
478    
479     mcp-multibroker --stdio --name tools \
480     code 'stdio:mcp-fs --name code /home/alice/src/project' \
481     notes 'stdio:mcp-fs --name notes /home/alice/notes'
482    
483     C<--stdio> selects the upstream connection. The child commands still use
484     C<stdio:>; that selects each downstream connection independently.
485     No upstream HTTP URL is needed in this case.
486    
487     =head2 Discover and refresh tools
488    
489     Ask the LLM:
490    
491     Call discover-brokers and list-tools, then show me which servers
492     are available and what each is for.
493    
494     C<discover-brokers> returns instructions, no instructions, or an error for
495     each configured server. C<list-tools> requests current tool definitions;
496     unreachable servers are omitted. A reachable server can still fail later.
497    
498     If the client still has an old direct tool list, C<call-tool> can invoke
499     an exact prefixed name found by C<list-tools>. Refresh the client's MCP
500     connection if it continues to hide newly available tools.
501    
502     Discovery queries the configured servers. It cannot add a server absent
503     from the broker's startup command. Changing that command requires a restart.
504    
505     =head2 Add an HTTP child
506    
507     A broker can mix spawned stdio servers and existing HTTP endpoints:
508    
509     mcp-multibroker --stdio \
510     code 'stdio:mcp-fs --name code /home/alice/src/project' \
511     remote https://example.org/mcp/ --bearer TOKEN
512    
513     C<--bearer> immediately after the HTTP pair belongs to that child.
514     C<--token> before all pairs configures the multibroker's own HTTP listener.
515     They authenticate different connections.
516    
517     To avoid putting a child's bearer token in the startup command, add:
518    
519     [client remote]
520     bearer = TOKEN
521     timeout = 300
522    
523     to the private global configuration, and omit C<--bearer> from the command.
524     The prefix C<remote> selects these client defaults. The command-line URL
525     still chooses the endpoint. Use the actual credential accepted by that
526     server, not the literal placeholder C<TOKEN>.
527    
528     A token already present in a child's URL needs no separate bearer option.
529     The bundled servers use static URL-safe tokens; they do not validate
530     OAuth access tokens or implement HTTP Basic authentication.
531     Use TLS or an appropriate tunnel when credentials cross untrusted networks.
532    
533     The multibroker does not put every child inside the mcp-fs sandbox.
534     Each process or remote service has its own authority and enforcement.
535    
536     =head2 Add a live Vim editor
537    
538     Install the Vim plugin using L<mcp-vim/VIM PLUGIN INSTALLATION>. It is
539     included in the source distribution but is not installed by Perl's
540     C<make install>.
541    
542     A spawned mcp-vim child also listens for editor connections. Start it
543     eagerly so Vim can connect before the first MCP tool call:
544    
545     mcp-multibroker --stdio \
546     code 'stdio:mcp-fs --name code /home/alice/src/project' \
547     vim 'stdio:mcp-vim --name editor' --eager
548    
549     In another terminal, obtain the editor child's URL prefix:
550    
551     mcp-vim --name editor --print-url
552    
553     Append the desired target name in Vim:
554    
555     :Mcp http://HOST:PORT/TOKEN/my-editor
556    
557     Use the actual printed prefix in place of C<http://HOST:PORT/TOKEN/>.
558     Ask the LLM to call C<vim.targets>, then C<vim.state> before reading or
559     editing buffers. These tools see live, possibly unsaved buffers.
560     Edits require a current changedtick and do not save files to disk.
561    
562     C<--eager> belongs immediately after its stdio pair.
563     An eager connection failure is logged; the broker does not continuously
564     restart the child. Later tool use can try connecting again.
565    
566     =head2 Ask the client's human a question
567    
568     For a modern client with form elicitation, add a question server:
569    
570     mcp-multibroker --stdio \
571     code 'stdio:mcp-fs --name code /home/alice/src/project' \
572     questions 'stdio:mcp-ask-user'
573    
574     The LLM can call C<questions.ask-user> with a question, up to three
575     suggested answers and room for free text. For example, tell it to use
576     that tool if choosing among several possible tasks needs your input.
577     Decline and cancel are distinct results; neither supplies an answer.
578    
579     Unlike permission prompting with C<auto>, this tool has no local-helper
580     fallback. Without modern client form support, it returns a tool error.
581     See L<mcp-ask-user> for argument limits and result fields.
582    
583     =head1 HTTP TOKENS AND SERVER IDENTITY
584    
585     For the ordinary bundled HTTP endpoints, a client can present an accepted
586     token in either of these ways:
587    
588     POST /TOKEN/
589     POST / Authorization: Bearer TOKEN
590    
591     URL tokens are path components, not browser cookies.
592     For another configured endpoint, C</TOKEN> prefixes that endpoint path.
593     All accepted tokens authenticate the same operations; they are not separate
594     users or permission levels. Permissions still govern the tool operation.
595    
596     By default, the master secret and server name determine one stable token
597     and a port in 16384..32767. Changing a server's name changes its derived
598     credentials and default port. Changing or losing the master secret changes
599     all derived credentials. Keep an existing C<[global]> secret when editing
600     other configuration.
601    
602     To configure explicit tokens:
603    
604     [instance code]
605     tokens = first-secret,second-secret
606 root 1.1
607 root 1.5 Replace those placeholders with actual unguessable URL-safe tokens.
608     Repeated C<--token> options replace the whole configured list and the
609     derived default. The first token appears in C<--print-url>; all are accepted.
610     mcp-vim also accepts its token set for Vim and browser WebSocket connections.
611    
612     If C<--print-url> disagrees with the client's URL, compare the name,
613     command-line overrides, user and configuration environment with the running
614     process. The command resolves configuration; it does not ask the running
615     server which URL it uses. A changed file needs a server restart.
616    
617     An Origin allowlist restricts browser origins; it does not authenticate
618     clients. A CORS preflight can succeed without a token, while the MCP POST
619     still requires one. See L<AnyEvent::MCP::Server::HTTP/AUTHENTICATION> for
620     the low-level server interface.
621    
622     =head1 CLIENT EXAMPLES
623    
624     Client settings and command syntax evolve independently of this distribution.
625     These examples show the connection choices; consult the linked client
626     documentation if its interface differs. Replace illustrative paths and
627     credentials with your own.
628 root 1.1
629 root 1.5 =head2 OpenAI Codex CLI
630 root 1.1
631 root 1.5 For the first direct filesystem connection:
632 root 1.1
633 root 1.5 codex mcp add code -- \
634     mcp-fs --stdio --name code /home/alice/src/project
635 root 1.1 codex mcp list
636    
637 root 1.5 For a multibroker connection:
638    
639     codex mcp add mytools -- \
640     mcp-multibroker --stdio \
641     code 'stdio:mcp-fs --name code /home/alice/src/project'
642    
643 root 1.1 Use C</mcp> within Codex to inspect connections.
644     See L<Codex MCP documentation|https://learn.chatgpt.com/docs/extend/mcp>.
645    
646 root 1.5 =head2 Anthropic Claude Code
647 root 1.1
648 root 1.5 For the direct connection:
649 root 1.1
650 root 1.5 claude mcp add --transport stdio --scope user code -- \
651     mcp-fs --stdio --name code /home/alice/src/project
652 root 1.1 claude mcp list
653    
654 root 1.5 Replace the launched command with the multibroker command above when you
655     want several servers. Use C</mcp> for connection status. See
656 root 1.1 L<Claude Code MCP documentation|https://code.claude.com/docs/en/mcp>.
657    
658 root 1.5 =head2 Google Gemini CLI
659 root 1.1
660 root 1.5 Merge a direct server entry into C<~/.gemini/settings.json>:
661 root 1.1
662     {
663     "mcpServers": {
664 root 1.5 "code": {
665     "command": "mcp-fs",
666 root 1.1 "args": [
667 root 1.5 "--stdio", "--name", "code", "/home/alice/src/project"
668     ]
669 root 1.1 }
670     }
671     }
672    
673 root 1.5 For a combined connection, use C<mcp-multibroker> as the command and its
674     C<--stdio> and prefix/server pairs as the argument array.
675     Use C</mcp> to inspect the connection. See
676     L<Gemini CLI MCP documentation|https://geminicli.com/docs/tools/mcp-server/>.
677    
678     =head2 Hosted clients, including ChatGPT web
679    
680     A hosted client cannot spawn your local stdio command or reach your
681     machine's loopback address directly. Run the server or multibroker in HTTP
682     mode and configure a supported tunnel or reachable endpoint.
683    
684     For ChatGPT, use its custom MCP setup and, for a private server, an
685     appropriately configured Secure MCP Tunnel. Availability depends on the
686     client's plan, workspace and feature permissions. See
687     L<ChatGPT custom MCP servers|https://developers.openai.com/api/docs/guides/custom-mcp-server>
688     and L<Secure MCP Tunnel|https://developers.openai.com/blog/connect-private-mcp-servers-to-openai-products>.
689    
690     =head1 TROUBLESHOOTING
691    
692     =head2 The server does not start
693    
694     Read stderr or the client's server log. Missing Perl modules, a missing
695     workdir, unsuitable utilities or an unavailable bubblewrap executable can
696     fail startup. Confirm that the client launches the same executable and
697     arguments you intended, with the expected C<PATH> and Perl installation.
698    
699     For a local sandbox check, run from the project directory:
700    
701     mcp-fs --exec-cmd workdir-read -- ls
702 root 1.1
703 root 1.5 This runs C<ls> with the named grants and trusted baseline mounts, without
704     MCP or saved permission rules. A failure here can identify a bubblewrap
705     or runtime problem. It does not test the client connection or approval UI.
706     C<--sandbox none> disables isolation and changes worker authority; it is
707     not a fix that preserves the same permission boundary.
708 root 1.1
709 root 1.5 =head2 The client cannot connect
710    
711     For stdio, configure a command the client launches, rather than a URL.
712     A separately running stdio process is not the client's connection.
713     Do not put banners or diagnostics on stdout.
714    
715     For HTTP, leave the server running and check its address and port.
716     C<--print-url> exits without starting it. Loopback binds accept local
717     connections only; hosted or remote clients need the appropriate route or
718     tunnel. An occupied port causes a listener error, so check the server log.
719    
720     =head2 Authentication fails
721    
722     Obtain the URL with the same name, bind/token overrides and configuration
723     environment as the running process. Use the complete path, including any
724     required trailing slash. A clean URL needs an accepted bearer token.
725    
726     A multibroker child credential is not necessarily the upstream listener's
727     credential. C<--bearer> after a child pair and C<--token> before the pairs
728     configure different sides of the connection.
729    
730     If the server warns that it cannot save the master secret, another process
731     may derive a different token. Fix ownership and write access to the private
732     configuration. Do not replace an existing secret simply to add a setting.
733    
734     =head2 Connected, but there are no tools
735    
736     Inspect the server's stderr for omitted utilities. mcp-fs's C<workdirs>
737     tool reports configuration even when a utility-dependent tool is absent.
738     For a multibroker, call C<discover-brokers> to see individual connection
739     errors, then C<list-tools> to refresh definitions.
740    
741     A third-party child might require initialization or features this client
742     implementation does not support. See L<AnyEvent::MCP::Client> and its
743     transport documentation for limitations.
744    
745     =head2 There is no approval dialog
746    
747     First check whether the tool was denied by a saved rule or is waiting for
748     the client's own approval. An allowed operation needs no server prompt.
749    
750     The default helper runs on the server machine. A background service may
751     have neither a usable display nor C</dev/tty>, even though your interactive
752     shell has both. Supply the appropriate display environment, a usable helper,
753     or C<--ask auto> with a modern client supporting form elicitation.
754     C<--ask mcp> reports an error if that support is absent.
755    
756     Setting an asking mode cannot make an unsupported client display a form.
757     Check stderr and the tool error instead of assuming a missing dialog is
758     an approval.
759    
760     =head2 It asks again after I chose allow
761 root 1.1
762 root 1.5 Allow-once covers one tool invocation, including its permission retries.
763     The next invocation asks again. Use allow-always to save a rule.
764 root 1.1
765 root 1.5 Inspect the saved rule's action, workdir and grants. Listing names and
766     reading contents are different actions. A rule for one exact workdir
767     spelling will not match a differently spelled startup argument.
768     A request for extra authority, such as networking, does not match a
769     workdir-read-only allow rule. Earlier ask or deny rules take precedence.
770 root 1.1
771 root 1.5 Confirm that the prompt's permanent rule was successfully saved and that
772     you are editing the rules for the actual child name, not merely its
773     multibroker prefix.
774 root 1.1
775 root 1.5 =head2 The worker cannot see a directory or executable
776 root 1.1
777 root 1.5 The worker sees granted mounts and trusted baseline mounts, not everything
778     the server process can see. Check C<workdirs> for the selected path, mounts
779     and runtime paths. A symlink target outside those mounts is unavailable.
780 root 1.1
781 root 1.5 For tools or libraries under C</opt>, add an appropriate trusted mount
782     as shown earlier and restart mcp-fs. A configured executable path alone
783     does not mount the executable or its dependencies inside the worker.
784     A trusted mount supplies baseline access to every worker using it; a
785     writable mount likewise supplies baseline write authority.
786 root 1.1
787 root 1.5 An arbitrary command might also need its user's configuration or repository
788     credentials under HOME, or network access. Request the corresponding grants
789     when needed; do not assume C<workdir-read> includes them.
790     For example, CVS access commonly needs C<workdir-read>, C<home-read> and
791     C<network>. An explicit exec grant array replaces the default rather than
792     adding to it.
793 root 1.1
794 root 1.5 =head2 My configuration change seems to be ignored
795 root 1.1
796 root 1.5 Check which file and section the process actually selects. Global settings
797     use the server user's C<HOME>/C<XDG_CONFIG_HOME>. Instance names, program
798     basenames and multibroker prefixes serve different purposes.
799 root 1.1
800 root 1.5 Restart after changing startup settings, mounts or utilities. Permission
801     rules need no restart, but their order still matters. Refresh discovery
802     after a child restart; reconnect a client that retains an old tool list.
803     C<--print-url> reads the current configuration, which can differ from an
804     older running process.
805 root 1.1
806 root 1.5 =head2 The command failed, but the MCP request succeeded
807 root 1.1
808 root 1.5 C<exec> reports exit status, signal or timeout as a normal tool result.
809     A successful MCP exchange is not a successful Unix command.
810     Conversely, a transport failure does not prove a command did nothing:
811     it may have completed before the connection was lost. Calls are not
812     automatically replayed after a transport failure.
813 root 1.1
814 root 1.5 =head1 WHERE TO GO NEXT
815 root 1.1
816 root 1.5 For available tools and server-specific options:
817 root 1.1
818     perldoc mcp-fs
819     perldoc mcp-multibroker
820 root 1.5 perldoc mcp-vim
821     perldoc mcp-ask-user
822 root 1.1 perldoc anyevent-mcp
823    
824 root 1.5 For a complete first Perl server, options, replies, permission checks and
825     asynchronous work, see L<AnyEvent::MCP::Server::Simple/TUTORIAL>.
826     For the module map and shared configuration reference, see L<AnyEvent::MCP>.
827     For permission rule details, see L<AnyEvent::MCP::Server::Permissions>.
828 root 1.1
829     =head1 SEE ALSO
830    
831     L<AnyEvent::MCP>, L<AnyEvent::MCP::Server::Simple>,
832 root 1.5 L<mcp-fs>, L<mcp-multibroker>, L<mcp-vim>, L<mcp-ask-user>,
833     L<AnyEvent::MCP::Server::Permissions>
834 root 1.1
835     =cut