Skip to content

feat(mcp): MCP server for connecting external AI agents#31

Open
Pycomet wants to merge 1 commit into
harden/ai-cron-chatfrom
feat/mcp-server
Open

feat(mcp): MCP server for connecting external AI agents#31
Pycomet wants to merge 1 commit into
harden/ai-cron-chatfrom
feat/mcp-server

Conversation

@Pycomet

@Pycomet Pycomet commented Jul 20, 2026

Copy link
Copy Markdown
Owner

What & why

Lets users connect their own AI agent (Claude Code, Cursor, custom agents) to their GrindProof account over the Model Context Protocol — turning GrindProof into an accountability backend any agent can plug into. v1 uses a personal access token (OAuth is an explicit, layerable v2).

Stacked on harden/ai-cron-chat — merge that first. Base is set accordingly.

Highlights

  • Personal access tokens — SHA-256 hashed at rest, shown once, revocable, optional expiry. New mcp_tokens table + RLS + a lightweight fixed-window rate-limit RPC (no external infra).
  • RLS preserved for external calls — resolve token → userId, then mint a short-lived HS256 JWT (SUPABASE_JWT_SECRET) so auth.uid() scoping still applies. Defense-in-depth even if a tool forgets a user_id filter.
  • Single credential→identity boundary (resolveCredential) so OAuth later touches only that function, not the transport or tools.
  • Shared, transport-neutral tool registry (specs.ts + AI-SDK / MCP adapters). The in-app coach keeps its 10 tools; MCP exposes 16 (adds goal write + check-in logging). The sanitizeForPrompt output hardening now protects both surfaces.
  • Actions extracted to src/lib/actions/{goals,daily-checks}.ts and reused by the tRPC routers (behavior-preserving; accountability side effects — carry-over RPC, score recompute, pattern engine — kept).
  • Endpoint /api/mcp/mcp (the [trpc] route collision forces the nested segment); custom auth wrapper gives proper 401 vs 429.
  • "Connect an agent" settings UI — generate (shown once + copy + client-config snippet), list, revoke.

Verification

  • tsc clean · 283 tests pass (34 new, incl. the prompt-injection hardening test) · production build green (/api/mcp/[transport] compiles, settings page prerenders).
  • Supabase checked: project reachable; mcp_tokens not yet applied (migration pending).

Required before it works live

  1. Set the real SUPABASE_JWT_SECRET (Supabase → Settings → API → JWT Secret) in .env.local and Vercel (all envs).
  2. Apply the migration (supabase db push).
  3. Live end-to-end: connect Claude Code / MCP Inspector to /api/mcp/mcp; verify cross-user isolation (RLS) and revoke → immediate 401.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ksr7x9xqCDazE3RqjCmcEX

Lets users connect their own AI agent (Claude Code, Cursor, custom
agents) to their GrindProof account over the Model Context Protocol.

- Personal access tokens: SHA-256 hashed at rest, shown once, revocable,
  optional expiry (mcp_tokens table + RLS + fixed-window rate-limit RPC)
- RLS preserved for external calls by minting a short-lived HS256 JWT
  (SUPABASE_JWT_SECRET) so auth.uid() scoping still applies
- resolveCredential is the single credential->identity boundary, so OAuth
  can be layered on later without touching transport or tools
- Shared transport-neutral tool registry (specs.ts + AI-SDK/MCP adapters):
  coach keeps its 10 tools; MCP exposes 16 (adds goal write + check-in
  logging). sanitizeForPrompt output hardening preserved for both surfaces
- Goal/daily-check write logic extracted into src/lib/actions and reused
  by the tRPC routers (behavior-preserving; accountability side effects kept)
- Remote Streamable-HTTP endpoint at /api/mcp/mcp (custom auth wrapper for
  proper 401 vs 429) + "Connect an agent" settings UI (generate/list/revoke)

Migration is not yet applied to Supabase (needs `supabase db push`).
SUPABASE_JWT_SECRET must be set in .env.local and Vercel.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ksr7x9xqCDazE3RqjCmcEX
@vercel

vercel Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Deployment failed with the following error:

Hobby accounts are limited to daily cron jobs. This cron expression (0 * * * *) would run more than once per day. Upgrade to the Pro plan to unlock all Cron Jobs features on Vercel.

Learn More: https://vercel.link/3Fpeeb1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant