Skip to main content
Glama
shivankj11

slack-file-upload-mcp

by shivankj11

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

file_path

Absolute local path (~ expanded). Must be a regular, non-empty file.

channel

Channel id (C…/G…), DM id (D…), #channel-name, or a user id (U…) to DM.

message

Text posted with the file (Slack's initial_comment). Slack mrkdwn: *bold*, _italic_, <url|label>.

title

File title in Slack. Defaults to the filename.

filename

Override the stored name. Defaults to the local basename.

thread_ts

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

  1. Token. A user token (xoxp-…) or bot token (xoxb-…) with:

    • files:write — required.

    • channels:read + groups:read — only needed to resolve #name → id. Passing a C… id works without them.

    • im:write — only needed to DM a U… user id.

    A bot token must be invited to the channel (/invite @yourapp); a user token posts as you.

    manifest.yaml in this repo creates an app with exactly those scopes: api.slack.com/appsCreate New AppFrom 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.

  2. 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 serve
  3. Verify: SLACK_MCP_TOKEN=… uv run slack-file-upload-mcp whoami

Configuration

Env var

Default

Purpose

SLACK_MCP_TOKEN

The token. Falls back to SLACK_USER_TOKEN, SLACK_BOT_TOKEN, SLACK_TOKEN.

SLACK_FILE_UPLOAD_ALLOWED_DIRS

unset (any path)

Comma-separated directory prefixes the server may read from. Set it to confine a prompt-injected agent to e.g. ~/Desktop,/tmp instead of letting it exfiltrate ~/.ssh.

SLACK_FILE_UPLOAD_MAX_MB

1024

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_DIRS are rejected (the path is resolve()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 stubbed

Available Tools

1 tool
slack_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNo
channelYes
messageNo
filenameNo
file_pathYes
thread_tsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

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

Purpose5/5

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.

Usage Guidelines5/5

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. 1 tool updatev0.1.0
    • First observedslack_upload_file

TDQS

A4.9/5.0

Scored across 1 tool

Disambiguation5/5

Only one tool exists, so there is no possibility of confusion with other tools. Its purpose is singular and clearly described.

Naming Consistency5/5

The single tool name follows a clear verb_noun pattern with a server prefix: slack_upload_file. This is consistent and intuitive.

Tool Count4/5

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.

Completeness5/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables file operations (PDF, Office, images, archives, media) through natural language, with tools for reading, writing, converting, and analyzing files locally.
    1
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables 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