Skip to content
 
 

Repository files navigation

Vitally MCP

Streamable HTTP MCP server for Vitally.io, deployed on Vercel and gated by Clerk OAuth (Google sign-in restricted to allowed domains). Built on Next.js 16 with mcp-handler.

Endpoints

Path Purpose
/mcp MCP Streamable HTTP transport
/.well-known/oauth-protected-resource/mcp OAuth Protected Resource Metadata (RFC 9728)
/ One-screen landing page for humans

Architecture

  • app/mcp/route.tsmcp-handler route wrapped in Clerk's withMcpAuth. Hosts every Vitally tool. Streamable HTTP only — SSE is disabled.
  • app/.well-known/oauth-protected-resource/mcp/route.ts — publishes the Clerk-backed protected resource metadata.
  • proxy.ts — Clerk middleware (Next.js 16 renamed middleware.tsproxy.ts).
  • lib/vitally/ — TypeScript port of the Vitally REST client. Reads env vars at first instantiation and throws if any are missing.

Configure

Set these env vars locally in .env.local and in Vercel project settings:

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
VITALLY_API_SUBDOMAIN=...
VITALLY_API_KEY=...
VITALLY_DATA_CENTER=US

The Vitally vars are required — the server fails loudly at cold start if any are missing. There is no demo or mock mode.

Clerk dashboard setup (one-time)

  1. Create a new Clerk application.
  2. Enable Sign in with Google as the only auth method.
  3. Restrict sign-ups via allowlist or domain restriction (e.g. @mailmojo.no).
  4. In the application's API settings, enable Dynamic Client Registration under the OAuth/MCP section so Claude clients can register on first connect.
  5. Copy the publishable and secret keys into your env vars.

Run locally

npm install
npm run dev
# In another terminal:
npx @modelcontextprotocol/inspector

Connect Inspector to http://localhost:3000/mcp. You'll see a 401 → Clerk OAuth flow → tool list.

Deploy to Vercel

  1. Push this branch and connect the repo as a new Vercel project.
  2. Enable Fluid compute (Functions → Fluid) — required for the longer maxDuration we use on the MCP route.
  3. Set framework preset to Next.js (auto-detected).
  4. Add the env vars above to Production + Preview.
  5. Deploy. Endpoints will be:
    • https://<project>.vercel.app/mcp
    • https://<project>.vercel.app/.well-known/oauth-protected-resource/mcp

Optionally bind a custom domain (e.g. vitally-mcp.mailmojo.no).

Add to Claude

In Claude Desktop or Claude Web: Settings → Custom Connectors → Add a connector and paste the /mcp URL. The first connect pops a Clerk login.

Available tools

  • Discovery: search_tools
  • Accounts: search_accounts, get_account_details, get_account_users, refresh_accounts, get_account_health
  • Traits: list_custom_traits, update_account_traits
  • Users: search_users, get_user_details
  • Conversations / Tasks / Notes: get_account_conversations, get_account_tasks, get_account_notes, get_note_by_id, create_account_note
  • NPS: get_account_nps
  • Projects: get_account_projects
  • Custom objects: list_custom_objects, get_custom_object, list_custom_object_instances, search_custom_object_instances

See app/mcp/route.ts for input schemas.

Vitally Elements (custom properties defined in Vitally) appear as keys prefixed with vitally.custom. inside an account's or user's traits object. List endpoints accept includeTraits / traitKeys to opt into returning these without bloating the default payload.

Attribution

Originally created by John Jung, containerised by Dan Searle, ported to streamable HTTP + Clerk OAuth by the mailmojo.no fork.

Releases

Packages

Used by

Contributors

Languages