Skip to main content
Glama
nuwainfo

ffl-mcp

Official
by nuwainfo

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.

ffl-mcp-demo


Table of Contents


Related MCP server: kintone MCP Server

Installation

⚡ Short URLs for convenience

  • Linux/macOS: curl -fsSL https://fastfilelink.com/mcp/install.sh | bash

  • Windows (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 | bash

Downloads 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 | iex

Downloads 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 install

Targets can be controlled with --target (default: all):

uvx --from git+https://github.com/nuwainfo/ffl-mcp install --target claude-desktop,claude-code,codex,grok-build
uvx --from git+https://github.com/nuwainfo/ffl-mcp install --print

claude-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.toml

Claude 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-mcp

The 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-mcp

MCP 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

fflShareText(text, name?, ...)

Plain text

fflShareBase64(dataB64, name?, ...)

Binary data (base64-encoded)

fflShareFile(path, name?, ...)

Single local file or folder

fflShareFiles(paths, name?, ...)

Multiple files (ffl auto-zips them into one download)

Common options for all share tools:

Option

Default

Description

e2ee

False

End-to-end encryption

qrInTerminal

False

Return ASCII QR art (qrCode in response)

authUser / authPassword

—

HTTP Basic Auth to protect the link

maxDownloads

1

Stop serving after N downloads (P2P only)

timeoutSeconds

1800

Inactivity timeout in seconds (P2P only)

recipientAuth

—

pickup (6-digit code), pubkey (RSA), pubkey+pickup, or email (OTP)

pickupCode

auto

Specific pickup code for pickup mode

recipientPublicKey

—

Path to .fflpub file for pubkey mode

recipientEmail

—

Email(s) for email OTP mode, comma-separated

alias

—

Custom link alias e.g. my-release (requires Standard+ account)

receipt

—

Email notification when recipient downloads

receiptConfirm

—

Require recipient confirmation before download; pass a message or ""

forceRelay

False

Disable WebRTC, route all traffic through tunnel

transport

—

Explicitly choose p2p or relay. p2p overrides an automatically detected managed-sandbox relay profile.

preferredTunnel

—

Preferred ffl tunnel, for example default, default:web, cloudflare, ngrok, or bore. A caller-provided value overrides an automatic profile choice.

port

—

Local HTTP server port (auto-detect by default). Useful with fixed tunnels.

invite

False

Open the ffl invite page in a local browser with the generated sharing link.

enableReporting

False

Enable ffl diagnostic error reporting. Disabled by default.

upload

—

Upload to FFL server instead of P2P — e.g. "1 day", "6 hours" (requires Standard+ account)

resumeUpload

False

Resume an interrupted upload

proxy

—

Proxy URL e.g. socks5://127.0.0.1:9050

Additional options for fflShareFile / fflShareFiles:

Option

Default

Description

preview

False

Append ?preview=true to the returned link, so ffl's download page opens straight into its full preview view instead of the normal floating card.

exclude

—

Glob or regex patterns to exclude, comma-separated — e.g. *.pyc,__pycache__ or re:\.env$

pause

—

Pause server upload at a percentage from 1 to 99. Requires upload.

vfs

False

Expose as VFS server (vfs:// URI) — fflShareFile only

preferredTunnel

—

Set preferred tunnel for this and future runs — cloudflare, ngrok, bore, etc.

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).

transferMode

Meaning

webrtc_p2p

Direct peer-to-peer over WebRTC (fastest)

p2p_tcp / p2p_quic

Direct peer-to-peer over raw TCP/QUIC

http_fallback

HTTP relay when P2P fails

http_direct

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 as recipientPublicKey)

  • <name>.fflkey — keep private (pass as recipientPrivateKey when downloading)

Session Management

  • fflListSessions() — list active share sessions

  • fflStopSession(sessionId) — terminate a session

  • fflGetSession(sessionId) — get session details

  • fflGetSessionEvents(sessionId, limit=50) — retrieve webhook events


Notes

  • FFL_USE_STDIN=1 avoids writing text/base64 payloads to disk.

  • Folder and multi-file previews start a local webhook server so FFL can register preview routes.

  • FFL_DEBUG=1 saves ffl output to a temp log file; path returned as debugLogPath. Set FFL_DEBUG=/path/to/log.txt to use a fixed path.

  • ALLOWED_BASE_DIR restricts fflShareFile/fflShareFiles to a specific directory.

  • During installation, ffl-mcp probes example.com and stun.cloudflare.com in parallel for up to 0.5 seconds. If every answer is in the synthetic 198.18.0.0/15 range, it registers FFL_NETWORK_PROFILE=synthetic-dns-198-18; later shares immediately use relay through default:web instead of waiting for P2P. No profile is written for timeouts, failures, mixed answers, or ordinary networks.

  • Pass --env FFL_NETWORK_PROFILE=p2p to install to override the install-time result, or use a share tool's transport value p2p for 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" -v

Available Tools

11 tools
fflDownloadFfldownloadB

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.

NameRequiredDescriptionDefault
urlYesFastFileLink URL or regular HTTP(S) URL to download from
proxyNoProxy server URL (e.g. socks5://127.0.0.1:9050)
resumeNoResume incomplete download (default: False)
authUserNoUsername for HTTP Basic Authentication
outputPathNoOptional output file or directory path (default: use filename from server)
pickupCodeNo6-digit pickup code (when recipientAuth is pickup)
authPasswordNoPassword for HTTP Basic Authentication
recipientAuthNoRecipient authentication mode required by sender — pickup, pubkey, or email
enableReportingNo
recipientPrivateKeyNoPath to .fflkey private key file for pubkey auth

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

NameRequiredDescriptionDefault
sessionIdYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

C2.8/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

NameRequiredDescriptionDefault
limitNo
sessionIdYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

C2.7/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

fflHowToShareFromRemoteAgentFflhowtosharefromremoteagentA

Only for cloud-hosted assistants (e.g. Grok Bot) that cannot access the user's computer directly. Call this first when you need to share a file or folder that lives on the user's computer. Local agents such as Claude Code, Codex or Cursor do not need it.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does disclose the key behavioral trait: it is a prerequisite step, not the sharing action itself, and it is scoped to a particular class of caller. It does not state side effects, permissions or failure modes, but for a no-parameter guidance tool with an output schema those gaps are small.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with zero waste. The scope restriction is front-loaded ahead of the action, and the exclusion of local agents removes the most likely mis-invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given zero parameters, an output schema and no annotations, the definition covers the two things an agent needs: who should call it and when in the sequence. It stops short of naming the follow-up tool (fflShareFile vs fflShareFiles vs fflShareText), which would have completed the workflow picture.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; baseline of 4 applies. The description adds no parameter-relevant detail, nor does it need to.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific resource (a file or folder on the user's computer) and an ordering role ('call this first'), which distinguishes it from the fflShareFile/fflShareFiles siblings that perform the actual share. It never explicitly says what the tool itself returns (guidance/instructions), so the verb is implied rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use (cloud-hosted assistants like Grok Bot with no direct access to the user's computer), explicit when-not-to-use (local agents such as Claude Code, Codex, Cursor), and an explicit sequencing rule ('call this first'). This is about as unambiguous as guidance gets.

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')

NameRequiredDescriptionDefault
nameNoBase name for the generated key files (default: ffl assigns a name)

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

fflShareBase64Fflsharebase64A

Share arbitrary binary data (base64-encoded) using ffl. Returns a sessionId and link. Managed-sandbox policy: When running inside 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 relay immediately: forceRelay=True and preferredTunnel="default:web". 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.

If qrInTerminal is True, also returns a QR code as ASCII art for terminal display.

IMPORTANT: Always present the returned link so the user can click it to open in a browser. Do not display it as a plain unformatted URL — in some interfaces (such as Claude Dispatch) plain URLs are not auto-linked and will not be clickable.

NameRequiredDescriptionDefault
e2eeNoEnable end-to-end encryption (default: False)
nameNoDownload filename shown to recipient (default: data.bin)data.bin
portNoLocal HTTP server port (default: auto-detect)
aliasNoCustom link alias instead of random UID (requires Standard+ account)
proxyNoProxy server URL (e.g. socks5://127.0.0.1:9050)
inviteNoOpen invite page in browser with the sharing link
dataB64YesBase64-encoded binary data to share
hookUrlNoCustom webhook URL for events
receiptNoSend email notification when recipient downloads (pass email address, or empty string for account email)
authUserNoHTTP Basic Auth username to protect the link
transportNo
forceRelayNoDisable direct WebRTC; route all traffic through tunnel
pickupCodeNoSpecific pickup code to use (default: auto-generated)
authPasswordNoHTTP Basic Auth password to protect the link
maxDownloadsNoStop serving after N downloads (default: 1)
qrInTerminalNoReturn ASCII QR code art for terminal display
recipientAuthNoRecipient authentication mode — pickup (6-digit code), pubkey (RSA challenge), pubkey+pickup (both), email (OTP)
receiptConfirmNoRequire recipient to confirm before download starts; pass confirmation message or empty string for default
recipientEmailNoRecipient email(s) for OTP auth, comma-separated
timeoutSecondsNoStop serving after N seconds of inactivity (default: 1800)
enableReportingNoEnable ffl error reporting for diagnostics (disabled by default)
preferredTunnelNo
recipientPublicKeyNoPath to recipient .fflpub public key file for pubkey auth

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations, so the description must carry the load — and it does disclose what a caller otherwise could not guess: environment-dependent network behavior, forced relay semantics, that qrInTerminal adds ASCII art to the result, and an imperative about link presentation. It stops short of describing session lifetime or the local-server serving model, but the output schema covers the return shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action in one sentence, followed by a clearly labeled policy block and a single imperative note. Despite the length forced by 23 parameters, no sentence is redundant and the operational payload is easy to locate.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 23-parameter tool with an output schema, the description supplies the highest-value missing context: the sandbox networking policy that would otherwise cause silent failures, and the link-presentation requirement. Minor gap is the absence of framing relative to fflShareFile/fflShareFiles and of session lifecycle expectations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 91%, so the baseline is 3; the description earns above that by explaining the two least self-explanatory parameters (forceRelay, preferredTunnel) with the concrete policy and rationale behind their values. The remaining 22 parameters are adequately covered by the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource+format: 'Share arbitrary binary data (base64-encoded) using ffl', plus the return contract (sessionId and link). Against siblings fflShareText/fflShareFile/fflShareFiles, the 'base64-encoded binary data' framing makes the distinction clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit when-to-use rule for a real ambiguity: inside managed sandboxes (ChatGPT Work, Codex sandbox, Claude Code cloud) use forceRelay=True and preferredTunnel='default:web', with an explicit exclusion list for local CLI environments. It does not, however, say when to pick this tool over fflShareFile or fflShareFiles, so selection among siblings is left implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fflShareFileFflsharefileA

Share a local file or folder using ffl. Respects ALLOWED_BASE_DIR when configured. Managed-sandbox policy: When running inside 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 relay immediately: forceRelay=True and preferredTunnel="default:web". 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.

If qrInTerminal is True, also returns a QR code as ASCII art for terminal display.

IMPORTANT: Always present the returned link so the user can click it to open in a browser. Do not display it as a plain unformatted URL — in some interfaces (such as Claude Dispatch) plain URLs are not auto-linked and will not be clickable.

NameRequiredDescriptionDefault
vfsNoExpose as VFS server (vfs:// URI) instead of regular download
e2eeNoEnable end-to-end encryption (default: False)
nameNoCustom download filename shown to recipient
pathYesPath to file or folder to share
portNo
aliasNoCustom link alias instead of random UID (requires Standard+ account)
pauseNo
proxyNoProxy server URL (e.g. socks5://127.0.0.1:9050)
inviteNo
uploadNoUpload 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)
excludeNoExclude files matching glob or regex patterns, comma-separated (e.g. '*.log' or 're:\.tmp$')
hookUrlNoCustom webhook URL for events
previewNoOpen recipient's browser directly in preview mode — ideal for folders or multiple files so the recipient sees a file list before downloading (default: False)
receiptNoSend email notification when recipient downloads (pass email address, or empty string for account email)
authUserNoHTTP Basic Auth username to protect the link
transportNo
forceRelayNoDisable direct WebRTC; route all traffic through tunnel
pickupCodeNoSpecific pickup code to use (default: auto-generated)
authPasswordNoHTTP Basic Auth password to protect the link
maxDownloadsNoStop serving after N downloads, P2P only (default: 1)
qrInTerminalNoReturn ASCII QR code art for terminal display
resumeUploadNoResume an interrupted upload (default: False)
recipientAuthNoRecipient authentication mode — pickup (6-digit code), pubkey (RSA challenge), pubkey+pickup (both), email (OTP)
receiptConfirmNoRequire recipient to confirm before download starts; pass confirmation message or empty string for default
recipientEmailNoRecipient email(s) for OTP auth, comma-separated
timeoutSecondsNoStop serving after N seconds of inactivity, P2P only (default: 1800)
enableReportingNo
preferredTunnelNoSet preferred tunnel for this and future runs — cloudflare, ngrok, bore, etc.
recipientPublicKeyNoPath to recipient .fflpub public key file for pubkey auth

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does add real behavior: it discloses the ALLOWED_BASE_DIR constraint, the sandbox/network posture (outbound HTTPS only, no UDP/ICE or raw TCP), and that qrInTerminal changes the return payload. It stays silent on session lifetime, whether the call blocks, or what happens after maxDownloads/timeout, though those are partly covered in the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose, environment rule, QR note, and output-presentation requirement appear in that order, which is sensible front-loading. The sandbox paragraph is long but earns its length; the trailing formatting instruction is slightly tangential to tool selection yet prevents a real failure mode.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 29-parameter tool with an output schema, the description supplies the pieces the schema cannot: environment-dependent configuration, the base-directory restriction, and the requirement to surface the returned link clickably. What it omits (duration/serving semantics, upload vs P2P tradeoffs) is largely documented per-parameter in the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 83%, so the baseline is 3; the description goes beyond by naming concrete values for forceRelay and preferredTunnel and by explaining they must be used together in sandboxed environments. It adds nothing about the other 26 parameters, but the one parameter cluster it does explain is the one with genuine ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Share a local file or folder using ffl') that is immediately actionable. It does not, however, distinguish itself from the very similar sibling fflShareFiles (plural) or fflShareText/fflShareBase64, so an agent must infer which one to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Contains a strong, explicit environment-based rule (use forceRelay=True and preferredTunnel="default:web" inside ChatGPT Work, Grok Bot, Codex sandbox, Claude Code cloud) with an explicit negative list of local CLIs and user machines. But it gives no guidance on when to choose this tool over fflShareFiles, fflShareText, or fflShareBase64.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fflShareFilesFflsharefilesA

Share multiple local files at once using ffl. ffl auto-zips them into a single download. Managed-sandbox policy: When running inside 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 relay immediately: forceRelay=True and preferredTunnel="default:web". 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.

IMPORTANT: Always present the returned link so the user can click it to open in a browser. Do not display it as a plain unformatted URL — in some interfaces (such as Claude Dispatch) plain URLs are not auto-linked and will not be clickable.

NameRequiredDescriptionDefault
e2eeNoEnable end-to-end encryption (default: False)
nameNoCustom download filename shown to recipient (e.g. 'release-v2.0.zip')
portNo
aliasNoCustom link alias instead of random UID (requires Standard+ account)
pathsYesList of local file paths to share together (auto-zipped by ffl)
pauseNo
proxyNoProxy server URL (e.g. socks5://127.0.0.1:9050)
inviteNo
uploadNoUpload to FFL server for async sharing — e.g. '1 day', '6 hours' (requires Standard+ account)
excludeNoExclude files matching glob or regex patterns, comma-separated
hookUrlNoCustom webhook URL for events
previewNoOpen 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.
receiptNoSend email notification when recipient downloads
authUserNoHTTP Basic Auth username to protect the link
transportNo
forceRelayNoDisable direct WebRTC; route all traffic through tunnel
pickupCodeNoSpecific pickup code to use (default: auto-generated)
authPasswordNoHTTP Basic Auth password to protect the link
maxDownloadsNoStop serving after N downloads, P2P only (default: 1)
qrInTerminalNoReturn ASCII QR code art for terminal display
resumeUploadNoResume an interrupted upload (default: False)
recipientAuthNoRecipient authentication mode — pickup, pubkey, pubkey+pickup, email
receiptConfirmNoRequire recipient to confirm before download starts
recipientEmailNoRecipient email(s) for OTP auth, comma-separated
timeoutSecondsNoStop serving after N seconds of inactivity, P2P only (default: 1800)
enableReportingNo
preferredTunnelNoSet preferred tunnel — cloudflare, ngrok, bore, etc.
recipientPublicKeyNoPath to recipient .fflpub public key file for pubkey auth

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries real weight: it discloses auto-zipping into one download, the networking constraint of managed sandboxes (no UDP/ICE or raw TCP), and the presentation requirement for the returned link. It stops short of disclosing lifecycle/security defaults such as the link remaining live with no auth and E2EE off by default, which matters for a tool that exposes local paths over the network.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose in the first sentence, then the policy block, then the output-presentation rule — a sensible order with no filler. The policy paragraph is verbose for what amounts to one conditional instruction, and the all-caps IMPORTANT block would be better placed with the return-value guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 28-parameter, annotation-free tool with an output schema, the description covers the three things an agent can't infer: auto-zip grouping, sandbox relay configuration, and clickable-link presentation. It leaves the auth/encryption/upload mode choices to schema descriptions, which is acceptable given the 82% coverage but is the remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 82%, so the baseline is 3, but the description adds genuine meaning beyond the schema by prescribing the exact forceRelay=True plus preferredTunnel="default:web" pairing for sandboxed environments, which the schema describes only generically. The many advanced params (upload, e2ee, alias, auth*) get no narrative guidance and rely on their schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'Share multiple local files at once using ffl', plus the key behavior 'ffl auto-zips them into a single download'. The word 'multiple' implicitly separates it from the sibling fflShareFile, and 'local files' separates it from fflShareText/fflShareBase64.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit conditional rule with an explicit exclusion: force relay when inside ChatGPT Work / Grok Bot / Codex sandbox / Claude Code cloud, and 'Do not apply this rule to local Claude Code CLI, local Codex CLI... or ordinary user machines'. It does not, however, say when to pick this over fflShareFile or fflShareText, so sibling selection is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fflShareTextFflsharetextA

Share text content using ffl. Returns a sessionId and link. Managed-sandbox policy: When running inside 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 relay immediately: forceRelay=True and preferredTunnel="default:web". 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.

If qrInTerminal is True, also returns a QR code as ASCII art for terminal display.

IMPORTANT: Always present the returned link so the user can click it to open in a browser. Do not display it as a plain unformatted URL — in some interfaces (such as Claude Dispatch) plain URLs are not auto-linked and will not be clickable.

NameRequiredDescriptionDefault
e2eeNoEnable end-to-end encryption (default: False)
nameNoDownload filename shown to recipient (default: shared.txt)shared.txt
portNoLocal HTTP server port (default: auto-detect)
textYesText content to share
aliasNoCustom link alias instead of random UID (requires Standard+ account)
proxyNoProxy server URL (e.g. socks5://127.0.0.1:9050)
inviteNoOpen invite page in browser with the sharing link
hookUrlNoCustom webhook URL for events
receiptNoSend email notification when recipient downloads (pass email address, or empty string for account email)
authUserNoHTTP Basic Auth username to protect the link
transportNo
forceRelayNoDisable direct WebRTC; route all traffic through tunnel
pickupCodeNoSpecific pickup code to use (default: auto-generated)
authPasswordNoHTTP Basic Auth password to protect the link
maxDownloadsNoStop serving after N downloads (default: 1)
qrInTerminalNoReturn ASCII QR code art for terminal display
recipientAuthNoRecipient authentication mode — pickup (6-digit code), pubkey (RSA challenge), pubkey+pickup (both), email (OTP)
receiptConfirmNoRequire recipient to confirm before download starts; pass confirmation message or empty string for default
recipientEmailNoRecipient email(s) for OTP auth, comma-separated
timeoutSecondsNoStop serving after N seconds of inactivity (default: 1800)
enableReportingNoEnable ffl error reporting for diagnostics (disabled by default)
preferredTunnelNo
recipientPublicKeyNoPath to recipient .fflpub public key file for pubkey auth

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does a good job disclosing return values, the QR-in-terminal behavior, and the sandbox networking constraint that no annotation or schema field expresses. It omits important behavioral facts about the underlying session—e.g. that a link is served only until maxDownloads/timeoutSeconds elapse and that sessions persist until fflStopSession—which are material for a tool with 23 parameters.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and return values are front-loaded, followed by a clearly labeled policy block and a short QR note. The closing IMPORTANT presentation directive is somewhat agent-instruction rather than tool definition, but every block is scannable and earns its space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

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 detailed, and the description still names sessionId and link. Given 23 parameters with no annotations, the sandbox policy and terminal-QR note fill the biggest gaps, though the session lifetime and security posture of an exposed download link are not addressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 91%, so the baseline is 3; the description exceeds that by explaining the joint semantics of forceRelay and preferredTunnel in sandboxed environments, which the schema fields alone do not convey. The remaining parameters (e2ee, receipt, recipientAuth, etc.) are left to their schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Share text content') and names the return values (sessionId and link). The resource type cleanly separates it from siblings such as fflShareFile and fflShareBase64 without needing to inspect their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The managed-sandbox policy gives explicit conditional guidance for when to set forceRelay=True and preferredTunnel="default:web", including a negative rule for local CLI environments. However, there is no guidance on when to choose this tool over fflShareFile/fflShareBase64/fflShareFiles, so tool-selection is only implied by the resource name.

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.

NameRequiredDescriptionDefault
sessionIdYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

C2.7/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters2/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

  1. 11 tool updatesv0.5.1
    • ChangedfflDownload10 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / authPassword / description
        Added value: +"Password for HTTP Basic Authentication"
      • addedInput schema / properties / authUser / description
        Added value: +"Username for HTTP Basic Authentication"
      • addedInput schema / properties / outputPath / description
        Added value: +"Optional output file or directory path (default: use filename from server)"
      • addedInput schema / properties / pickupCode / description
        Added value: +"6-digit pickup code (when recipientAuth is pickup)"
      • addedInput schema / properties / proxy / description
        Added value: +"Proxy server URL (e.g. socks5://127.0.0.1:9050)"
      • addedInput schema / properties / recipientAuth / description
        Added value: +"Recipient authentication mode required by sender — pickup, pubkey, or email"
      • addedInput schema / properties / recipientPrivateKey / description
        Added value: +"Path to .fflkey private key file for pubkey auth"
      • addedInput schema / properties / resume / description
        Added value: +"Resume incomplete download (default: False)"
      • addedInput schema / properties / url / description
        Added value: +"FastFileLink URL or regular HTTP(S) URL to download from"
    • ChangedfflGetSession1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • ChangedfflGetSessionEvents1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • AddedfflHowToShareFromRemoteAgent
    • ChangedfflKeygen2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / name / description
        Added value: +"Base name for the generated key files (default: ffl assigns a name)"
    • ChangedfflListSessions2 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • removedOutput schema / description
        Removed value: -"Generic wrapper for non-object return types."
    • ChangedfflShareBase6425 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / alias / description
        Added value: +"Custom link alias instead of random UID (requires Standard+ account)"
      • addedInput schema / properties / authPassword / description
        Added value: +"HTTP Basic Auth password to protect the link"
      • addedInput schema / properties / authUser / description
        Added value: +"HTTP Basic Auth username to protect the link"
      • addedInput schema / properties / dataB64 / description
        Added value: +"Base64-encoded binary data to share"
      • addedInput schema / properties / e2ee / description
        Added value: +"Enable end-to-end encryption (default: False)"
      • addedInput schema / properties / enableReporting / description
        Added value: +"Enable ffl error reporting for diagnostics (disabled by default)"
      • addedInput schema / properties / forceRelay / description
        Added value: +"Disable direct WebRTC; route all traffic through tunnel"
      • addedInput schema / properties / hookUrl / description
        Added value: +"Custom webhook URL for events"
      • addedInput schema / properties / invite / description
        Added value: +"Open invite page in browser with the sharing link"
      • addedInput schema / properties / maxDownloads / description
        Added value: +"Stop serving after N downloads (default: 1)"
      • addedInput schema / properties / name / description
        Added value: +"Download filename shown to recipient (default: data.bin)"
      • addedInput schema / properties / pickupCode / description
        Added value: +"Specific pickup code to use (default: auto-generated)"
      • addedInput schema / properties / port / description
        Added value: +"Local HTTP server port (default: auto-detect)"
      • addedInput schema / properties / preferredTunnel
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedInput schema / properties / proxy / description
        Added value: +"Proxy server URL (e.g. socks5://127.0.0.1:9050)"
      • addedInput schema / properties / qrInTerminal / description
        Added value: +"Return ASCII QR code art for terminal display"
      • addedInput schema / properties / receipt / description
        Added value: +"Send email notification when recipient downloads (pass email address, or empty string for account email)"
      • addedInput schema / properties / receiptConfirm / description
        Added value: +"Require recipient to confirm before download starts; pass confirmation message or empty string for default"
      • addedInput schema / properties / recipientAuth / description
        Added value: +"Recipient authentication mode — pickup (6-digit code), pubkey (RSA challenge), pubkey+pickup (both), email (OTP)"
      • addedInput schema / properties / recipientEmail / description
        Added value: +"Recipient email(s) for OTP auth, comma-separated"
      • addedInput schema / properties / recipientPublicKey / description
        Added value: +"Path to recipient .fflpub public key file for pubkey auth"
      • addedInput schema / properties / timeoutSeconds / description
        Added value: +"Stop serving after N seconds of inactivity (default: 1800)"
      • addedInput schema / properties / transport
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • removedInput schema / properties / waitLinkSeconds
        Removed value: -{
        -  "default": 20,
        -  "type": "integer"
        -}
    • ChangedfflShareFile27 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / alias / description
        Added value: +"Custom link alias instead of random UID (requires Standard+ account)"
      • addedInput schema / properties / authPassword / description
        Added value: +"HTTP Basic Auth password to protect the link"
      • addedInput schema / properties / authUser / description
        Added value: +"HTTP Basic Auth username to protect the link"
      • addedInput schema / properties / e2ee / description
        Added value: +"Enable end-to-end encryption (default: False)"
      • addedInput schema / properties / exclude / description
        Added value: +"Exclude files matching glob or regex patterns, comma-separated (e.g. '*.log' or 're:\\.tmp$')"
      • addedInput schema / properties / forceRelay / description
        Added value: +"Disable direct WebRTC; route all traffic through tunnel"
      • addedInput schema / properties / hookUrl / description
        Added value: +"Custom webhook URL for events"
      • addedInput schema / properties / maxDownloads / description
        Added value: +"Stop serving after N downloads, P2P only (default: 1)"
      • addedInput schema / properties / name / description
        Added value: +"Custom download filename shown to recipient"
      • addedInput schema / properties / path / description
        Added value: +"Path to file or folder to share"
      • addedInput schema / properties / pickupCode / description
        Added value: +"Specific pickup code to use (default: auto-generated)"
      • addedInput schema / properties / preferredTunnel / description
        Added value: +"Set preferred tunnel for this and future runs — cloudflare, ngrok, bore, etc."
      • addedInput schema / properties / preview / description
        Added 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)"
      • addedInput schema / properties / proxy / description
        Added value: +"Proxy server URL (e.g. socks5://127.0.0.1:9050)"
      • addedInput schema / properties / qrInTerminal / description
        Added value: +"Return ASCII QR code art for terminal display"
      • addedInput schema / properties / receipt / description
        Added value: +"Send email notification when recipient downloads (pass email address, or empty string for account email)"
      • addedInput schema / properties / receiptConfirm / description
        Added value: +"Require recipient to confirm before download starts; pass confirmation message or empty string for default"
      • addedInput schema / properties / recipientAuth / description
        Added value: +"Recipient authentication mode — pickup (6-digit code), pubkey (RSA challenge), pubkey+pickup (both), email (OTP)"
      • addedInput schema / properties / recipientEmail / description
        Added value: +"Recipient email(s) for OTP auth, comma-separated"
      • addedInput schema / properties / recipientPublicKey / description
        Added value: +"Path to recipient .fflpub public key file for pubkey auth"
      • addedInput schema / properties / resumeUpload / description
        Added value: +"Resume an interrupted upload (default: False)"
      • addedInput schema / properties / timeoutSeconds / description
        Added value: +"Stop serving after N seconds of inactivity, P2P only (default: 1800)"
      • addedInput schema / properties / transport
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedInput schema / properties / upload / description
        Added 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)"
      • addedInput schema / properties / vfs / description
        Added value: +"Expose as VFS server (vfs:// URI) instead of regular download"
      • removedInput schema / properties / waitLinkSeconds
        Removed value: -{
        -  "default": 20,
        -  "type": "integer"
        -}
    • ChangedfflShareFiles26 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / alias / description
        Added value: +"Custom link alias instead of random UID (requires Standard+ account)"
      • addedInput schema / properties / authPassword / description
        Added value: +"HTTP Basic Auth password to protect the link"
      • addedInput schema / properties / authUser / description
        Added value: +"HTTP Basic Auth username to protect the link"
      • addedInput schema / properties / e2ee / description
        Added value: +"Enable end-to-end encryption (default: False)"
      • addedInput schema / properties / exclude / description
        Added value: +"Exclude files matching glob or regex patterns, comma-separated"
      • addedInput schema / properties / forceRelay / description
        Added value: +"Disable direct WebRTC; route all traffic through tunnel"
      • addedInput schema / properties / hookUrl / description
        Added value: +"Custom webhook URL for events"
      • addedInput schema / properties / maxDownloads / description
        Added value: +"Stop serving after N downloads, P2P only (default: 1)"
      • addedInput schema / properties / name / description
        Added value: +"Custom download filename shown to recipient (e.g. 'release-v2.0.zip')"
      • addedInput schema / properties / paths / description
        Added value: +"List of local file paths to share together (auto-zipped by ffl)"
      • addedInput schema / properties / pickupCode / description
        Added value: +"Specific pickup code to use (default: auto-generated)"
      • addedInput schema / properties / preferredTunnel / description
        Added value: +"Set preferred tunnel — cloudflare, ngrok, bore, etc."
      • addedInput schema / properties / preview / description
        Added 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."
      • addedInput schema / properties / proxy / description
        Added value: +"Proxy server URL (e.g. socks5://127.0.0.1:9050)"
      • addedInput schema / properties / qrInTerminal / description
        Added value: +"Return ASCII QR code art for terminal display"
      • addedInput schema / properties / receipt / description
        Added value: +"Send email notification when recipient downloads"
      • addedInput schema / properties / receiptConfirm / description
        Added value: +"Require recipient to confirm before download starts"
      • addedInput schema / properties / recipientAuth / description
        Added value: +"Recipient authentication mode — pickup, pubkey, pubkey+pickup, email"
      • addedInput schema / properties / recipientEmail / description
        Added value: +"Recipient email(s) for OTP auth, comma-separated"
      • addedInput schema / properties / recipientPublicKey / description
        Added value: +"Path to recipient .fflpub public key file for pubkey auth"
      • addedInput schema / properties / resumeUpload / description
        Added value: +"Resume an interrupted upload (default: False)"
      • addedInput schema / properties / timeoutSeconds / description
        Added value: +"Stop serving after N seconds of inactivity, P2P only (default: 1800)"
      • addedInput schema / properties / transport
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedInput schema / properties / upload / description
        Added value: +"Upload to FFL server for async sharing — e.g. '1 day', '6 hours' (requires Standard+ account)"
      • removedInput schema / properties / waitLinkSeconds
        Removed value: -{
        -  "default": 20,
        -  "type": "integer"
        -}
    • ChangedfflShareText25 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedInput schema / properties / alias / description
        Added value: +"Custom link alias instead of random UID (requires Standard+ account)"
      • addedInput schema / properties / authPassword / description
        Added value: +"HTTP Basic Auth password to protect the link"
      • addedInput schema / properties / authUser / description
        Added value: +"HTTP Basic Auth username to protect the link"
      • addedInput schema / properties / e2ee / description
        Added value: +"Enable end-to-end encryption (default: False)"
      • addedInput schema / properties / enableReporting / description
        Added value: +"Enable ffl error reporting for diagnostics (disabled by default)"
      • addedInput schema / properties / forceRelay / description
        Added value: +"Disable direct WebRTC; route all traffic through tunnel"
      • addedInput schema / properties / hookUrl / description
        Added value: +"Custom webhook URL for events"
      • addedInput schema / properties / invite / description
        Added value: +"Open invite page in browser with the sharing link"
      • addedInput schema / properties / maxDownloads / description
        Added value: +"Stop serving after N downloads (default: 1)"
      • addedInput schema / properties / name / description
        Added value: +"Download filename shown to recipient (default: shared.txt)"
      • addedInput schema / properties / pickupCode / description
        Added value: +"Specific pickup code to use (default: auto-generated)"
      • addedInput schema / properties / port / description
        Added value: +"Local HTTP server port (default: auto-detect)"
      • addedInput schema / properties / preferredTunnel
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedInput schema / properties / proxy / description
        Added value: +"Proxy server URL (e.g. socks5://127.0.0.1:9050)"
      • addedInput schema / properties / qrInTerminal / description
        Added value: +"Return ASCII QR code art for terminal display"
      • addedInput schema / properties / receipt / description
        Added value: +"Send email notification when recipient downloads (pass email address, or empty string for account email)"
      • addedInput schema / properties / receiptConfirm / description
        Added value: +"Require recipient to confirm before download starts; pass confirmation message or empty string for default"
      • addedInput schema / properties / recipientAuth / description
        Added value: +"Recipient authentication mode — pickup (6-digit code), pubkey (RSA challenge), pubkey+pickup (both), email (OTP)"
      • addedInput schema / properties / recipientEmail / description
        Added value: +"Recipient email(s) for OTP auth, comma-separated"
      • addedInput schema / properties / recipientPublicKey / description
        Added value: +"Path to recipient .fflpub public key file for pubkey auth"
      • addedInput schema / properties / text / description
        Added value: +"Text content to share"
      • addedInput schema / properties / timeoutSeconds / description
        Added value: +"Stop serving after N seconds of inactivity (default: 1800)"
      • addedInput schema / properties / transport
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • removedInput schema / properties / waitLinkSeconds
        Removed value: -{
        -  "default": 20,
        -  "type": "integer"
        -}
    • ChangedfflStopSession1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
  2. 10 tool updatesv0.2.1
    • First observedfflDownload
    • First observedfflGetSession
    • First observedfflGetSessionEvents
    • First observedfflKeygen
    • First observedfflListSessions
    • First observedfflShareBase64
    • First observedfflShareFile
    • First observedfflShareFiles
    • First observedfflShareText
    • First observedfflStopSession

TDQS

A3.6/5.0

Scored across 11 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count4/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers