Content
# griply-mcp
[](https://codecov.io/github/vinayh/griply-mcp)
An [MCP](https://modelcontextprotocol.io) server for [Griply](https://griply.app) that provides AI assistants with direct access to your goals, tasks, and habits via the Firebase/Firestore API.
> **Disclaimer:** This is an unofficial, personal project. It is not endorsed, approved, or affiliated with Griply in any way. Use at your own risk.
## Setup
```bash
bun install
```
### Firebase Config
Create `src/firebase/config.ts` with your Griply Firebase project config (this file is gitignored):
```typescript
export const firebaseConfig = {
apiKey: "...",
authDomain: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "...",
};
```
You can extract these values from the Griply web app's JavaScript bundle.
### Auth Secrets
Store your Griply auth credentials with Bun's Secrets API:
```bash
bun -e 'await Bun.secrets.set({ service: "griply-mcp", name: "GRIPLY_EMAIL", value: "your-email@example.com" })'
bun -e 'await Bun.secrets.set({ service: "griply-mcp", name: "GRIPLY_PASSWORD", value: "your-password" })'
```
Bun stores these in your OS credential store: Keychain on macOS, libsecret on Linux, and Credential Manager on Windows.
If Bun secrets are not set, the server falls back to environment variables. Create a `.env` file if you prefer that path or need it for CI/deployment:
```
GRIPLY_EMAIL=your-email@example.com
GRIPLY_PASSWORD=your-password
GRIPLY_TIMEZONE=Europe/London # optional, IANA tz name; defaults to America/New_York
```
`GRIPLY_TIMEZONE` is used to encode deadlines (Griply anchors them at midnight in the user's local timezone) and to format the `startDate`/`deadline` output as calendar dates the user picked. Set it to whatever timezone your Griply client uses.
## Usage with Claude Code
Add to `~/.claude/settings.json`:
```json
{
"mcpServers": {
"griply": {
"command": "bun",
"args": ["/path/to/griply-mcp/src/index.ts"]
}
}
}
```
If you use `.env` fallback instead of Bun secrets, keep exporting the `GRIPLY_` variables before launching the server.
## Tools
### Goals
| Tool | Description |
|------|-------------|
| `list_goals` | List goals, optionally filtered by life area |
| `get_goal` | Get a goal with its linked tasks |
| `create_goal` | Create a new goal |
| `complete_goal` | Mark a goal as completed |
| `get_goal_progress` | Calculate goal progress based on task completion |
### Tasks
| Tool | Description |
|------|-------------|
| `list_tasks` | List tasks with a filter (`today`, `upcoming`, `inbox`, `all`, `completed`) |
| `create_task` | Create a new task with optional priority, deadline, time slot, and goal link |
| `update_task` | Update an existing task's name, priority, dates, or time slot |
| `complete_task` | Mark a task as completed |
| `delete_task` | Hard-delete a task. The Griply mobile app soft-deletes via a Cloud Function we can't reach from the client SDK; reads filter out mobile-app soft-deletes (`deletedAt`) so the result is symmetric. |
### Habits
| Tool | Description |
|------|-------------|
| `list_habits` | List active habits with schedule metadata and today's completion status |
| `add_habit_occurrence` | Log a habit completion for a given date |
### Summary
| Tool | Description |
|------|-------------|
| `get_today_summary` | Get today's tasks, habits, and completion counts |
## Development
```bash
bun dev # run with --watch
bun test # run tests (requires .env + config)
```
Run `src/index.ts` directly with `bun` — there is no bundle step. `bun build` against this codebase produces a non-functional artifact because the bundler swaps Firestore's gRPC transport for the browser-side gRPC-Web one, which can't open Firestore's listen stream from Node and silently falls back to offline mode.
## Architecture
The server connects directly to Griply's Firestore database using the Firebase JS SDK, bypassing the web UI entirely. Authentication is handled via `signInWithEmailAndPassword`.