Skip to content

mobydeck/skate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🛹 Skate

Access Mattermost Boards tasks from CLI and AI agents via MCP.

Skate lets you manage project tasks, track time, and collaborate with AI coding agents — all from your terminal. It's a thin, stateless Go client over the Mattermost Boards API with zero runtime dependencies.

Install

Homebrew (macOS / Linux)

brew install mobydeck/tap/skate

macOS note: If Gatekeeper blocks the binary on first run, allow it with: xattr -d com.apple.quarantine $(which skate)

Binary download

Download from Releases, or build from source:

git clone https://github.com/mobydeck/skate
cd skate
make install   # builds and installs to ~/.local/bin/

Cross-build for all platforms:

just cross-build   # outputs to dist/

Setup

1. Initialize global config

skate init

You'll need:

  • Your Mattermost server URL (e.g., https://mm.example.com)
  • A personal access token
  • Your team ID (auto-detected if only one team)

Re-run skate init anytime to update settings — existing values are shown as defaults.

2. Initialize per-project config

In your project directory:

skate local-init

This creates .skate.yaml with the board ID for this project. Skate walks up directories to find the nearest .skate.yaml and merges it with the global config, so nested folders inherit settings. Re-run to change the board.

3. Connect an AI agent

skate setup claude-code   # Claude Code
skate setup cursor        # Cursor
skate setup codex         # Codex
skate setup opencode      # OpenCode
skate setup roocode       # RooCode

This registers the MCP server and installs a skill file (SKILL.md — the workflow guide) that teaches the agent how to use Skate.

Use --project / -p flag to install for the current project only (writes to .mcp.json instead of global config).

Re-run after every skate upgradeskate setup overwrites the installed SKILL.md with the version embedded in the new binary, so the agent picks up new tools and conventions. Use diff <(skate skill) <(tail -n +6 ~/.claude/skills/skate/SKILL.md) to check whether the installed copy is in sync.

4. Bootstrap an AI agent session

In most cases nothing extra is needed:

  • The MCP server returns the workflow guide's location during the initialize handshake (the instructions field). Claude Code and other compliant clients inject this into the model's context automatically — no manual prompt required.
  • If no installed SKILL.md is found (e.g. --project install or unknown agent), the handshake instead tells the agent to call the skate_help MCP tool, which returns the same content inline.

If an agent doesn't honor either signal, paste the output of skate prompt into the chat:

skate prompt claude-code   # or: cursor, codex
Before starting work, read and follow rules in /home/user/.claude/skills/skate/SKILL.md

CLI Commands

Boards

$ skate boards
ID                           TITLE                   TYPE
bto6yyshu77yj5x5mbu34cnhzcr  🗓️ Sprint Planner       Private
bht3p6dq1i381jrzx8kngmt4gjw  🎯 Arthur – Tasks       Private
bqn9n36errtymuqk1ph7xy7coiw  📖 Read Books           Private
skate boards                          # List all boards
skate boards --json                   # JSON output
skate boards --yaml                   # YAML output

Tasks

By default, skate tasks shows only Not Started and In Progress tasks, sorted by priority (high to low).

$ skate tasks
ID                           TITLE                        STATUS       PRIORITY   ASSIGNEE
c4cf6f4wzbjgxdm3hpa7iygtjdo  Task translation middleware  Not Started  2. Medium
cuppcm819atnixx71qg9i485jsr  listing tasks                In Progress  1. High 🔥
skate tasks                           # Active tasks from .skate.yaml board
skate tasks --all                     # All tasks regardless of status
skate tasks --status "Not Started"    # Filter by specific status
skate tasks --board <BOARD_ID>        # Specific board
skate tasks --mine                    # Only tasks assigned to you
skate tasks --all-users               # All users (overrides only_mine config)
skate tasks --json                    # JSON output
skate task <TASK_ID>                  # View task details (last 5 comments)
skate task <TASK_ID> --full           # View task with all comments
skate task <TASK_ID> -T               # View task without translation
skate task <TASK_ID> --json           # Full task data as JSON
skate comments <TASK_ID>              # View all comments for a task
skate task-files <TASK_ID>            # List attached files
skate download <FILE_ID>              # Download a file (board from .skate.yaml)
skate download <FILE_ID> -b <BOARD>   # Download from specific board
skate find "search term"              # Search tasks by title and content
skate find "bug" --json               # Search with JSON output
skate next                            # Top-priority Not Started task (renders full task)
skate next --mine                     # Top of queue limited to your assignments
skate state                           # Snapshot: who you are, running timer, your in-progress tasks

Task detail renders as markdown:

$ skate task c4cf6f4wzbjgxdm3hpa7iygtjdo

# 📪 Task translation middleware

| Property | Value |
|----------|-------|
| Status   | In Progress |
| Priority | 2. Medium |

## Description
Add translation middleware for non-English board content...

## Comments
**@arthur** (Apr 3, 2026):
> Implemented translation middleware with OpenAI SDK

## Time Tracking
- @arthur: 00:08

Total: 00:08

Task Management

skate create "Fix login bug" --status "Not Started" --priority "High"
skate create "New feature" --description "Detailed description here"
skate create "Triage failing job" --assignee arthur          # accepts username or user ID
skate statuses                                    # list available statuses for the board
skate update <TASK_ID> --title "New title"        # rename a task
skate update <TASK_ID> --priority "High"          # change priority
skate update <TASK_ID> --assignee arthur          # reassign (username or user ID)
skate update <TASK_ID> --status "In Progress" -t  # status + start timer
skate update-status <TASK_ID> "In Progress"       # shortcut for --status
skate update-status <TASK_ID> "In Progress" -t   # update status + start timer
skate update-status <ID1> <ID2> <ID3> "Completed" # batch close (continues on failures)
skate comment <TASK_ID> "Implemented the fix, running tests"
skate add-content <TASK_ID> "Discovery: the API requires ..."   # text block (default)
skate add-content <TASK_ID> "Architecture" -t h2               # heading block
skate add-content <TASK_ID> -t divider                         # divider block
skate add-content <TASK_ID> "Review audit" -t checkbox         # checkbox block
skate add-content <TASK_ID> ./diagram.png -t image             # inline image block
skate attach <TASK_ID> ./screenshot.png
skate edit-block <TASK_ID> <BLOCK_ID> "new text"               # rewrite a comment, content block, or heading
skate delete-block <TASK_ID> <BLOCK_ID>                        # remove a wrong comment, content block, or attachment

Time Tracking

Time tracking requires the Mattermost Boards time tracking plugin. If unavailable, timer commands will print a message and continue without error.

$ skate timer-start c4cf6f4wzbjgxdm3hpa7iygtjdo
Timer started on: Task translation middleware

$ skate timer-stop --notes "Completed implementation"
Timer stopped: Task translation middleware — 00:08
skate timer-start <TASK_ID>                     # Start timer (auto-stops previous)
skate timer-stop --notes "Completed feature"    # Stop running timer
skate time-add <TASK_ID> 01:30 --notes "Code review"   # Add manual time
skate time-add <TASK_ID> 02:00 --date 2026-04-01       # Backdate entry

Configuration

skate config                          # Show effective config (merged global + local + env)
skate config --json                   # JSON output
skate me                              # Show the authenticated Mattermost user
skate users                           # List team members
skate users arthur                    # Filter team members by username/name substring

Workflow guide (SKILL.md)

skate skill                                                        # Print the embedded workflow guide
skate skill | less                                                 # Paginate
diff <(skate skill) <(tail -n +6 ~/.claude/skills/skate/SKILL.md)  # Check installed copy is current

skate skill prints the same content the skate_help MCP tool returns. Useful for iterating on the guide and verifying that skate setup installed the latest version.

Cache

skate cache ls          # List cached download files (size + mtime)
skate cache clean       # Delete all cached download files

The cache holds files saved by the skate_download MCP tool when an agent didn't pass an explicit output_path. Default location: ~/.cache/skate/downloads/ (Linux) / %LocalAppData%\skate\downloads\ (Windows).

Output Formats

All data commands support --json / -j and --yaml / -y flags:

skate boards --json
skate tasks --yaml
skate task <ID> -j
skate task-files <ID> -y

Pretty markdown rendering (--pretty / -P)

For commands that emit markdown (skate task, skate next, skate skill, skate comments), pass --pretty (or -P) to render via Glamour with terminal styling:

skate task <ID> -P
skate next --pretty
skate skill -P | less -R

This is a human-only ergonomics flag — it's intentionally hidden from --help and not advertised to AI agents. The rendered output contains ANSI escapes and is unsuitable for parsing or automation; use the default raw-markdown output (or --json) when scripting.

When stdout is not a TTY (e.g. piped to a file), Glamour falls back to plain reformatted text so pipelines don't get poisoned with escape codes.

MCP Tools

When connected via MCP, AI agents can use these tools.

The MCP server's initialize response sets the instructions field to a one-line directive pointing the agent at the installed SKILL.md (or telling it to call skate_help if no file is installed). Most clients inject this into the model's context automatically, so the agent learns the workflow without any manual setup.

Tool Description
skate_help Return the canonical Skate workflow guide (the same content as the installed SKILL.md) plus the server's configured board_id
skate_statuses List available statuses for the board
skate_boards List available boards
skate_tasks List tasks (default: active only; show_all, mine, all_users flags)
skate_next Pick the highest-priority Not Started task and return its full details
skate_state Session-resume snapshot: user, running timer, your In Progress tasks
skate_task Get task details as markdown (all comments shown via MCP; no_translate to skip translation)
skate_update_status Change one or many task statuses (task_id single or task_ids array; optional start_timer for single)
skate_update_task Update any of: title, icon, status, priority, assignee (optional start_timer)
skate_create_task Create a new task (assignee accepts a user ID)
skate_comment Add a comment to a task
skate_add_content Add a content block (text, h1-h3, divider, checkbox, image)
skate_attach Upload a local file and attach it to a task
skate_edit_block Rewrite a content block, comment, or heading in place
skate_delete_block Delete a content block, comment, or attachment by block ID
skate_download Download an attached file. ≤32 KiB UTF-8 → inline; otherwise auto-saved to ~/.cache/skate/downloads/<file_id> (or output_path if given).
skate_comments Get all comments for a task (no_translate to skip translation)
skate_task_files List files attached to a task
skate_find Search tasks by title and content
skate_config Show effective configuration (mentions, translate)
skate_me Show the authenticated Mattermost user (id, username)
skate_users List team members (optional query substring filter)
skate_timer_start Start timer on a task
skate_timer_stop Stop running timer with notes
skate_time_add Add manual time entry

Example Prompts for AI Agents

"Look at the board tasks, pick the highest priority unstarted task, and implement it"

"Check my current tasks and update the one I'm working on"

"Create a task for the bug I just found in the auth module"

"Start a timer, implement the task, then stop the timer with notes"

"List all tasks assigned to me that are In Progress"

"Take the next task by priority"

"Work on next task"

Translation

Skate can automatically translate non-English board content to English using any OpenAI-compatible API (OpenAI, Ollama, OpenRouter, etc.).

Enable in config:

# ~/.config/skate.yaml
translate:
  enabled: true
  provider: openai         # or ollama, openrouter
  model: gpt-5-mini        # any chat model
  base_url: ""             # custom endpoint (e.g., http://localhost:11434/v1 for Ollama)
  api_key: "sk-..."        # API key (not needed for Ollama)

Translation uses a fast heuristic to detect non-English text and only calls the API when needed. English content passes through untouched.

Config Files

  • Global: ~/.config/skate.yaml (Linux), %AppData%\skate\skate.yaml (Windows)
  • Local: .skate.yaml (per project, walks up directories)
  • User cache: ~/.cache/skate/users.yaml (Linux), %LocalAppData%\skate\users.yaml (Windows)
# ~/.config/skate.yaml
mattermost_url: "https://mm.example.com"
token: "your-personal-access-token"
team_id: "your-team-id"
only_mine: false           # show only your tasks by default
mentions: true             # @mention users in agent comments (default: true)

translate:
  enabled: false
  provider: openai
  model: gpt-5-mini
  base_url: ""
  api_key: ""
# .skate.yaml (in project root)
board_id: "your-board-id"

# Local config can also override global settings per project:
# mattermost_url: "https://other-server.com"
# mentions: false
# translate:
#   enabled: true
#   model: llama3

Environment Variables

All config values can be overridden with environment variables:

Variable Description
SKATE_URL Mattermost server URL
SKATE_TOKEN Personal access token
SKATE_TEAM_ID Team ID
SKATE_BOARD_ID Default board ID
SKATE_TRANSLATE_ENABLED Enable translation (true/1)
SKATE_TRANSLATE_PROVIDER Translation provider
SKATE_TRANSLATE_MODEL Model name
SKATE_TRANSLATE_BASE_URL Custom API endpoint
SKATE_TRANSLATE_API_KEY API key

Building

make build         # build for current platform
make install       # build + install to ~/.local/bin/
make test          # run tests
just cross-build   # cross-build for linux/darwin/windows (amd64 + arm64)
just release       # create draft GitHub release with all binaries

Version is set at build time via ldflags. It defaults to dev, or auto-derives from git tags:

VERSION=1.0.0 make build   # explicit version

Architecture

  • Pure Go — single static binary, no runtime dependencies, cross-compilable to 5 platforms
  • Stateless — no local database, all data lives in Mattermost
  • User cache — resolved usernames cached in ~/.cache/skate/users.yaml (Linux) or %LocalAppData%\skate\ (Windows)
  • MCP stdio — agents start skate on demand, zero idle cost
  • Config merging — global config + local .skate.yaml + env vars (env wins)
  • Version — set via ldflags, shared across CLI, HTTP client User-Agent, and MCP server

License

See LICENSE for details.

About

Access Mattermost Boards tasks from CLI and AI agents via MCP

Resources

Stars

Watchers

Forks

Contributors

Languages