An MCP server for Griply 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.
bun installCreate src/firebase/config.ts with your Griply Firebase project config (this file is gitignored):
export const firebaseConfig = {
apiKey: "...",
authDomain: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "...",
};You can extract these values from the Griply web app's JavaScript bundle.
Store your Griply auth credentials with Bun's Secrets API:
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.
Add to ~/.claude/settings.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.
| 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 |
| 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. |
| 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 |
| Tool | Description |
|---|---|
get_today_summary |
Get today's tasks, habits, and completion counts |
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.
The server connects directly to Griply's Firestore database using the Firebase JS SDK, bypassing the web UI entirely. Authentication is handled via signInWithEmailAndPassword.