Skip to main content
Glama
stickafile-mcp

stickafile-mcp

by gitkvn

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

  1. Sign in at stickafile.com, open the gear menu, choose api tokens, and create one.

  2. Register the server with Claude Code, pasting the token:

    claude mcp add stickafile --scope user -e STICKAFILE_TOKEN=sf_... -- npx -y stickafile-mcp
  3. In 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

STICKAFILE_TOKEN

yes

An sf_ API token. Scopes: list portals, push to portals, create links.

STICKAFILE_ALLOW

no

Directories push may read from, separated by : (; on Windows). Default: the directory the server was started in, which Claude Code sets to the project.

STICKAFILE_PORTAL

no

Default portal, by name or 8-character token. When set, a push without portal goes there instead of making a link.

STICKAFILE_URL

no

Base URL. Default https://stickafile.com. Point at a dev deploy to test.

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

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_ALLOW is the real boundary. path must 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 word secret(s) or credential(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. vetPath opens 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 portal raises the bar, but an agent that has called list_portals can 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 of permissions.allow and 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 \\?\GLOBALROOT paths. \\?\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 checkout

The 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 tools
list_portalsList Stickafile portalsA
Read-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

    A4.5/5.0

    Scored across 2 tools

    Disambiguation5/5

    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.

    Naming Consistency4/5

    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.

    Tool Count3/5

    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.

    Completeness3/5

    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

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI agents to securely transfer files between machines via encrypted, expiring share links, with tools for upload, download, status checks, and link management.
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Enables 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.
      1
      ISC
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables 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
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables 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