# Slack Toolkit

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-totallygreg-claude-mp-slack-toolkit`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [totallyGreg](https://agentstack.voostack.com/s/totallygreg)
- **Installs:** 0
- **Category:** [Communication](https://agentstack.voostack.com/c/communication)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [totallyGreg](https://github.com/totallyGreg)
- **Source:** https://github.com/totallyGreg/claude-mp/tree/main/plugins/slack-toolkit/skills/slack-toolkit
- **Website:** https://github.com/totallyGreg/claude-mp

## Install

```sh
agentstack add skill-totallygreg-claude-mp-slack-toolkit
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Slack Toolkit

Direct Slack Web API access via Python CLI. Fills gaps in the official Slack MCP plugin (no Canvas read/update, no reactions) and provides a full fallback when MCP is unavailable.

> **Rule:** Check if the Slack MCP server is connected first. Use this skill only when MCP is unavailable or for operations MCP cannot perform (Canvas read/update, reactions).

## Configuration

| Variable | Source | Required |
|----------|--------|----------|
| `$SLACK_USER_TOKEN` | Env var or `keychainctl get SLACK_USER_TOKEN` | Yes (Canvas, reactions, threads) |
| `$SLACK_BOT_TOKEN` | Env var or `keychainctl get SLACK_BOT_TOKEN` | Optional (channel reads, bot actions) |

Token resolution: env var first, `keychainctl` fallback (macOS-only). Validates prefix (`xoxp-`/`xoxb-`).

## Enterprise Grid

All Slack conversation endpoints require **POST with form-encoded body**. GET returns `not_authed` on enterprise grids. The CLI handles this transparently.

## Canvas Types

Slack has two incompatible canvas backends. The type is determined at the **workspace level** — some workspaces (particularly Enterprise Grid) route all canvas creation through the legacy Quip backend, even when using the `canvases.create` API.

- **Quip-type** (`filetype: "quip"`): Legacy format. Read works (auto HTML→markdown). `canvases.edit` (append/replace) **does not work**. Content limited to ~4KB per create call. Inline comments not accessible via API.
- **New Canvas API** (all other filetypes): Full CRUD via `canvases.create`/`canvases.edit`. Auto-chunked for large content.

The `canvas create` command automatically tests Canvas API availability before creating canvases. Run `canvas probe` to detect your workspace type. On quip workspaces, updating content requires creating a new canvas with the full content.

## CLI Reference

All commands: `python3 ${CLAUDE_PLUGIN_ROOT}/skills/slack-toolkit/scripts/slacker.py  [args]`

### Canvas Operations (MCP gaps)

```bash
# Read canvas content via url_private (reliable for quip canvases; new-type support varies by workspace)
# There is no official canvases.read API — content is fetched via files.info → url_private.
# On failure, outputs JSON metadata (canvas_id, title, filetype, permalink) and exits non-zero.
slacker.py canvas read 

# Create standalone canvas
slacker.py canvas create  --content "# Markdown content"
slacker.py canvas create  --content-file /path/to/file.md

# Create channel-pinned canvas tab (one per channel; use read to find existing)
slacker.py canvas channel-create  --title "Title" --content-file /path/to/file.md

# Update canvas — append from file (recommended for code blocks / large content)
slacker.py canvas update  --append-file /path/to/content.md

# Update canvas — replace a section (requires section_id from read)
slacker.py canvas update  --replace  --content-file /path/to/content.md

# Find section IDs for targeted in-place edits (atomic edit workflow)
slacker.py canvas sections lookup  --section-types h2 --contains-text "Status"
# → {"sections": [{"id": "temp:C:abc123..."}]}

# Then replace that section atomically (no canvas recreation needed)
slacker.py canvas update  --replace temp:C:abc123... --content-file new-status.md

# Delete a canvas permanently (irreversible)
slacker.py canvas delete 

# Manage canvas access
slacker.py canvas access set  read|write|owner --channel-ids C1 C2
slacker.py canvas access set  write --user-ids U1 U2
slacker.py canvas access delete  --channel-ids C1
slacker.py canvas access delete  --user-ids U1

# Rewrite quip canvas as new-type (creates new canvas, outputs both IDs)
slacker.py canvas rewrite 

# Detect workspace canvas type (quip vs new-type)
slacker.py canvas probe
```

Canvas content uses markdown. `canvas create` and `canvas channel-create` send full content in one call (large payloads supported); H4+ headings are auto-downgraded to H3 with a warning. `canvas update --append-file` auto-chunks appends into ~4KB operations. On quip workspaces, create still works but append/replace does not. `--channel-ids` and `--user-ids` are mutually exclusive for access commands. See `references/canvas-operations.md` and `references/api-reference.md` for details.

### Reactions (MCP gap)

```bash
slacker.py react   
slacker.py unreact   
```

Emoji name without colons (e.g., `thumbsup` not `:thumbsup:`).

### Threads & History (MCP fallback)

```bash
# Full thread with pagination
slacker.py thread   [--limit 200]

# Channel history
slacker.py history  [--limit 100]

# Parse Slack URL to channel + timestamp
slacker.py parse-url "https://workspace.slack.com/archives/C0123/p1768255289788089"
```

### Common Flags

| Flag | Description |
|------|-------------|
| `--bot` | Use bot token instead of user token |
| `--limit N` | Max messages to retrieve (default: 200 threads, 100 history; hard cap: 1000) |

## Output Contract

- **stdout**: JSON (compact, parseable) or markdown (canvas read)
- **stderr**: Human-readable errors and pre-flight warnings (speculative — do not treat as failures)
- **Exit codes**: 0=success, 1=usage, 2=auth, 3=API error, 4=rate limited

**API response trust:** `{"ok": true}` is authoritative — no verification read needed. Pre-flight warnings on stderr (e.g., quip detection) are heuristics emitted *before* the call — if the call returns `ok: true`, the operation succeeded regardless.

## Thread URL Parsing

Two formats supported:
- `https://.slack.com/archives//p` → basic
- `...p?thread_ts=&cid=` → threaded reply

Timestamp: strip `p` prefix, insert `.` before last 6 digits.

## Reference Documentation

| Reference | Content |
|-----------|---------|
| `references/api-reference.md` | Endpoint table with methods, scopes, rate tiers |
| `references/canvas-operations.md` | Size limits, quip vs new-type, auto-chunking, update patterns |

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [totallyGreg](https://github.com/totallyGreg)
- **Source:** [totallyGreg/claude-mp](https://github.com/totallyGreg/claude-mp)
- **License:** MIT
- **Homepage:** https://github.com/totallyGreg/claude-mp

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-totallygreg-claude-mp-slack-toolkit
- Seller: https://agentstack.voostack.com/s/totallygreg
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
