slack-file-upload-mcp
Allows uploading local files to Slack channels, DMs, or thread replies with an optional message, title, and filename override.
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., "@slack-file-upload-mcpupload ~/Downloads/report.csv to #general with message 'Q3 numbers attached'"
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.
slack-file-upload-mcp
A one-tool MCP server that does the thing the normal Slack MCP can't: post a local file to Slack, with a message.
The Slack MCP sends text (slack_send_message) and reads files, but has no way to put a file from your disk into a channel. Run this alongside it and an agent can share a screenshot, CSV, log, or PDF directly.
The tool
slack_upload_file
Arg | Required | Meaning |
| ✅ | Absolute local path ( |
| ✅ | Channel id ( |
| Text posted with the file (Slack's | |
| File title in Slack. Defaults to the filename. | |
| Override the stored name. Defaults to the local basename. | |
| Post as a reply in this thread instead of the channel root. |
Returns one line: Uploaded report.csv (4821 bytes) to C09ABCD1234 · file_id=F0… · ts=1756… · https://…. The ts is the share timestamp, so the Slack MCP can thread replies under the uploaded file.
Uploads go through Slack's current files.getUploadURLExternal → upload → files.completeUploadExternal flow (via slack_sdk's files_upload_v2); the retired files.upload endpoint is not used.
Related MCP server: Notion Uploader MCP
Setup
Token. A user token (
xoxp-…) or bot token (xoxb-…) with:files:write— required.channels:read+groups:read— only needed to resolve#name→ id. Passing aC…id works without them.im:write— only needed to DM aU…user id.
A bot token must be invited to the channel (
/invite @yourapp); a user token posts as you.manifest.yamlin this repo creates an app with exactly those scopes: api.slack.com/apps → Create New App → From a manifest → pick the workspace → paste the file → Create → Install to Workspace (admin approval may be required) → OAuth & Permissions → copy the User OAuth Token (xoxp-…).It's deliberately a separate app from any existing one: adding a scope to an installed app forces a reinstall, which rotates that app's token and breaks whatever else was using it.
Register the server (token lives in the MCP env, not in the repo):
claude mcp add slack-file-upload --scope user \ --env SLACK_MCP_TOKEN=xoxp-your-token \ -- uv run --directory /path/to/slack-file-upload-mcp slack-file-upload-mcp serveVerify:
SLACK_MCP_TOKEN=… uv run slack-file-upload-mcp whoami
Configuration
Env var | Default | Purpose |
| — | The token. Falls back to |
| unset (any path) | Comma-separated directory prefixes the server may read from. Set it to confine a prompt-injected agent to e.g. |
|
| Reject files larger than this before contacting Slack. Slack's own ceiling is 1 GB. |
Guardrails
Path must be absolute and resolve to an existing regular file; directories and symlink targets outside
SLACK_FILE_UPLOAD_ALLOWED_DIRSare rejected (the path isresolve()d before the allowlist check).Empty files are rejected up front — Slack's upload-URL endpoint requires a non-zero length and fails opaquely on 0 bytes.
Slack API errors are translated into actionable text (
not_in_channel→ "invite the app to the channel",missing_scope→ which scopes).
CLI
uv run slack-file-upload-mcp serve # stdio MCP (also the bare default)
uv run slack-file-upload-mcp whoami # verify the token
uv run slack-file-upload-mcp upload ~/x.png '#general' -m 'here you go'upload runs the exact code path the MCP tool runs — useful for smoke tests without a client.
Tests
uv run pytest # offline; the Slack client is stubbedAvailable Tools
1 toolslack_upload_fileA
Upload a local file to a Slack channel, DM, or thread, with an optional message.
This is the piece the Slack MCP is missing: it posts files, not just text. Use it whenever the thing to share lives on disk (a screenshot, CSV, log, PDF) instead of pasting the contents into a message.
Args:
file_path: Absolute path to the local file (~ is expanded). Must be a
regular, non-empty file.
channel: Channel id (C…/G…), DM id (D…), #channel-name, or a
user id (U…) to upload into a DM with that person. Prefer the id:
resolving a name costs an extra API call and needs channels:read, so a
token without it fails with missing_scope — retry with the id, which
the Slack MCP's own results already carry.
message: Text posted with the file (Slack's initial_comment). Supports
Slack mrkdwn — *bold*, _italic_, <url|label>.
title: File title shown in Slack. Defaults to the filename.
filename: Override the name Slack stores. Defaults to the local basename.
thread_ts: Post the file as a reply in this thread instead of the channel root.
Returns: A one-line confirmation with the file id and permalink.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| channel | Yes | ||
| message | No | ||
| filename | No | ||
| file_path | Yes | ||
| thread_ts | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations (readOnlyHint false, destructiveHint false), the description discloses concrete behavioral traits: name resolution requires an extra API call and channels:read, thread_ts posts as a reply, defaults for title/filename, and the return format (one-line confirmation with file id and permalink). It also warns against non-regular or empty files. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, followed by a focused usage rationale, then a clearly labeled Args block and a Returns line. Every sentence carries real content—failure modes, defaults, formatting support—with no filler. The structured layout makes it easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter tool with a return value, the description covers everything an agent needs to invoke it correctly: parameter formats, defaults, prerequisite permissions, error behavior, and expected output. The output schema exists, but the description still adds the one-line confirmation detail, making the tool fully self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate—and it does thoroughly. Each of the six parameters gets meaningful semantics: file_path requires absolute path with ~ expansion and a non-empty regular file; channel lists all accepted formats and the ID-preference rationale; message explains Slack mrkdwn support; title and filename have explicit defaults; thread_ts explains posting as a reply.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Upload a local file to a Slack channel, DM, or thread, with an optional message.' It also frames the tool as 'the piece the Slack MCP is missing,' clearly distinguishing it from text-only posting tools despite having no siblings. The scope and action are unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: 'Use it whenever the thing to share lives on disk (a screenshot, CSV, log, PDF) instead of pasting the contents into a message.' It also gives practical selection guidance on channel IDs vs names, including the extra API call and 'missing_scope' failure mode. This is strong, actionable usage direction.
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 tool update
v0.1.0- First observed
slack_upload_file
TDQS
Scored across 1 tool
Only one tool exists, so there is no possibility of confusion with other tools. Its purpose is singular and clearly described.
The single tool name follows a clear verb_noun pattern with a server prefix: slack_upload_file. This is consistent and intuitive.
The server is intentionally scoped to a single file-upload operation, so one tool is reasonable. It is slightly under the typical 3-15 range but not excessive or sparse given the narrow purpose.
The tool covers the core upload workflow with support for file path, channel, message, title, filename, and thread replies. No obvious missing operations are needed for the stated file-upload focus.
Maintenance
Related MCP Connectors
Enable interaction with Slack workspaces. Supports subscribing to Slack events through Resources.
File uploads for AI agents. Upload, list, and manage files. No signup required.
Connect AnyFile to AI clients to manage files, share links, file requests, and analytics.
Related MCP Servers
- FlicenseAqualityDmaintenanceEnables uploading files to Notion with complete workflow support including file upload, automatic page attachment, and download URL generation. Supports files up to 20MB with custom naming and metadata handling.21-
- FlicenseBqualityDmaintenanceEnables uploading images and files to Notion pages from Cursor chat, supporting multiple attachment types like image blocks, file blocks, cover images, and icons.2-
- FlicenseNot gradedqualityDmaintenanceEnables file operations (PDF, Office, images, archives, media) through natural language, with tools for reading, writing, converting, and analyzing files locally.1-
- AlicenseNot gradedqualityCmaintenanceEnables local file exchange between users and CLI agents via a web UI and MCP server, allowing agents to read/uploads and deliver artifacts without copy-paste.MIT