Motion MCP Public
io.github.dishui/motion-mcp-public
Documentation
motion-mcp
A remote MCP server that connects Claude to Motion — read and manage your tasks, projects, and comments using plain English.
Features
- 11 tools — read and write tasks, projects, comments, schedules, and recurring tasks
- Per-user auth — each person connects their own Motion account via OAuth; data is fully isolated
- Works with Claude.ai and Claude Code
Tools
| Tool | Description |
|---|---|
get_tasks | Get tasks (defaults to current user) |
get_workspaces | List all workspaces |
get_projects | List projects in a workspace |
get_schedule | Get work schedule and timezone |
get_task_comments | Get comments on a task |
get_recurring_tasks | Get recurring task definitions (current user) |
create_task | Create a new task |
update_task | Update task fields or status |
delete_task | Delete a task |
create_comment | Add a comment to a task |
update_project | Update project fields |
Usage
Add to Claude Code:
claude mcp add motion https://<your-deployment>/mcp --transport http --scope user
Claude will open a browser window to connect your Motion account. You'll need your Motion API key from app.usemotion.com/settings/api.
For Claude.ai, add your deployment URL as a custom connector in Settings → Connectors (requires team admin to approve first).
Self-hosting
Prerequisites
- Node.js 20+
- Fly.io account (or any hosting that supports persistent Node.js processes)
Setup
git clone <repo>
cd motion-mcp
npm install
cp .env.example .env
# Fill in .env
npm run dev
Environment Variables
| Variable | Required | Description |
|---|---|---|
JWT_SECRET | yes | Secret for signing access tokens — openssl rand -hex 32 |
ENCRYPTION_KEY | yes | AES-256 key for encrypting stored API keys — openssl rand -hex 32 |
BASE_URL | yes | Public URL of your deployment e.g. https://your-app.fly.dev |
DB_PATH | no | Path to SQLite file (default: ./motion.db) |
PORT | no | Port to listen on (default: 3000) |
Deploy to Fly.io
fly launch --no-deploy
fly volumes create motion_data --size 1 --region sjc --yes
fly scale count 1 --yes
fly secrets set \
JWT_SECRET=$(openssl rand -hex 32) \
ENCRYPTION_KEY=$(openssl rand -hex 32) \
BASE_URL=https://$(fly info --json | python3 -c "import sys,json; print(json.load(sys.stdin)['Hostname'])")
fly deploy
Add to your fly.toml under [env]:
DB_PATH = "/data/motion.db"
[[mounts]]
source = "motion_data"
destination = "/data"
Note: Keep
fly scale count 1— SQLite cannot be shared across multiple machines.
Register Claude with your instance
claude mcp add motion https://<your-app>.fly.dev/mcp --transport http --scope user
Auth flow
- User adds the MCP URL to Claude
- Claude detects OAuth support via
/.well-known/oauth-authorization-server - Browser opens to
/oauth/authorize - User pastes their Motion API key — validated live against Motion
- Key is stored AES-256-GCM encrypted in SQLite
- Claude receives a 90-day JWT stored in its config
- All requests are scoped to that user's Motion data
Tech stack
- TypeScript, Node.js
@modelcontextprotocol/sdk- Express
- better-sqlite3, jsonwebtoken
License
MIT
