# Motion Mcp

> MCP server for Motion calendar — full calendar event access, availability checking, and task management with natural-language. What Motion's public API should have been!

- **Type:** MCP server
- **Install:** `agentstack add mcp-fidgetcoding-motion-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [fidgetcoding](https://agentstack.voostack.com/s/fidgetcoding)
- **Installs:** 0
- **Category:** [Productivity](https://agentstack.voostack.com/c/productivity)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [fidgetcoding](https://github.com/fidgetcoding)
- **Source:** https://github.com/fidgetcoding/motion-mcp

## Install

```sh
agentstack add mcp-fidgetcoding-motion-mcp
```

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

## About

# Motion MCP

**Full calendar access for Claude Code — events, availability, scheduling.**

**What Motion's public API should have been, but they chose not to (for some reason, so I fixed it).**

[](https://www.npmjs.com/package/fidgetcoding-motion-mcp)
[](https://opensource.org/licenses/MIT)
[](https://nodejs.org)
[](https://modelcontextprotocol.io)

[](https://x.com/fidgetcoding) [](https://www.linkedin.com/in/nate-davidovich/) [](https://youtube.com/@fidgetcoding) [](https://instagram.com/fidgetcoding)

---

## Quick Navigation

| Link | Section | What it does | Time |
|---|---|---|---|
| [Natural Language Examples](#natural-language-examples) | Talk to it | Copy-paste prompts for events, availability, teammates, all-day | ~1 min |
| [Why This Exists](#why-this-exists) | Why | The Motion public API gap and why this shim exists | ~2 min |
| [How This Compares](#how-this-compares) | Comparison | vs Motion web/app, raw public API, no-MCP baseline | ~1 min |
| [Install](#install) | Setup | One-liner to wire the MCP into Claude | ~1 min |
| [Tools](#tools) | Reference | All 12 MCP tools — calendar + tasks | ~2 min |
| [Usage Examples](#usage-examples) | Reference | Worked flows (today, availability, recurring, move) | ~2 min |
| [Configuration](#configuration) | Setup | Env vars, default calendar, timezone | ~3 min |
| [Troubleshooting](#troubleshooting) | Reference | Auth failures, token expiry, sync delays | ~2 min |
| [Security](#security) | Reference | Secret handling + disclosure | ~1 min |
| [Project Status](#project-status) | Meta | Low-maintenance mode + where to go instead | ~1 min |
| [License](#license) | Meta | MIT | — |
| [Author](#author) | Meta | Who built it | — |

---

## Natural Language Examples

> [!IMPORTANT]
> **You talk. Claude dispatches. No commands, no syntax, no JSON.**
>
> Once this MCP is installed, you drive your Motion calendar through Claude in plain English. Claude picks the tool, fills in the parameters, and hands the result back in conversation.

```
"What's on my calendar today?"
```

```
"Am I free Thursday afternoon? Find me any 45-minute gaps between 1pm and 5pm."
```

```
"Create a 30-minute meeting called 'Team Sync' tomorrow at 2pm with teammate@example.com."
```

```
"Move my 3pm call to 4pm, same day."
```

```
"Cancel the standup on Friday."
```

```
"Search my calendar for anything about onboarding this month."
```

```
"Is Sarah busy Wednesday morning? Pull her events between 9am and noon."
```

```
"List all my teammates so I know whose availability I can check."
```

```
"Show me every all-day event this week — out of office, holidays, deadlines."
```

```
"Force a sync with Google Calendar, I just added something over there and want it to show up here."
```

Every one of the above becomes a tool call under the hood. You never have to know which tool. You never have to build a payload. You just say the sentence.

↑ back to top

---

## Why This Exists

> I was a paying Motion user for a long time. Then I tried to connect Motion to Claude via MCP and realized I'm paying ~$228/year for a calendar that doesn't really have smart tools — at least not ones I can hand to an agent. So I built this.

Motion bills itself as an AI-first calendar. The marketing promises scheduling intelligence, automatic rescheduling, teammate coordination. And inside the Motion web app, most of that is actually there. The problem is the public API.

Motion's public API has a respectable surface for **tasks and projects** — 27 endpoints covering create, list, update, workspaces, custom fields, statuses, recurring tasks. If all you want is "make Claude add a Motion task," you can wire that up in an afternoon against the docs. Several other Motion MCPs already exist for exactly that. The built-in Motion MCP does it. `@rf-d/motion-mcp` does it. `h3ro-dev/motion-mcp-server` does it.

None of them can touch calendar events. Neither can Motion's own public API.

For a product where the calendar *is* the product, that's a remarkable gap. You can create a task. You can set its priority. You can update its status. You cannot read, create, update, or delete a single event on the calendar that task is supposed to land on. You also can't check availability, list teammates, query free/busy, search events, pull all-day items, or manage which calendars are connected. Every surface that an agent would actually need to run your day is locked behind the internal API.

There's also no official Motion MCP server from Motion themselves. If there were one and it exposed the calendar endpoints cleanly, I wouldn't have written this. I waited, checked regularly, and eventually accepted that it wasn't coming.

So this MCP fills the gap by doing what the Motion web app does: it authenticates through Firebase (the same auth flow the Motion frontend uses) and talks to `internal.usemotion.com`. That gives Claude the full calendar surface — event CRUD, availability, search, teammate events, all-day events, sync triggers, calendar management. There's a bit of extra setup because you have to pull a Firebase refresh token out of your browser's IndexedDB, but once it's wired up, it just works.

Motion is a good product. The auto-scheduler is thoughtful, the UI is polished, their team clearly cares. You can sign up at [usemotion.com](https://www.usemotion.com/). But paying ~$228/year for a calendar that can't be driven by an agent is a hard sell for me personally, and the absence of an official MCP was the thing that eventually pushed me off the platform. If Motion ships a first-party MCP that covers this surface, I'll be genuinely happy — and honestly, this repo can probably retire the day they do.

Until then, this is here.

↑ back to top

---

## How This Compares

| Capability | 🟢 **Motion MCP (this repo)** | Motion web/app | Raw Motion public API | No integration |
|---|---|---|---|---|
| Full event CRUD from Claude | 🟢 **✅ Yes** | Manual (GUI) | ❌ No | ❌ No |
| Availability / free-busy checks | 🟢 **✅ Yes** | ✅ Visual only | ❌ No | ❌ No |
| Teammate event visibility | 🟢 **✅ Yes** | ✅ Yes | ❌ No | ❌ No |
| Recurring events (read) | 🟢 **✅ Yes** (instances via `list_events`) | ✅ Yes | ❌ No | ❌ No |
| All-day event queries | 🟢 **✅ Yes** | ✅ Yes | ❌ No | ❌ No |
| Search events by text | 🟢 **✅ Yes** | ✅ Yes | ❌ No | ❌ No |
| Calendar management (enable/disable) | 🟢 **✅ Yes** | ✅ Yes | ❌ No | ❌ No |
| List connected calendars | 🟢 **✅ Yes** | ✅ Yes | ❌ No | ❌ No |
| Sync trigger (Google/Outlook) | 🟢 **✅ Yes** | ✅ Yes | ❌ No | ❌ No |
| Task read (public API) | 🟢 **✅ Yes** | ✅ Yes | ✅ Yes | ❌ No |
| Auto-scheduling integration | 🟢 **✅ Works** (events you create respect Motion's engine) | ✅ Yes | Partial (tasks only) | ❌ No |
| One-command install | 🟢 **✅ Yes** (`claude mcp add motion -- npx -y fidgetcoding-motion-mcp`) | N/A | N/A | N/A |
| Works with raw Motion subscription | 🟢 **✅ Yes** (standard Motion plan, no extra tier required) | ✅ Yes | ✅ Yes | N/A |
| Open source / MIT | 🟢 **✅ Yes** | ❌ Proprietary | N/A | N/A |

The tradeoff is honest: this MCP requires a few extra setup steps because it authenticates the way Motion's own web app does (Firebase refresh token + user ID pulled from your browser's IndexedDB). In exchange, you get the calendar surface that every other integration is locked out of.

↑ back to top

---

## Install

One command:

```bash
claude mcp add motion -- npx -y fidgetcoding-motion-mcp
```

Then configure credentials (see [Configuration](#configuration)) and restart Claude Code.

If you'd rather set everything up inline in your Claude MCP config, skip ahead to [Configuration](#configuration) for the JSON shape.

↑ back to top

---

## Tools

### Calendar tools (internal API)

| Name | What it does | Key params |
|---|---|---|
| `list_calendars` | List every calendar connected to your Motion account — names, IDs, source emails, enabled status. | *(none)* |
| `list_events` | Fetch events inside a date range with full details (title, time, attendees, location, conference link). | `start_date`, `end_date`, `calendar_id?` |
| `search_events` | Search events by text query across titles and descriptions. | `query` |
| `create_event` | Create an event with title, time, description, location, attendees. Defaults to your primary calendar if no ID is passed. Organizer and timezone are filled in automatically. | `title`, `start`, `end`, `calendar_id?`, `description?`, `location?`, `attendees?`, `is_all_day?`, `status?`, `visibility?`, `conference_type?` |
| `update_event` | Modify an existing event — title, time, description, location. | `event_id`, `title?`, `start?`, `end?`, `description?`, `location?` |
| `delete_event` | Remove an event by ID. | `event_id` |
| `check_availability` | Find open time slots across all calendars. Scans working hours (9am–6pm, weekdays) and returns gaps of at least a given duration. | `start_date`, `end_date`, `duration_minutes?` |
| `get_teammate_events` | Pull a teammate's events for a date range given their user ID. Useful for "is Sarah free Wednesday morning?" | `teammate_user_ids`, `start_date`, `end_date` |
| `get_allday_events` | List all-day events separately (OOO, holidays, deadlines) with optional calendar filtering. | `start_date`, `end_date`, `calendar_id?` |
| `sync_calendars` | Force a sync between Motion and your connected providers (Google, Outlook). Useful when events were added externally. | *(none)* |
| `manage_calendars` | Enable or disable specific calendars inside your Motion account. | `calendar_id`, `enabled` |

### Task tools (public API)

| Name | What it does | Key params |
|---|---|---|
| `get_tasks` | List tasks with optional status filtering (`TODO`, `IN_PROGRESS`, `COMPLETED`). | `status?` |

> **Why only one task tool?** The full Motion task surface (create, update, projects, recurring, custom fields) is already well-served by the built-in Motion MCP and several community MCPs. This repo intentionally focuses on the calendar gap those other MCPs can't fill. `get_tasks` is included so you don't need a second MCP just to read task status alongside your calendar.

↑ back to top

---

## Usage Examples

Worked examples — what you say, what Claude does, what comes back.

### Example 1 — "What's on my calendar today?"

**You:** *"What's on my calendar today?"*

**Claude calls:** `list_events` with `start` = today 00:00 and `end` = today 23:59 in your configured timezone.

**Result:** Claude summarizes the day in conversation: meeting titles, times, attendees, and any conference links. No spreadsheet. No JSON dump. Just the rundown.

---

### Example 2 — "Am I free Thursday afternoon for a 45-minute block?"

**You:** *"Am I free Thursday afternoon? I need a 45-minute block between 1pm and 5pm."*

**Claude calls:** `check_availability` with `start` = Thursday 13:00, `end` = Thursday 17:00, `duration_minutes` = 45.

**Result:** Claude returns the open gaps that meet the duration requirement — e.g., *"You're free 1:30–3:15 PM and 4:15–5:00 PM. Two slots fit 45 minutes."* If nothing fits, it says so directly.

---

### Example 3 — "Create a 1:1 with an invite."

**You:** *"Create a 30-minute 1:1 with teammate@example.com next Tuesday at 2pm, called 'Weekly 1:1'."*

**Claude calls:** `create_event` with title, start/end in your timezone, and `attendees: ["teammate@example.com"]`.

**Result:** Event is created on your primary calendar, invite fires, Motion's auto-scheduler respects the fixed time. Claude confirms the event ID. (Recurring-event *creation* isn't exposed by this MCP — set recurrence in the Motion app; existing recurring events show up normally in `list_events`.)

---

### Example 4 — "Move my 3pm to 4pm."

**You:** *"Move my 3pm meeting today to 4pm."*

**Claude calls:** `list_events` to find the 3pm event, then `update_event` with the new `start` and `end`.

**Result:** Event is moved, attendees are re-notified by Motion, Claude confirms with the new time. If there's more than one 3pm event, Claude asks which one before moving anything.

↑ back to top

---

## Configuration

This MCP needs four credentials. The Motion API key is straightforward. The other three require extracting values from your browser — this is the price of reaching Motion's calendar endpoints, which are only exposed through their internal auth flow.

### Environment variables

| Variable | Required | Description |
|---|---|---|
| `MOTION_API_KEY` | Yes | Your Motion API key from **Settings → API** in the Motion web app. |
| `FIREBASE_API_KEY` | Yes | Firebase API key extracted from your browser (starts with `AIza`). See Step 2 below. |
| `FIREBASE_REFRESH_TOKEN` | Yes | Firebase refresh token from IndexedDB. See Step 2 below. |
| `MOTION_USER_ID` | Yes | Your Motion user ID. See Step 3 below. |
| `MOTION_TIMEZONE` | No | IANA timezone (default: `America/New_York`). Used for event headers and new-event defaults. Set this to match **your** locale — the default is just a default. |

### Step 1 — Get your Motion API key

1. Open [app.usemotion.com](https://app.usemotion.com).
2. Go to **Settings → API**.
3. Generate or copy your API key.

### Step 2 — Get your Firebase credentials

The internal API authenticates through Firebase. You need two values: a Firebase API key and a refresh token.

1. Open [app.usemotion.com](https://app.usemotion.com) in Chrome (or any Chromium browser with DevTools).
2. Open DevTools (`Cmd+Option+I` on Mac, `Ctrl+Shift+I` on Windows/Linux).
3. Go to **Application → IndexedDB → `firebaseLocalStorageDb` → `firebaseLocalStorage`**.
4. Click the entry in the table. A JSON object shows below.
5. Find `value → stsTokenManager → refreshToken` — copy the entire string. This is your `FIREBASE_REFRESH_TOKEN`.
6. For `FIREBASE_API_KEY`: open the **Network** tab, find any request to `googleapis.com`, and copy the value of the `key=` query parameter (it starts with `AIza`).

### Step 3 — Get your Motion User ID

Your user ID is visible in the same IndexedDB entry from Step 2 — look for the `uid` field. It's a string of letters and numbers (e.g., `abc123def456...`).

Alternatively, inspect any `internal.usemotion.com` request in the Network tab — the `userId` field appears in many of them.

### Step 4 — Set your default calendar (optional but recommended)

`create_event` defaults to your primary Motion calendar when no `calendar_id` is passed. "Primary" is whatever Motion has flagged as your default account — it's not hard-coded to a specific email. If you have multiple connected calendars and want Claude to route new events to a specific one, call `list_calendars` once to get the ID and pass it explicitly to `create_event`, or have Claude remember it for the session.

### Step 5 — Wire it into Claude

Either drop the credentials into a `.env` file at the project root:

```bash
MOTION_API_KEY=your_motion_api_key_here
FIREBASE_API_KEY=your_firebase_api_key_here
FIREBASE_REFRESH_TOKEN=your_firebase_refresh_token_here
MOTION_USER_ID=your_motion_user_id_here
MOTION_TIMEZONE=America/New_York
```

…or pass them via your Claude MCP config:

```json
{
  "mcpServers": {
    "motion": {
      "command": "npx",
      "args": ["-y", "fidgetcoding-motion-mcp"],
      "env": {
        "MOTION_API_KEY": "your_motion_api_key_here",
        "FIREBASE_API_KEY": "your_firebase_api_key_here",
        "FIREBASE_REFRESH_TOKEN": "your_firebase_refresh_token_here",
        "MOTION_USER_ID": "your_motion_user_id_here",
        "MOTION_TIMEZONE": "America/New_York"
      }
    }
  }
}
```

Restart Claude Code after either option.

↑ back to top

---

## Troubleshooting

**"Authentication failed" or "Invalid refresh token".**
Firebase refresh tokens last roughly 6 months before they need re-issuing. Re-extract the refresh token from your browser using Step 2 above. The Firebase API key itself doesn't expire.

**"User ID not found" or calendar calls return empty.**
Your `MOTION_USER_ID` is likely stale or mistyped. Re-pull it from the same IndexedDB entry as the refr

…

## Source & license

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

- **Author:** [fidgetcoding](https://github.com/fidgetcoding)
- **Source:** [fidgetcoding/motion-mcp](https://github.com/fidgetcoding/motion-mcp)
- **License:** MIT

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:** yes
- **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/mcp-fidgetcoding-motion-mcp
- Seller: https://agentstack.voostack.com/s/fidgetcoding
- 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%.
