Skip to content
Back to work

Personal project · 2026 — Present

Maria — personal AI assistant

Obsidian vault memory, Slack conversations, and disciplined agent loops in Cursor

  • Obsidian
  • Markdown
  • Cursor
  • Project rules
  • Slack
  • Google Calendar MCP
  • Git
  • Zod
  • TypeScript

The problem

Useful conversations disappear when a chat window closes, and coding agents are fast at producing plausible work while staying indifferent to your conventions. I wanted a personal assistant that could answer from durable memory, capture decisions and tasks without storing secrets, and stay under my control — driven by an agent workflow disciplined enough that the output does not have to be redone.

The approach

Maria is an Obsidian vault that acts as the source of truth, with Slack as the conversation interface and a Cursor Cloud runtime that reads vault context, answers questions, and writes concise captures back to Markdown. The constraints live in the repository rather than in the prompt: committed project rules encode memory policy, permissions, and safety boundaries — including explicit confirmation before external actions and never storing passwords or tokens in Git — and work is scoped into an explicit research, plan, then change loop, so the expensive thinking happens before anything is written.

The outcome

A working personal assistant I use daily: it remembers preferences and project state across sessions, routes captures into the right folders, commits vault updates to main, and integrates with Google Calendar through a self-hosted MCP server. It is also my worked example of AI-assisted engineering — agents handle the mechanical work while architectural decisions stay with me — and a full-stack side project in the boring sense: content schema, automation triggers, OAuth setup, and the discipline of keeping durable memory separate from chat.

Architecture moves

  • Obsidian vault structured by folders — inbox, profile, projects, areas, people, meetings, knowledge — with wikilinks instead of duplicate notes.
  • Slack (or a Slack relay) as the chat surface; the vault as durable memory, not a transcript dump.
  • Cursor automations triggered from Slack with scoped MCP tools for messaging and calendar.
  • Project rules committed alongside the content, so conventions travel with the repository instead of living in someone's prompt history.
  • Google Calendar MCP (`@cocal/google-calendar-mcp`) with OAuth credentials kept outside Git.
  • Memory policy: capture facts, decisions, and tasks; never passwords, API keys, or recovery codes.
  • Permissions model with explicit escalation points: read and suggest freely; ask rather than assume before sending messages, changing calendar events, or spending money.

Performance levers

  • Concise captures instead of full chat logs keep the vault searchable and small.
  • Research and audit passes kept strictly read-only, separating diagnosis from change.
  • Zod-validated content modules in other projects inspired the same boundary-validation pattern here.
  • Git commits on main for routine memory updates — no PR overhead for a personal knowledge base.

Engineering impact

  • Turned recurring 'where did I write that down?' moments into a searchable vault.
  • Gave me hands-on experience designing agent permissions, memory policy, and human-in-the-loop external actions.
  • Mechanical work gets faster without the review burden that usually comes with generated code — decisions that need a human stay with a human.
  • Demonstrates full-stack product thinking beyond UI — schema, integrations, automation, and ops.

Challenges conquered

  • Drawing the line between durable memory and chat noise — most of a conversation should not become a note.
  • Keeping secrets out of a system designed to remember things, which means strict categories and runtime enforcement.
  • Resisting plausible-looking agent output that is subtly wrong, particularly invented facts and confidently misremembered APIs.
  • First-time OAuth for Calendar in a headless cloud environment, where interactive browser auth cannot complete without a manual step.