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