Skip to content

Yodawgz0/MeetingAPI

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MCP Backend + Fathom Integration

Backend-only Node.js/TypeScript service that exposes Fathom meeting data through both REST APIs and a Model Context Protocol (MCP) interface. It is built with production-grade auth, logging, error handling, and test coverage so you can lift it into your own infrastructure with minimal work.

Highlights

  • API Key + OAuth 2.0 Authorization Code authentication with automatic refresh.
  • REST + MCP parity for meetings list/summary/transcript and webhook handling.
  • Webhook signature verification (HMAC-SHA256) and consistent error envelopes.
  • Optional mock data mode for offline/local development.

Table of Contents

  1. Architecture
  2. Quickstart
  3. Configuration
  4. Authentication & Webhooks
  5. REST API Reference
  6. MCP JSON-RPC Reference
  7. Testing Strategy
  8. Manual Sanity Checks
  9. Extensibility Notes

Architecture

flowchart LR
  Client[["REST / MCP Clients"]] -->|HTTP / JSON-RPC| App["Express App"]
  App --> Auth["multiAuth Middleware"]
  Auth -->|API Key| FathomClient["FathomClient"]
  Auth -->|OAuth| OAuthSvc["OAuth Service"]
  OAuthSvc --> TokenStore[/"InMemory Token Store"/]
  FathomClient -->|Live requests| FathomAPI[/"Fathom Cloud API"/]
  FathomClient -->|Fallback| MockData[/"Deterministic mock data"/]
  App --> WebhookRouter["Webhook Router"]
  WebhookRouter --> SigVerifier["FathomWebhookService HMAC check"]
  App --> MCPRouter["MCP Router (JSON-RPC)"]
Loading

Everything funnels through the same service layer, ensuring feature parity between REST and MCP. When outbound traffic to Fathom is blocked (e.g., CI, local dev), the client can automatically fall back to mock payloads.


Quickstart

Requirements

  • Node.js 20+
  • npm 10+

Install / Build / Run

npm install              # install deps
npm run build            # compile TypeScript -> dist
npm run dev              # ts-node + mock data enabled by default
npm test                 # run unit + integration suites

The server listens on PORT (default 4000).


Configuration

Create a .env file (or export the variables) before running:

Variable Description Default
PORT HTTP port 4000
SERVICE_NAME Log identifier mcp-backend
FATHOM_BASE_URL Fathom REST origin https://api.fathom.video
FATHOM_ALLOWED_API_KEYS Comma-separated API-key allow list (optional) (empty)
FATHOM_WEBHOOK_SECRET Shared secret for HMAC verification change-me
FATHOM_OAUTH_CLIENT_ID / FATHOM_OAUTH_CLIENT_SECRET OAuth client credentials demo placeholders
FATHOM_OAUTH_TOKEN_URL Token endpoint Fathom default
FATHOM_USE_MOCKS Serve deterministic mock data (great for local/offline) true when NODE_ENV!==production

Example .env:

PORT=4000
SERVICE_NAME=mcp-backend
FATHOM_WEBHOOK_SECRET=whsec_xxx
FATHOM_OAUTH_CLIENT_ID=your-client-id
FATHOM_OAUTH_CLIENT_SECRET=super-secret
FATHOM_ALLOWED_API_KEYS=demo-api-key-1,demo-api-key-2
FATHOM_USE_MOCKS=true

Authentication & Webhooks

Request flow (REST/MCP)

sequenceDiagram
  participant Client
  participant API as MCP Backend
  participant Auth as multiAuth
  participant OAuth as OAuthService
  participant Fathom as Fathom API
  participant Mock as Mock Data

  Client->>API: HTTP / JSON-RPC + headers
  API->>Auth: validate headers
  alt api-key
    Auth->>API: {mode: api-key, apiKey, userId}
  else oauth
    Auth->>OAuth: getValidAccessToken(userId)
    OAuth-->>Auth: access token (refresh if needed)
    Auth->>API: {mode: oauth, userId}
  end
  API->>Fathom: fetch meetings/summary/transcript
  alt network failure & mocks enabled
    Fathom--X API: error
    API->>Mock: serve deterministic payload
  else success
    Fathom-->>API: real payload
  end
  API-->>Client: JSON response
Loading

Webhook security

  • Fathom sends X-Fathom-Signature = HMAC_SHA256(secret, rawBody).
  • Express stores the raw body, we recompute the hash, and reject mismatches with 401.
  • Valid events are logged and handed off for further processing.

REST API Reference

Endpoint Description
GET /health/live Liveness probe.
GET /api/fathom/meetings List meetings for the authenticated user. Supports limit/cursor.
GET /api/fathom/meetings/:id/summary Summary/highlights/action items.
GET /api/fathom/meetings/:id/transcript Full transcript with pagination/limit.
POST /webhook/fathom Receives meeting webhooks (signature required).
# List meetings via API key mode (mock data when FATHOM_USE_MOCKS=true)
curl "http://localhost:4000/api/fathom/meetings?limit=1" \
  -H 'x-auth-mode: api-key' \
  -H 'x-user-id: demo-user' \
  -H 'x-fathom-api-key: <your-api-key>'

# Meeting summary (works for OAuth or API key)
curl http://localhost:4000/api/fathom/meetings/meeting-demo-1/summary \
  -H 'x-auth-mode: api-key' \
  -H 'x-user-id: demo-user' \
  -H 'x-fathom-api-key: <your-api-key>'

# Transcript with pagination
curl "http://localhost:4000/api/fathom/meetings/meeting-demo-1/transcript?limit=2" \
  -H 'x-auth-mode: api-key' \
  -H 'x-user-id: demo-user' \
  -H 'x-fathom-api-key: <your-api-key>'

# Webhook (replace signature with HMAC)
curl -X POST http://localhost:4000/webhook/fathom \
  -H 'Content-Type: application/json' \
  -H 'x-fathom-signature: <hmac>' \
  -d '{"event":"meeting.completed","meetingId":"abc123"}'

MCP JSON-RPC Reference

Send JSON-RPC payloads to POST /mcp with Content-Type: application/json.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "list_meetings",
  "params": {
    "auth": {
      "mode": "api-key",
      "userId": "user-123",
      "apiKey": "demo-api-key-1"
    },
    "limit": 10
  }
}
{
  "jsonrpc": "2.0",
  "id": "hook-1",
  "method": "handle_webhook_event",
  "params": {
    "signature": "<hmac>",
    "event": {
      "event": "meeting.completed",
      "meetingId": "abc123"
    }
  }
}

Error responses follow JSON-RPC conventions (code, message, optional data).


Testing Strategy

Type Suite What it validates
Unit src/modules/auth/__tests__/oauthService.test.ts OAuth code exchange, refresh, and error handling logic.
Unit src/modules/fathom/__tests__/webhookService.test.ts Pure HMAC verification logic.
Unit src/middleware/__tests__/multiAuth.test.ts Header validation, allow-list enforcement, request context injection.
Integration (HTTP) src/modules/fathom/__tests__/fathomRouter.test.ts REST controllers wired through createApp, covering API key & OAuth paths plus pagination/validation failures.
Integration (HTTP) src/modules/fathom/__tests__/fathomMock.e2e.test.ts Full end-to-end flows mirroring the curl commands (meetings list + summary + transcript) while mock mode is enabled.
Integration (HTTP) src/modules/fathom/__tests__/webhookController.test.ts Webhook router enforcing raw-body capture, signature verification, and success path.
Integration (JSON-RPC) src/mcp/__tests__/mcpRouter.test.ts MCP interface happy paths plus error cases (unknown methods, missing auth, invalid JSON-RPC version).

Run everything with npm test (27 specs across 7 suites).


Manual Sanity Checks

With the dev server running (mock mode on):

curl http://localhost:4000/health/live
curl "http://localhost:4000/api/fathom/meetings?limit=1" -H 'x-auth-mode: api-key' -H 'x-user-id: demo-user' -H 'x-fathom-api-key: <key>'
curl http://localhost:4000/api/fathom/meetings/meeting-demo-1/summary -H 'x-auth-mode: api-key' -H 'x-user-id: demo-user' -H 'x-fathom-api-key: <key>'
curl "http://localhost:4000/api/fathom/meetings/meeting-demo-1/transcript?limit=2" -H 'x-auth-mode: api-key' -H 'x-user-id: demo-user' -H 'x-fathom-api-key: <key>'

The outputs should match the deterministic mock payloads (handy for demos/automated smoke tests).


Extensibility Notes

  • Token Persistence: swap InMemoryOAuthTokenStore with Redis/Dynamo/etc. for multi-instance deployments.
  • Mock-to-live switch: set FATHOM_USE_MOCKS=false in staging/production to hit real Fathom APIs.
  • Webhook fan-out: plug FathomWebhookService.handleEvent into queues or workflows as needed.
  • Multi-tenancy: the authentication context travels with each request (req.authContext), making it straightforward to plug in tenant routing or per-user storage.
  • Observability: structured Pino logs already redact sensitive headers; pipe them into your log stack for alerting/metrics.

Enjoy shipping Fathom data safely across REST, MCP, and webhooks 🚀

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors