Skip to content
AG
← All Projects

Sathi — Personal Assistant MCP Server

Sathi — Personal Assistant MCP Server

Overview

A remote MCP server that turns Claude into a personal assistant — tracks habits, tasks, finances, goals, documents, and memory with semantic search. Built on OAuth 2.0 + PKCE, deployed serverless on Vercel with 41 MCP tools across 6 domains.

Tech Stack

Next.js 16React 19TypeScriptSupabasePostgreSQLpgvectorMCP SDKZodOpenAI EmbeddingsTailwind CSSVercel

Key Features

41 MCP tools across Habits, Tasks, Finance, Goals, Documents, and Memory

OAuth 2.0 with PKCE (S256) for secure remote MCP client authentication

Hybrid semantic + full-text search on memories using pgvector and GIN indexes

Duplicate memory detection at 0.9 cosine similarity threshold

Document wallet with chunked embeddings (OpenAI text-embedding-ada-002, 1536 dims)

Habit streak tracking and completion analytics with IST-aware date handling

Spending categorization with uncategorized-transaction surfacing

Goal tracking with milestone sub-steps and progress reviews

Stateless serverless architecture — new MCP instance per request

SHA-256 hashed OAuth tokens, service-role Supabase access server-side

Dashboard UI for all 6 domains alongside MCP access

Challenges & Solutions

Stateless MCP server on Vercel serverless

MCP protocol typically assumes persistent connections, but Vercel functions can't hold state between requests. Built a fresh MCP server instance on every POST /api/mcp call — no module-level state, no singletons — so it scales horizontally with zero warm-up coupling.

OAuth 2.0 + PKCE for remote MCP clients

Claude.ai and other MCP clients require OAuth for remote servers — no API key auth. Implemented full /oauth/authorize, /token, /register, /revoke flow with PKCE S256, and SHA-256 hashed tokens in Supabase so raw tokens never hit the DB.

Recall quality on memory search

Pure vector search missed exact keyword hits like names, dates, and IDs. Built a pa_hybrid_search RPC combining pgvector cosine similarity with Postgres full-text search over a GIN-indexed search_vector column, giving the best of both worlds.

Sharing a Supabase project with memory-mcp without collisions

Sathi coexists with an earlier memory-mcp server on the same Supabase instance. Namespaced every Sathi table with a pa_ prefix (pa_memory_items, pa_memory_spaces, pa_memory_access_log) to keep schemas isolated and migrations conflict-free.

Timezone correctness for an India-based user

Streaks and daily filters kept going off-by-one because server default was UTC. Standardized everything on Asia/Kolkata via IST helpers in types/index.ts — all display, filtering, and habit-completion logic now uses IST consistently.

Architecture

Next.js 16 + Supabase (pgvector) + MCP SDK + OAuth 2.0 PKCE, deployed on Vercel serverless

Next Project

AI Chatbot Widget