ffl-mcp
OfficialYou can use ffl-mcp to share and receive files/text between machines via ffl links and manage those share sessions.
Share plain text or base64 binary data as clickable ffl links.
Share a local file/folder, or multiple files that ffl auto-zips into one download.
Configure shares with E2EE, QR codes, Basic Auth, pickup/pubkey/email OTP recipient auth, download limits, timeouts, aliases, upload/relay/tunnel options, exclusions, previews, and VFS.
Download from FastFileLink URLs or any HTTP(S) URL, with resume, auth, key, and proxy options.
Generate RSA keypairs for passwordless pubkey authentication.
List, inspect, stop, and view events for active share sessions.
Get guidance for cloud-hosted assistants sharing files from a user's remote computer.
Allows selecting Cloudflare as the tunnel provider for ffl share sessions, exposing local file/folder shares through a Cloudflare tunnel.
Allows selecting ngrok as the tunnel provider for ffl share sessions, exposing local file/folder shares through an ngrok tunnel.
Uses WebRTC for peer-to-peer file transfers when available, with relay/HTTP fallback via ffl; can be disabled with forceRelay.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ffl-mcpshare the file /tmp/debug.log and give me the link"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ffl-mcp
MCP server for ffl. Let AI share anything for you.
Backed by ffl, which turns any file/folder into an HTTPS link.
This MCP server uses the ffl-python binding locally.
No file contents are sent to the LLM; the model only triggers local ffl.
This demo shows collaborative debugging: Claude on the left shares a local environment (DB + logs) via P2P link, Claude on the right downloads and diagnoses the error. In this scenario, the two Claudes represent different people working on separate machines.
Table of Contents
Related MCP server: kintone MCP Server
Installation
⚡ Short URLs for convenience
Linux/macOS:
curl -fsSL https://fastfilelink.com/mcp/install.sh | bashWindows (script):
iwr -useb https://fastfilelink.com/mcp/install.ps1 | iex🔒
fastfilelink.com/mcp/*is a redirect to GitHub. Use the direct GitHub URLs below if you prefer.
Windows — GUI Installer
Download and run ffl-mcp-setup.exe from the latest release.
It registers the server with Claude Desktop, Claude Code, Codex, and Grok Build.
No command line needed — the installer registers ffl-mcp with Claude Desktop and Claude Code automatically.
Linux / macOS — one-liner
curl -fsSL https://raw.githubusercontent.com/nuwainfo/ffl-mcp/refs/heads/main/scripts/Install.sh | bashDownloads the platform binary from the latest GitHub release and runs ffl-mcp install to register with Claude, Codex, and Grok Build. Falls back to uvx automatically if no binary is available for your platform.
Windows — one-liner (PowerShell)
iwr -useb https://raw.githubusercontent.com/nuwainfo/ffl-mcp/refs/heads/main/scripts/Install.ps1 | iexDownloads ffl-mcp.exe from the latest GitHub release and registers it with Claude, Codex, and Grok Build.
uvx (no binary, requires uv)
uvx --from git+https://github.com/nuwainfo/ffl-mcp installTargets can be controlled with --target (default: all):
uvx --from git+https://github.com/nuwainfo/ffl-mcp install --target claude-desktop,claude-code,codex,grok-builduvx --from git+https://github.com/nuwainfo/ffl-mcp install --printclaude-code uses the Claude Code CLI. codex writes the native ~/.codex/config.toml configuration used by Codex clients. grok-build writes ~/.grok/config.toml, which Grok Build can reload from /mcps.
Legacy target names (claude-cli, codex-cli, codex-desktop, and grok) remain accepted as aliases. The installer first creates a timestamped backup of any config it changes.
For custom config paths, pass the file:
uvx --from git+https://github.com/nuwainfo/ffl-mcp install --config /path/to/claude_desktop_config.json
uvx --from git+https://github.com/nuwainfo/ffl-mcp install --codex-config /path/to/codex/config.toml
uvx --from git+https://github.com/nuwainfo/ffl-mcp install --grok-config /path/to/grok/config.tomlClaude Code cloud sessions
Cloud-hosted Claude Code sessions start in a fresh container. To make ffl-mcp
available in every new session, open the cloud environment menu in the session
title bar, choose Edit, and add this as the environment Setup script:
claude mcp add ffl -s user -e FFL_USE_STDIN=1 -- uvx --from git+https://github.com/nuwainfo/ffl-mcp ffl-mcpThe setup script runs when each new session starts. In the first new session,
run claude mcp list to confirm that the ffl server was registered.
Run directly (development)
Prereq: uv installed.
# optional safety: restrict file sharing to a directory
export ALLOWED_BASE_DIR="$HOME/Downloads"
# optional: use stdin for text/base64 instead of temp files
export FFL_USE_STDIN=1
uvx --from git+https://github.com/nuwainfo/ffl-mcp ffl-mcpMCP Config (manual JSON)
{
"mcpServers": {
"ffl": {
"command": "uvx",
"args": ["--from", "git+https://github.com/nuwainfo/ffl-mcp", "ffl-mcp"],
"env": {
"ALLOWED_BASE_DIR": "/Users/you/Downloads",
"FFL_USE_STDIN": "1"
}
}
}
}Tools
Sharing
Tool | Input |
| Plain text |
| Binary data (base64-encoded) |
| Single local file or folder |
| Multiple files (ffl auto-zips them into one download) |
Common options for all share tools:
Option | Default | Description |
|
| End-to-end encryption |
|
| Return ASCII QR art ( |
| — | HTTP Basic Auth to protect the link |
|
| Stop serving after N downloads (P2P only) |
|
| Inactivity timeout in seconds (P2P only) |
| — |
|
| auto | Specific pickup code for |
| — | Path to |
| — | Email(s) for |
| — | Custom link alias e.g. |
| — | Email notification when recipient downloads |
| — | Require recipient confirmation before download; pass a message or |
|
| Disable WebRTC, route all traffic through tunnel |
| — | Explicitly choose |
| — | Preferred ffl tunnel, for example |
| — | Local HTTP server port (auto-detect by default). Useful with fixed tunnels. |
|
| Open the ffl invite page in a local browser with the generated sharing link. |
|
| Enable ffl diagnostic error reporting. Disabled by default. |
| — | Upload to FFL server instead of P2P — e.g. |
|
| Resume an interrupted upload |
| — | Proxy URL e.g. |
Additional options for fflShareFile / fflShareFiles:
Option | Default | Description |
|
| Append |
| — | Glob or regex patterns to exclude, comma-separated — e.g. |
| — | Pause server upload at a percentage from 1 to 99. Requires |
|
| Expose as VFS server ( |
| — | Set preferred tunnel for this and future runs — |
preview only affects the returned link's query string and works for any
share (single file, folder, or multi-file). The preview sidecar routes
(/manifest, /file, /thumb — the manifest/thumbnail data behind that
preview page) are a separate, always-on mechanism: MCP starts them
automatically for folder shares and multi-file shares regardless of preview,
and never for single-file shares.
Managed-sandbox policy: In ChatGPT Work, Grok Bot, a cloud-hosted Codex
sandbox, or a Claude Code cloud session (Claude Code on the web / claude.ai/code,
or a remote session started from the Claude app), use forceRelay=True and
preferredTunnel="default:web" immediately. These environments may only allow
outbound HTTPS through a proxy, with no usable UDP/ICE or raw TCP tunnels. Do not
apply this rule to local Claude Code CLI, local Codex CLI, local Grok Build, or
ordinary user machines.
Response fields: sessionId, link, pid, transportDecision, qrCode? (ASCII art when qrInTerminal=True), debugLogPath?. transportDecision reports the selected mode, reason, automatic status, and effective preferredTunnel.
Sharing from a Remote Agent
fflHowToShareFromRemoteAgent() is guidance for a cloud-hosted assistant such
as Grok Bot when the user asks it to share a file or folder on the user's own
computer. It instructs the assistant to operate on that computer, use an
existing ffl/ffl.com when present, or locate the runtime bundled with the
installed ffl-mcp or ffl-python package without relying on a fixed internal
package path. Local agents such as Claude Code, Codex, and Cursor use
fflShareFile directly and do not need this tool.
Downloading
fflDownload(url, outputPath?, resume?, authUser?, authPassword?,
recipientAuth?, pickupCode?, recipientPrivateKey?, proxy?,
enableReporting?)
-> {ok, returncode, outputPath?, transferMode?, transferInfo?, message?, ...}Downloads from FastFileLink URLs (WebRTC P2P when possible, HTTP fallback) or any HTTP(S) URL (works like wget).
| Meaning |
| Direct peer-to-peer over WebRTC (fastest) |
| Direct peer-to-peer over raw TCP/QUIC |
| HTTP relay when P2P fails |
| Regular HTTP download (non-FastFileLink URL) |
For authenticated links: pass recipientAuth + pickupCode (pickup mode) or recipientPrivateKey (pubkey mode).
Set enableReporting=True only when you want to opt into ffl diagnostic error reporting for troubleshooting.
Keygen
fflKeygen(name?) -> {ok, returncode, output}Generates an RSA keypair for passwordless pubkey recipient auth:
<name>.fflpub— share with the sender (pass asrecipientPublicKey)<name>.fflkey— keep private (pass asrecipientPrivateKeywhen downloading)
Session Management
fflListSessions()— list active share sessionsfflStopSession(sessionId)— terminate a sessionfflGetSession(sessionId)— get session detailsfflGetSessionEvents(sessionId, limit=50)— retrieve webhook events
Notes
FFL_USE_STDIN=1avoids writing text/base64 payloads to disk.Folder and multi-file previews start a local webhook server so FFL can register preview routes.
FFL_DEBUG=1saves ffl output to a temp log file; path returned asdebugLogPath. SetFFL_DEBUG=/path/to/log.txtto use a fixed path.ALLOWED_BASE_DIRrestrictsfflShareFile/fflShareFilesto a specific directory.During installation, ffl-mcp probes
example.comandstun.cloudflare.comin parallel for up to 0.5 seconds. If every answer is in the synthetic198.18.0.0/15range, it registersFFL_NETWORK_PROFILE=synthetic-dns-198-18; later shares immediately use relay throughdefault:webinstead of waiting for P2P. No profile is written for timeouts, failures, mixed answers, or ordinary networks.Pass
--env FFL_NETWORK_PROFILE=p2ptoinstallto override the install-time result, or use a share tool'stransportvaluep2pfor one direct-P2P attempt.
Testing
# Unit + binary tests (no network needed)
python -m unittest discover -s tests -p "*Test.py" -v
# All tests including share/download round-trips (requires network)
FFL_INTEGRATION_TESTS=1 python -m unittest discover -s tests -p "*Test.py" -vAvailable Tools
11 toolsfflDownloadFfldownloadB
Download a file from a FastFileLink URL or regular HTTP(S) URL using ffl.
For FastFileLink URLs, this uses WebRTC P2P when possible for faster downloads. For regular URLs, it works like wget.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | FastFileLink URL or regular HTTP(S) URL to download from | |
| proxy | No | Proxy server URL (e.g. socks5://127.0.0.1:9050) | |
| resume | No | Resume incomplete download (default: False) | |
| authUser | No | Username for HTTP Basic Authentication | |
| outputPath | No | Optional output file or directory path (default: use filename from server) | |
| pickupCode | No | 6-digit pickup code (when recipientAuth is pickup) | |
| authPassword | No | Password for HTTP Basic Authentication | |
| recipientAuth | No | Recipient authentication mode required by sender — pickup, pubkey, or email | |
| enableReporting | No | ||
| recipientPrivateKey | No | Path to .fflkey private key file for pubkey auth |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description bears the full load; it does disclose the meaningful behavioral distinction (P2P/WebRTC versus plain HTTP fetch). However it says nothing about authentication flows implied by the schema (recipientAuth, pickupCode, private key), overwrite behavior when outputPath collides with an existing file, or where the file lands by default.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the core action, and the URL-type split is placed before any detail. No filler, but also no elaboration where elaboration would help.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a 10-parameter tool with three mutually exclusive recipient authentication modes and encrypted-key handling; the description never explains how those pieces fit together or what a caller must supply for a pickup-protected link. The output schema covers return values, but the invocation-side complexity is left entirely to the schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 90%, so nearly every parameter is already self-documenting. The description adds no extra meaning about url, resume, proxy, or the auth triad beyond what the schema states; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Download a file') and covers both URL flavors it accepts. Among siblings (share, list, keygen, stop), downloading is unmistakably distinct, though the description never names an alternative to disambiguate further.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains how the tool behaves for each URL type (WebRTC P2P for FastFileLink, wget-like for HTTP), which implies when it applies, but gives no explicit when-to-use/when-not guidance, no mention of prerequisites (auth mode, pickup code), and no pointer to any sibling tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fflGetSessionFflgetsessionC
Get details for a running session.
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden, yet it only implies read-only behavior without stating it. It says nothing about behavior on an unknown or ended sessionId, nor about any auth or scoping requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence that leads with the action, with no wasted words. It is terse to the point of under-specification, but structurally clean.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema covers return values and the tool takes only one parameter, so less prose is needed than for a complex tool. Still, the absence of annotations means the description should have stated read-only semantics and the origin of the sessionId, which it omits.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single required parameter, sessionId, has 0% schema description coverage and the description adds no meaning — it does not say where a session ID comes from (e.g., a share call or fflListSessions) or what format it takes. With one undocumented parameter, the description needed to compensate and does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb+resource ("Get details for a running session") that clearly marks this as a read of a session object. It does not distinguish itself from nearby siblings such as fflGetSessionEvents, fflListSessions, or fflStopSession, so an agent must infer the boundary from names alone.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to call this versus fflListSessions (to find a session) or fflGetSessionEvents (to see activity). The only implied precondition is that the session be "running," with no statement about completed or invalid sessions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fflGetSessionEventsFflgetsessioneventsC
Get recent hook events for a running session.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| sessionId | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It reveals only that this is a read of 'recent' events; it says nothing about behavior when the session is stopped, how far back 'recent' reaches, ordering, or any auth/limit behavior — significant gaps for an unannotated tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence with zero waste. However, the brevity is partly under-specification rather than true economy given the undefined jargon and undocumented parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values needn't be explained, but with no annotations, 0% parameter coverage, and undefined 'hook events', an agent still lacks enough context to call this confidently or know when to prefer it over siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must explain sessionId and limit, but it says nothing about either. 'Recent' only vaguely gestures at the limit parameter, and the schema gives no description of the default of 50 or expected sessionId format.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource: 'Get recent hook events for a running session' tells the agent it retrieves event data rather than session metadata, distinguishing it from siblings like fflGetSession and fflListSessions. The term 'hook events' is domain jargon left undefined, which slightly limits precision.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to call this versus fflGetSession or fflListSessions, and no mention of what to do when a session isn't running. The phrase 'for a running session' hints at a prerequisite but never states it as a condition or exclusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fflKeygenFflkeygenA
Generate an RSA keypair for passwordless pubkey authentication.
Produces two files:
.fflpub — public key (share with the sender)
.fflkey — private key (keep secret; used during download)
The sender then shares with: fflShareFile(..., recipientAuth='pubkey', recipientPublicKey='alice.fflpub') The recipient downloads with: fflDownload(..., recipientAuth='pubkey', recipientPrivateKey='alice.fflkey')
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Base name for the generated key files (default: ffl assigns a name) |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the write side effect (two files created), the security constraint (private key must be kept secret), and which key is used at which stage. It omits where the files are written and whether an existing key with the same name is overwritten — meaningful gaps for a keygen tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose, then a compact file listing, then two one-line workflow examples. Every line carries information the agent needs; nothing is restated from the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need no explanation, and the description fully covers the cross-tool workflow that makes this tool usable. It falls short only on operational details — output directory and overwrite behavior — which matter for a tool that writes key material.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description earns extra credit by spelling out the derived filenames (<name>.fflpub and <name>.fflkey), which tells the agent exactly how the single 'name' argument propagates. It does not clarify the default naming when name is null.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Generate an RSA keypair') plus the purpose ('passwordless pubkey authentication'), and no sibling tool does anything similar, so the boundary is unambiguous. The two-sentence breakdown of what files are produced makes the operation's effect concrete.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not just say when to use it — it shows the full workflow: hand the .fflpub to fflShareFile via recipientAuth='pubkey' and the .fflkey to fflDownload. Naming the sibling tools and the exact parameters that consume the output leaves nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fflListSessionsFfllistsessionsA
List active ffl share sessions started by this MCP server.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It usefully discloses the scope limitation to sessions started by this server, which prevents the agent assuming it sees all sessions, but it says nothing about whether terminated sessions appear, ordering, or limits. The output schema covers return values, lowering the bar somewhat.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler; every clause (active, ffl share, this server) earns its place by narrowing scope.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read with an output schema, the description gives enough to call it correctly and sets scope expectations. Only the lifecycle question (active vs. ended) and ordering/pagination remain unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters and the description correctly presents it as unfiltered, so there is no parameter semantics to explain. Baseline 4 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("List active ffl share sessions") plus a scope qualifier ("started by this MCP server"). It does not explicitly contrast with the closely named siblings fflGetSession and fflGetSessionEvents, so an agent must infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The word "active" narrows the use case implicitly, but there is no explicit when-to-use/when-not or named alternative for inspecting a single session or session history. Usage is inferable but not guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fflStopSessionFflstopsessionC
Stop a running ffl session by sessionId.
| Name | Required | Description | Default |
|---|---|---|---|
| sessionId | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden for a mutation tool. It does not disclose whether stopping is idempotent, whether session data/artifacts are discarded, what error occurs for an invalid or inactive sessionId, or whether cancellation is immediate. Only the bare action is conveyed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no filler. It is efficient, though the brevity is partly under-specification rather than economy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, but for a state-changing tool with no annotations and no parameter documentation the description is too thin. Nothing tells an agent the consequences of stopping a session or how failures manifest.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the schema contributes only the name and type of sessionId. The description repeats that the parameter is a sessionId without adding format, provenance (e.g., obtained from fflListSessions or fflGetSession), or validity constraints, leaving the parameter effectively undocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Stop') and resource ('ffl session') plus the identifier used, which is enough to distinguish it from read-oriented siblings like fflGetSession and fflListSessions. It stops short of naming a sibling or describing scope, but the purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The word 'running' hints at a precondition, but there is no explicit when-to-use guidance, no note about what to do if the session is already stopped or nonexistent, and no routing to alternatives (e.g., fflGetSession to confirm state first). An agent must infer usage entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v0.5.1- Changed
fflDownload10 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / authPassword / descriptionAdded value: +"Password for HTTP Basic Authentication" - added
Input schema / properties / authUser / descriptionAdded value: +"Username for HTTP Basic Authentication" - added
Input schema / properties / outputPath / descriptionAdded value: +"Optional output file or directory path (default: use filename from server)" - added
Input schema / properties / pickupCode / descriptionAdded value: +"6-digit pickup code (when recipientAuth is pickup)" - added
Input schema / properties / proxy / descriptionAdded value: +"Proxy server URL (e.g. socks5://127.0.0.1:9050)" - added
Input schema / properties / recipientAuth / descriptionAdded value: +"Recipient authentication mode required by sender — pickup, pubkey, or email" - added
Input schema / properties / recipientPrivateKey / descriptionAdded value: +"Path to .fflkey private key file for pubkey auth" - added
Input schema / properties / resume / descriptionAdded value: +"Resume incomplete download (default: False)" - added
Input schema / properties / url / descriptionAdded value: +"FastFileLink URL or regular HTTP(S) URL to download from"
- Changed
fflGetSession1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
fflGetSessionEvents1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Added
fflHowToShareFromRemoteAgent - Changed
fflKeygen2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / name / descriptionAdded value: +"Base name for the generated key files (default: ffl assigns a name)"
- Changed
fflListSessions2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / descriptionRemoved value: -"Generic wrapper for non-object return types."
- Changed
fflShareBase6425 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / alias / descriptionAdded value: +"Custom link alias instead of random UID (requires Standard+ account)" - added
Input schema / properties / authPassword / descriptionAdded value: +"HTTP Basic Auth password to protect the link" - added
Input schema / properties / authUser / descriptionAdded value: +"HTTP Basic Auth username to protect the link" - added
Input schema / properties / dataB64 / descriptionAdded value: +"Base64-encoded binary data to share" - added
Input schema / properties / e2ee / descriptionAdded value: +"Enable end-to-end encryption (default: False)" - added
Input schema / properties / enableReporting / descriptionAdded value: +"Enable ffl error reporting for diagnostics (disabled by default)" - added
Input schema / properties / forceRelay / descriptionAdded value: +"Disable direct WebRTC; route all traffic through tunnel" - added
Input schema / properties / hookUrl / descriptionAdded value: +"Custom webhook URL for events" - added
Input schema / properties / invite / descriptionAdded value: +"Open invite page in browser with the sharing link" - added
Input schema / properties / maxDownloads / descriptionAdded value: +"Stop serving after N downloads (default: 1)" - added
Input schema / properties / name / descriptionAdded value: +"Download filename shown to recipient (default: data.bin)" - added
Input schema / properties / pickupCode / descriptionAdded value: +"Specific pickup code to use (default: auto-generated)" - added
Input schema / properties / port / descriptionAdded value: +"Local HTTP server port (default: auto-detect)" - added
Input schema / properties / preferredTunnelAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / proxy / descriptionAdded value: +"Proxy server URL (e.g. socks5://127.0.0.1:9050)" - added
Input schema / properties / qrInTerminal / descriptionAdded value: +"Return ASCII QR code art for terminal display" - added
Input schema / properties / receipt / descriptionAdded value: +"Send email notification when recipient downloads (pass email address, or empty string for account email)" - added
Input schema / properties / receiptConfirm / descriptionAdded value: +"Require recipient to confirm before download starts; pass confirmation message or empty string for default" - added
Input schema / properties / recipientAuth / descriptionAdded value: +"Recipient authentication mode — pickup (6-digit code), pubkey (RSA challenge), pubkey+pickup (both), email (OTP)" - added
Input schema / properties / recipientEmail / descriptionAdded value: +"Recipient email(s) for OTP auth, comma-separated" - added
Input schema / properties / recipientPublicKey / descriptionAdded value: +"Path to recipient .fflpub public key file for pubkey auth" - added
Input schema / properties / timeoutSeconds / descriptionAdded value: +"Stop serving after N seconds of inactivity (default: 1800)" - added
Input schema / properties / transportAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - removed
Input schema / properties / waitLinkSecondsRemoved value: -{ - "default": 20, - "type": "integer" -}
- Changed
fflShareFile27 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / alias / descriptionAdded value: +"Custom link alias instead of random UID (requires Standard+ account)" - added
Input schema / properties / authPassword / descriptionAdded value: +"HTTP Basic Auth password to protect the link" - added
Input schema / properties / authUser / descriptionAdded value: +"HTTP Basic Auth username to protect the link" - added
Input schema / properties / e2ee / descriptionAdded value: +"Enable end-to-end encryption (default: False)" - added
Input schema / properties / exclude / descriptionAdded value: +"Exclude files matching glob or regex patterns, comma-separated (e.g. '*.log' or 're:\\.tmp$')" - added
Input schema / properties / forceRelay / descriptionAdded value: +"Disable direct WebRTC; route all traffic through tunnel" - added
Input schema / properties / hookUrl / descriptionAdded value: +"Custom webhook URL for events" - added
Input schema / properties / maxDownloads / descriptionAdded value: +"Stop serving after N downloads, P2P only (default: 1)" - added
Input schema / properties / name / descriptionAdded value: +"Custom download filename shown to recipient" - added
Input schema / properties / path / descriptionAdded value: +"Path to file or folder to share" - added
Input schema / properties / pickupCode / descriptionAdded value: +"Specific pickup code to use (default: auto-generated)" - added
Input schema / properties / preferredTunnel / descriptionAdded value: +"Set preferred tunnel for this and future runs — cloudflare, ngrok, bore, etc." - added
Input schema / properties / preview / descriptionAdded value: +"Open recipient's browser directly in preview mode — ideal for folders or multiple files so the recipient sees a file list before downloading (default: False)" - added
Input schema / properties / proxy / descriptionAdded value: +"Proxy server URL (e.g. socks5://127.0.0.1:9050)" - added
Input schema / properties / qrInTerminal / descriptionAdded value: +"Return ASCII QR code art for terminal display" - added
Input schema / properties / receipt / descriptionAdded value: +"Send email notification when recipient downloads (pass email address, or empty string for account email)" - added
Input schema / properties / receiptConfirm / descriptionAdded value: +"Require recipient to confirm before download starts; pass confirmation message or empty string for default" - added
Input schema / properties / recipientAuth / descriptionAdded value: +"Recipient authentication mode — pickup (6-digit code), pubkey (RSA challenge), pubkey+pickup (both), email (OTP)" - added
Input schema / properties / recipientEmail / descriptionAdded value: +"Recipient email(s) for OTP auth, comma-separated" - added
Input schema / properties / recipientPublicKey / descriptionAdded value: +"Path to recipient .fflpub public key file for pubkey auth" - added
Input schema / properties / resumeUpload / descriptionAdded value: +"Resume an interrupted upload (default: False)" - added
Input schema / properties / timeoutSeconds / descriptionAdded value: +"Stop serving after N seconds of inactivity, P2P only (default: 1800)" - added
Input schema / properties / transportAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / upload / descriptionAdded value: +"Upload to FFL server for async sharing — recipient doesn't need sender online. Pass duration e.g. '1 day', '6 hours', '1 week' (requires Standard+ account)" - added
Input schema / properties / vfs / descriptionAdded value: +"Expose as VFS server (vfs:// URI) instead of regular download" - removed
Input schema / properties / waitLinkSecondsRemoved value: -{ - "default": 20, - "type": "integer" -}
- Changed
fflShareFiles26 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / alias / descriptionAdded value: +"Custom link alias instead of random UID (requires Standard+ account)" - added
Input schema / properties / authPassword / descriptionAdded value: +"HTTP Basic Auth password to protect the link" - added
Input schema / properties / authUser / descriptionAdded value: +"HTTP Basic Auth username to protect the link" - added
Input schema / properties / e2ee / descriptionAdded value: +"Enable end-to-end encryption (default: False)" - added
Input schema / properties / exclude / descriptionAdded value: +"Exclude files matching glob or regex patterns, comma-separated" - added
Input schema / properties / forceRelay / descriptionAdded value: +"Disable direct WebRTC; route all traffic through tunnel" - added
Input schema / properties / hookUrl / descriptionAdded value: +"Custom webhook URL for events" - added
Input schema / properties / maxDownloads / descriptionAdded value: +"Stop serving after N downloads, P2P only (default: 1)" - added
Input schema / properties / name / descriptionAdded value: +"Custom download filename shown to recipient (e.g. 'release-v2.0.zip')" - added
Input schema / properties / paths / descriptionAdded value: +"List of local file paths to share together (auto-zipped by ffl)" - added
Input schema / properties / pickupCode / descriptionAdded value: +"Specific pickup code to use (default: auto-generated)" - added
Input schema / properties / preferredTunnel / descriptionAdded value: +"Set preferred tunnel — cloudflare, ngrok, bore, etc." - added
Input schema / properties / preview / descriptionAdded value: +"Open recipient's browser directly in preview mode — shows a file list before downloading (default: False). Recommended when sharing multiple files so the recipient can inspect contents first." - added
Input schema / properties / proxy / descriptionAdded value: +"Proxy server URL (e.g. socks5://127.0.0.1:9050)" - added
Input schema / properties / qrInTerminal / descriptionAdded value: +"Return ASCII QR code art for terminal display" - added
Input schema / properties / receipt / descriptionAdded value: +"Send email notification when recipient downloads" - added
Input schema / properties / receiptConfirm / descriptionAdded value: +"Require recipient to confirm before download starts" - added
Input schema / properties / recipientAuth / descriptionAdded value: +"Recipient authentication mode — pickup, pubkey, pubkey+pickup, email" - added
Input schema / properties / recipientEmail / descriptionAdded value: +"Recipient email(s) for OTP auth, comma-separated" - added
Input schema / properties / recipientPublicKey / descriptionAdded value: +"Path to recipient .fflpub public key file for pubkey auth" - added
Input schema / properties / resumeUpload / descriptionAdded value: +"Resume an interrupted upload (default: False)" - added
Input schema / properties / timeoutSeconds / descriptionAdded value: +"Stop serving after N seconds of inactivity, P2P only (default: 1800)" - added
Input schema / properties / transportAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / upload / descriptionAdded value: +"Upload to FFL server for async sharing — e.g. '1 day', '6 hours' (requires Standard+ account)" - removed
Input schema / properties / waitLinkSecondsRemoved value: -{ - "default": 20, - "type": "integer" -}
- Changed
fflShareText25 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / alias / descriptionAdded value: +"Custom link alias instead of random UID (requires Standard+ account)" - added
Input schema / properties / authPassword / descriptionAdded value: +"HTTP Basic Auth password to protect the link" - added
Input schema / properties / authUser / descriptionAdded value: +"HTTP Basic Auth username to protect the link" - added
Input schema / properties / e2ee / descriptionAdded value: +"Enable end-to-end encryption (default: False)" - added
Input schema / properties / enableReporting / descriptionAdded value: +"Enable ffl error reporting for diagnostics (disabled by default)" - added
Input schema / properties / forceRelay / descriptionAdded value: +"Disable direct WebRTC; route all traffic through tunnel" - added
Input schema / properties / hookUrl / descriptionAdded value: +"Custom webhook URL for events" - added
Input schema / properties / invite / descriptionAdded value: +"Open invite page in browser with the sharing link" - added
Input schema / properties / maxDownloads / descriptionAdded value: +"Stop serving after N downloads (default: 1)" - added
Input schema / properties / name / descriptionAdded value: +"Download filename shown to recipient (default: shared.txt)" - added
Input schema / properties / pickupCode / descriptionAdded value: +"Specific pickup code to use (default: auto-generated)" - added
Input schema / properties / port / descriptionAdded value: +"Local HTTP server port (default: auto-detect)" - added
Input schema / properties / preferredTunnelAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - added
Input schema / properties / proxy / descriptionAdded value: +"Proxy server URL (e.g. socks5://127.0.0.1:9050)" - added
Input schema / properties / qrInTerminal / descriptionAdded value: +"Return ASCII QR code art for terminal display" - added
Input schema / properties / receipt / descriptionAdded value: +"Send email notification when recipient downloads (pass email address, or empty string for account email)" - added
Input schema / properties / receiptConfirm / descriptionAdded value: +"Require recipient to confirm before download starts; pass confirmation message or empty string for default" - added
Input schema / properties / recipientAuth / descriptionAdded value: +"Recipient authentication mode — pickup (6-digit code), pubkey (RSA challenge), pubkey+pickup (both), email (OTP)" - added
Input schema / properties / recipientEmail / descriptionAdded value: +"Recipient email(s) for OTP auth, comma-separated" - added
Input schema / properties / recipientPublicKey / descriptionAdded value: +"Path to recipient .fflpub public key file for pubkey auth" - added
Input schema / properties / text / descriptionAdded value: +"Text content to share" - added
Input schema / properties / timeoutSeconds / descriptionAdded value: +"Stop serving after N seconds of inactivity (default: 1800)" - added
Input schema / properties / transportAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +} - removed
Input schema / properties / waitLinkSecondsRemoved value: -{ - "default": 20, - "type": "integer" -}
- Changed
fflStopSession1 field changed- added
Input schema / additionalPropertiesAdded value: +false
10 tool updates
v0.2.1- First observed
fflDownload - First observed
fflGetSession - First observed
fflGetSessionEvents - First observed
fflKeygen - First observed
fflListSessions - First observed
fflShareBase64 - First observed
fflShareFile - First observed
fflShareFiles - First observed
fflShareText - First observed
fflStopSession
TDQS
Scored across 11 tools
Each tool targets a distinct payload type or session operation: share text, base64, single file, or multiple files, plus list/get/stop/events. The file vs. files pair could be confused, but the description explicitly notes auto-zipping, making boundaries clear. Session inspection and guidance tools are clearly separate from sharing actions.
All tools use a consistent ffl-prefixed camelCase convention (fflShareText, fflListSessions, fflStopSession, etc.). Minor deviations like fflDownload (verb only) and fflKeygen (compound noun) break the verb_noun pattern slightly but remain readable and predictable.
11 tools is well within a reasonable range for a file-sharing server, covering sharing, downloading, session management, and key generation. The four share variants are slightly redundant but each maps to a real payload distinction.
The surface covers the full lifecycle: create shares (text/base64/file/files), download, keygen for pubkey auth, plus list/get/stop/events for session lifecycle. Minor gaps like no explicit session renewal or share update exist, but agents can work around them by starting a new share.
Maintenance
Related MCP Connectors
MCP server for Flux AI image generation
MCP server for AI dialogue using various LLM models via AceDataCloud
Official remote MCP server for Archivist AI TTRPG campaign memory: characters, sessions, and more.
Official MCP server for Agentwork — delegate tasks to AI agents with human-in-the-loop
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server for fffinstill — A Research Lab for Your Investment IdeasMIT

kintone MCP Serverofficial
AlicenseBqualityAmaintenanceOfficial MCP server for kintone, enabling AI assistants to manage kintone apps, records, and settings through natural language.202,337 npm59Apache 2.0- AlicenseAqualityDmaintenanceMCP server for Woody, an AI firearms expert that answers questions with verified citations, checks state-specific laws, and routes to specialist agents.319 PyPIMIT
- FlicenseNot gradedqualityBmaintenanceMCP server enabling AI agents to generate AI videos and images, analyze video content, and download videos from Douyin and Xiaohongshu.-