stickafile-mcp
This server lets an agent upload files from disk to Stickafile and get shareable links, and list the portals it can push to.
push— upload a regular file by absolute path (inside the allowed workspace) and return{ url, name, size }; bytes go from disk to storage without entering the model's context.By default a push creates a standalone link; passing an 8-character portal token (from
list_portals, never an invented name) puts the file into that project portal instead.list_portals— list the portals the token can push to, with name, token, mode (shared/inbox), status, file count, and URL.Enforces safety in the server: refuses dotfiles/credential-shaped names, files outside allowed roots, symlinks/junctions escaping them, multi-hardlink and non-regular files; verifies the opened file is the one vetted.
No resume — a failed push restarts from scratch, so it won't auto-retry; it asks the user first. Uploads run roughly a minute per gigabyte.
Never exposes the API token in tool output.
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., "@stickafile-mcp push dist/report.pdf 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.
stickafile-mcp
An MCP server that lets a coding agent upload a file from disk to Stickafile and hand back a shareable link. The bytes go from disk to storage and never enter the model's context.
Two tools:
push(path, portal?, note?)→{ url, name, size }list_portals()→ the portals the token can push to
A push makes a standalone link by default. Pass a portal token when the file belongs in a project's portal instead.
Install
Sign in at stickafile.com, open the gear menu, choose api tokens, and create one.
Register the server with Claude Code, pasting the token:
claude mcp add stickafile --scope user -e STICKAFILE_TOKEN=sf_... -- npx -y stickafile-mcpIn a project, ask for a link to a file:
push dist/report.pdf and give me the link
The server checks the token once at startup. A revoked, expired, or wrong-server token makes it exit with a message in the client's MCP log instead of failing on the first push. A network failure at startup does not block it; the first call reports the problem instead.
Any MCP client works; the equivalent .mcp.json entry is:
{
"mcpServers": {
"stickafile": {
"type": "stdio",
"command": "npx",
"args": ["-y", "stickafile-mcp"],
"env": { "STICKAFILE_TOKEN": "sf_..." }
}
}
}Related MCP server: pshare-share-mcp
Configuration
Variable | Required | Meaning |
| yes | An |
| no | Directories |
| no | Default portal, by name or 8-character token. When set, a |
| no | Base URL. Default |
Set them with more -e flags on claude mcp add, or in the env block of
.mcp.json.
Agent skill
skills/stickafile/ is an agent skill that
teaches an agent when to push a file, when to pass a portal, and what to do
when a push fails or is refused. It is also listed on
Agensi. To use it directly, copy the folder into your
agent's skills directory (for Claude Code, ~/.claude/skills/stickafile/).
Links and portals
push without portal makes a link: a standalone file owned by your
account, listed under Links on the dashboard, with no portal involved. This is
the quick-send path and needs nothing configured beyond the token. The usual
limits apply: 2 GB and 24 hours on the free plan, 10 GB and 30 days with pack
credit.
push with portal puts the file in that portal instead, so it sits with
a project's other files and the portal's own settings (gate, password, shared
view) apply. The argument takes an 8-character portal token (e.g. a1b2c3d4),
never a name. A name is guessable and an agent can invent a plausible one; a
token has to come from list_portals.
STICKAFILE_PORTAL changes the default: when it is set, a push without
portal goes to that portal rather than making a link. An explicit portal
token still wins. If the configured portal is missing or deactivated, the push
fails rather than silently falling back to a link.
note is optional plain text, up to 500 characters, shown on the download
page under the file name. It is dropped on portals that have notes turned
off.
Safety
push reads files, so it is the tool a prompt injection would aim at. The
controls below run in the server and do not depend on the model behaving.
STICKAFILE_ALLOWis the real boundary.pathmust be absolute, symlinks are resolved first, and the resolved path must sit inside one of the allowed roots. The agent cannot widen the roots.Deny list inside the roots. Dotfiles and dot-directories (
.env,.git,.ssh,.aws, ...) and credential-shaped names are refused, with no override. The name check strips backup and double extensions (id_rsa.bak,server.key.gz) and matches credential words as whole tokens (aws_credentials,prod-secrets.yaml), so a suffix or affix does not slip a key or secret past it. As a side effect, a file whose name contains the whole wordsecret(s)orcredential(s)is refused even when it is not sensitive (e.g.secret_plans.txt). If that is a false positive, you can rename it or copy it to a neutral name yourself, by hand, and push that. This is for the user to do; the agent is told never to rename or copy a file to get it past a refusal.Regular files only, and only what was vetted.
vetPathopens the file once and the uploader reads from that descriptor, so the bytes uploaded are the bytes that were checked — a symlink or file swapped in after the check cannot redirect the upload. The descriptor's device and inode (on Windows, volume serial and NTFS file ID) must match the entry that passed the name checks, or the push is refused. Files with more than one hard link are refused, because a hardlinked name can point at an inode whose home is outside the workspace. If you do want to send one, make a copy yourself by hand and push the copy; the agent is told to ask you rather than make it. The API token never appears in tool output.Portal choice. A push to the wrong shared portal exposes the file to everyone holding that portal's link. The default is therefore a link, which only you and the people you send it to can open; the server never picks a portal on its own. Requiring a token rather than a name for
portalraises the bar, but an agent that has calledlist_portalscan still pass any token it saw, and there is no setting that forbids the argument.
Claude Code's own permission prompt is the human confirmation. The path shown there is the path that gets read.
Don't allowlist or auto-approve
push. Leave it out ofpermissions.allowand don't answer its prompt with "don't ask again". The checks above stop keys, secrets and files outside the workspace, but they cannot tell an ordinary project file you meant to share from one a prompt injection wants sent. Approving each upload yourself is the main defence against an injected instruction uploading a project file.
Known gap: a parent directory swapped mid-check
The open-once check pins the file: if the vetted entry is swapped for a
symlink, junction, or other file before the open, the identity check refuses
it. It does not pin the directories above it. A process that can write
inside an allowed root could replace a parent directory with a link to
somewhere else between the path being resolved and the file being opened,
then put it back; the open and the identity check would then agree on the
outside file. This applies on every platform. Closing it needs the
operating system's path for the open handle (GetFinalPathNameByHandle,
F_GETPATH, /proc/self/fd), which Node does not expose without a native
module. It matters only if something other than you can write into an
allowed folder and race the server, for example an agent whose shell is
sandboxed without network access while this server has it.
Windows
Supported on Windows 10/11 and tested in CI on windows-latest (Node 20
and 22) alongside macOS and Linux. Separate STICKAFILE_ALLOW entries with
;, e.g. C:\Users\me\work;D:\exports; forward slashes and any drive-letter
case work. Windows-specific behaviour:
NTFS alternate data streams (
notes.txt:payload,report.pdf::$DATA) are refused; only a file's main contents are uploaded.Reserved device names (
CON,NUL,COM1,con.txt, ...) are refused, and so are\\.\device paths and\\?\GLOBALROOTpaths.\\?\C:\...long paths work.8.3 short names (
IDED~1,SSHDIR~1) are resolved to the long name before the name checks, so they cannot hide a denied name.Names ending in dots or spaces (
id_rsa.,server.pem) are checked as if the trailing characters were not there.Junctions are treated like symlinks: resolved first, then held to the root. NTFS hard links are refused like any other multi-link file.
Windows has no
O_NOFOLLOW. A swap of the file between the check and the open is caught by the file-ID check instead.
No resume
A failed push restarts from the beginning; the abandoned server-side session
is cleaned up automatically. Because a retry re-sends the whole file, push
tells the agent not to retry on its own and to ask the user first.
Development
npm run test:unit # path and deny-list tests; no network
STICKR_REPO=../stickr npm test # plus the full e2e against a local stickr checkoutThe e2e boots the Stickafile backend from a checkout of the private stickr
repo, so outside contributors cannot run it; npm run test:unit is the suite
that runs anywhere.
src/upload.js is a port of public/upload-core.js in the stickr repo. The
retry, chunking, and presign-continuation logic must stay in step between the
two; see the header comment in each.
Available Tools
2 toolslist_portalsList Stickafile portalsARead-only
List the Stickafile portals this account can push to, with each portal's name, token, mode (shared or inbox), status, and file count. Call this when push reports that a portal must be chosen, or when the user asks what portals exist. Not needed before an ordinary push.
Inputs: no named parameters. Returns: portals
pushPush a file to StickafileA
Upload a file from disk to a Stickafile portal and return a shareable download link. Use this when the user wants to send, share, or hand off a file (a build, an export, a report, an archive, a video, a dataset) to a person or another machine, or asks for "a link" to a file. The bytes are read from disk and uploaded directly; they never enter the conversation. path must be an absolute path to a regular file inside the workspace. Dotfiles and credential-like files (.env, keys, certificates) are refused. portal is an 8-character portal token, obtained from list_portals; never invent one. It is optional when the account has exactly one active portal. If it is omitted and the account has several portals, the tool returns the list of portals (name, token, and whether each is shared) for the user to choose from — relay that and ask; do not pick one yourself. Tell the user which file you are uploading before calling this. Uploads take roughly a minute per gigabyte; call once per file and wait for the result. Do NOT retry a failed push automatically: there is no resume, so a retry re-sends the entire file from the start. Stop and ask the user whether to retry. Returns { url, name, size }.
Inputs: path (required), portal. Returns: url, name, size
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 2 tools
push uploads a file and returns a link, while list_portals enumerates available portals; these are clearly distinct resource+action pairs with no overlap. The descriptions even clarify the dependency relationship between them without creating ambiguity.
Both names use lowercase snake_case, but 'push' is a bare verb while 'list_portals' follows the verb_noun convention. The deviation is minor and both remain readable and predictable in style.
Two tools is thin even for a focused file-sharing server; the primary action (push) plus one helper leaves no room for adjacent operations. It is defensible for a narrowly scoped uploader, but sits at the borderline of feeling under-provisioned.
The core upload-to-link workflow and portal discovery are covered, but there is no way to list files already in a portal, check upload status, delete/revoke a previously shared file, or manage portals beyond listing them. These are notable gaps for a file-sharing lifecycle.
Related MCP Connectors
Hosted file storage for agents: upload, list, download, share by link, expire, scratch.
File uploads for AI agents. Upload, list, and manage files. No signup required.
Persistent file storage for AI agents via MCP and curl. Upload, download, and version files.
Host files from coding agents; stage on a branch and attach to GitHub PRs.
Related MCP Servers
AlicenseNot gradedqualityDmaintenanceEnables AI agents to securely transfer files between machines via encrypted, expiring share links, with tools for upload, download, status checks, and link management.MIT- AlicenseAqualityDmaintenanceEnables AI assistants to upload files and folders to a Pshare instance and generate share links, with support for optional password, TTL, and chunked uploads for large files.1ISC
- AlicenseNot gradedqualityBmaintenanceEnables moving artifacts from ChatGPT/Codex sandboxes to remote server storage via host-native file parameters, streaming large files without Base64 or model-context overhead.MIT
- AlicenseNot gradedqualityBmaintenanceEnables agents to list, upload, download, and delete files on named static sites served by a private home lab, with token scopes controlling read-only or destructive access.Apache 2.0