Relay

io.github.vishnumuthyaluPublished by GitHub account vishnumuthyaluv1.0.1Updated Oct 24, 2026

Turn GitHub pushes into plain-English client update emails. Map repos to clients and review digests.

Overview

AI-generated overview

Relay turns GitHub pushes into plain-English client update emails, letting an assistant map repos to clients and review digests via a hosted MCP endpoint.

What you can do
  • Map repositories to clients and manage those mappings, including creating, updating and removing them
  • Review digest history and this month's usage against the plan cap
  • Send a sample digest to a confirmed client
  • Work with per-installation operations shared with the JSON API, after signing in with GitHub
When to use it
For freelancers and agencies who want clients to receive short, jargon-free summaries of pushes to their repositories, and who prefer to set up and check those client mappings by chatting with an assistant instead of using the dashboard.
Requirements
Remote MCP endpoint at relay-vishnu.fly.dev/mcp, with OAuth 2.1 sign-in through GitHub. The Relay GitHub App must be installed on the repositories, and each client must confirm by email before digests are sent. Self-hosting needs Node.js 22.12+, Docker with Postgres, a GitHub App, an Anthropic API key and a Resend API key.
Before you install
The server sends real email to clients and writes mapping data: creating a mapping triggers a confirmation email, and deleting one stops digests. Digests are written by Claude from commit text, and optional richer summaries can pull merged PR descriptions and ticket-tracker details. Self-hosting requires secrets such as SESSION_SECRET, GITHUB_CLIENT_SECRET, GITHUB_WEBHOOK_SECRET, ANTHROPIC_API_KEY, RESEND_API_KEY and optionally GITHUB_APP_PRIVATE_KEY and INTEGRATIONS_KEY.

Installation

In SourceWeft

  1. Open Relay in the dashboard and add it to a workspace.
  2. Connect the required credentials. They are stored privately and never shown on public pages.
  3. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.vishnumuthyalu%2Frelay/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config. The client completes OAuth sign-in on first connect.

{
  "mcpServers": {
    "relay": {
      "type": "http",
      "url": "https://relay-vishnu.fly.dev/mcp"
    }
  }
}

README

Relay

Plain-English client updates from every GitHub push

[CI] [Node.js Version]

Live at relay-vishnu.fly.dev. Install the GitHub App, then add https://relay-vishnu.fly.dev/mcp to your MCP client, find Relay in the MCP Registry, or install the extension from the VS Code Marketplace or Open VSX.

Relay is a GitHub App for freelancers and agencies. Install it on your repositories, map each one to a client, and every push to the main branch becomes a short, jargon-free email summary written by Claude. Clients confirm by email before anything is sent, and every digest has a one-click unsubscribe.

How it works

mermaid
sequenceDiagram    participant Dev    participant GitHub    participant Web as Relay web    participant Queue as Postgres (pg-boss)    participant Worker as Relay worker    participant Claude    participant Resend    participant Client
    Dev->>GitHub: git push    GitHub->>Web: POST /webhook/github (HMAC-signed, installation id)    Web->>Web: verify signature, claim X-GitHub-Delivery    alt duplicate, filtered, or client not confirmed        Web-->>GitHub: 200 duplicate / filtered    else new push for an active mapping        Web->>Queue: enqueue process-push        Web-->>GitHub: 202 accepted        Queue->>Worker: job        Worker->>Claude: summarize commits (structured output), unless over the monthly cap        Claude-->>Worker: validated summary        Worker->>Resend: digest email + List-Unsubscribe        Resend-->>Client: digest    end
  • GitHub App: one install connects any number of repositories, and no personal access tokens are needed (ADR 002).
  • Multi-tenant: every row belongs to an installation, users are authorized by the installations GitHub says they can access, and uninstalling deletes that tenant's data.
  • Postgres + pg-boss: the webhook replies 202 immediately, and a separate worker sends digests with retries and backoff (ADR 003).
  • Consent built in: double opt-in confirmation, signed one-click unsubscribe (RFC 8058), and confirm/unsubscribe pages that only change state on POST.
  • Cost controls: per-installation monthly cap on Claude-written digests (plain digests past it), token usage tracking, and a CLAUDE_ENABLED kill switch.
  • Spec-first: OpenAPI 3.1 and JSON Schema contracts enforced at runtime and in CI.
  • Remote MCP server with OAuth 2.1: add one URL to Claude Code, Claude Desktop, VS Code or Cursor, sign in with GitHub, and manage Relay by chatting (docs/mcp.md, ADR 004, ADR 005).
  • Dashboard: a small server-rendered UI at /dashboard for people who don't use MCP.
  • Richer summaries (opt-in): merged PR descriptions from GitHub, and issue details from the tenant's ticket tracker through Anthropic's MCP connector, with read-only tool allowlists and fallbacks (docs/summaries.md).

Running locally

Prerequisites: Node.js 22.12+, Docker (for Postgres), a GitHub App, an Anthropic API key and a Resend API key.

bash
git clone https://github.com/vishnumuthyalu/relay-extension.gitcd relay-extensionnpm installcp .env.example .env          # fill in the values; see docs/github-app.mddocker compose up -d db       # Postgres on localhost:5432 (dev + test databases)npm run migratenpm run dev                   # web process on :3000npm run dev:worker            # worker process, in a second terminal

GitHub must reach your machine for webhooks and sign-in, so run a tunnel (ngrok http 3000) and use its URL as PUBLIC_URL and in the app settings.

Then:

  1. Open PUBLIC_URL/install and install the app on a repository.
  2. Open PUBLIC_URL/dashboard and sign in with GitHub.
  3. Map the repository to a client in the dashboard, with the API (below) or with the MCP tools. The client receives a confirmation email.
  4. After the client confirms, push to the default branch, or run node simulate-webhook.js.

To run everything in containers instead: docker compose up --build.

Deploying

One image, two processes (web, worker), one Postgres. The hosted instance runs on Fly.io (one web and one worker machine) with Supabase Postgres; migrations run as Fly's release command before each deploy. See docs/deploy.md. Tags drive releases: v* deploys the backend and updates the MCP Registry entry, and ext-v* publishes the VS Code extension.

Configuration

All settings are environment variables; .env.example lists and explains each one. The web and worker processes refuse to start if a required value is missing.

VariableRequiredPurpose
DATABASE_URLYesPostgres connection string
PUBLIC_URLYesPublic base URL (webhooks, sign-in callback, email links)
SESSION_SECRETYes32+ random characters; signs sessions and email links
GITHUB_APP_SLUG, GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_WEBHOOK_SECRETYesFrom the GitHub App
ANTHROPIC_API_KEYUnless CLAUDE_ENABLED=falseClaude API key
RESEND_API_KEY, FROM_EMAILYesEmail delivery (verify your sending domain in Resend)
ANTHROPIC_MODELNoDefault claude-haiku-4-5
DIGEST_MONTHLY_CAPNoClaude-written digests per installation per month, default 100
CLAUDE_ENABLEDNofalse sends plain digests for everyone
GITHUB_APP_ID, GITHUB_APP_PRIVATE_KEYNoPull request context in summaries
INTEGRATIONS_KEYNoEncrypts ticket-tracker tokens; enables tracker connections

API

The JSON API is described in spec/openapi.yaml and validated at runtime. It uses the session cookie from Sign in with GitHub.

MethodPathPurpose
GET/api/meYou and the installations you can manage
GET/api/installations/{id}/mappingsClient mappings with status (pending, active, unsubscribed)
PUT/api/installations/{id}/mappings/{owner}/{repo}Create or update a mapping; sends the confirmation email
DELETE/api/installations/{id}/mappings/{owner}/{repo}Stop digests for a repository
POST/api/installations/{id}/mappings/{owner}/{repo}/testSend a sample digest to a confirmed client
GET/api/installations/{id}/digestsDigest history
GET/api/installations/{id}/usageThis month's usage against the cap

Other routes: POST /webhook/github (GitHub App deliveries), /mcp (remote MCP), /oauth/* and /.well-known/* (OAuth for MCP clients), /dashboard, /auth/login, /auth/callback, POST /auth/logout, /install, /confirm, /unsubscribe, /privacy, /health, /ready.

MCP server

Remote: add https://relay-vishnu.fly.dev/mcp to your MCP client (or https://<host>/mcp for your own deployment). For example:

bash
claude mcp add --transport http relay https://relay-vishnu.fly.dev/mcp

Local, against your own database:

bash
RELAY_INSTALLATION_ID=12345678 npm run mcp   # stdio server for one installationnpm run mcp:inspect                          # open it in the MCP Inspector

Client setup is in docs/mcp.md, and the tool contract is in spec/mcp-tools.md.

Testing

Tests run against a real Postgres: each test file gets its own schema, so suites run in parallel. docker compose up -d db creates the relay_test database.

bash
npm testnpm run lintnpx @stoplight/spectral-cli lint spec/openapi.yaml --ruleset .spectral.yaml

CI runs the same steps on Node 22 and 24 with a Postgres service container, and fails if coverage drops (npm run test:coverage).

Project structure

relay-extension/├── server.js                 # Web process: webhooks, sign-in, API, email link pages├── worker.js                 # Worker process: sends digests from the queue├── lib/│   ├── config.js             # Env validation│   ├── db/                   # Postgres pool, migrations runner, tenant-scoped queries│   ├── jobs/process-push.js  # One delivery: caps, Claude or fallback, email, records│   ├── queue.js              # pg-boss setup│   ├── service.js            # Per-installation operations shared by API and MCP│   ├── pipeline.js           # Summarize + email│   ├── claude.js             # Claude structured outputs + schema validation│   ├── email.js              # Email HTML, unsubscribe headers, Resend│   ├── links.js              # Signed confirm/unsubscribe links│   ├── github.js             # GitHub OAuth (Sign in with GitHub)│   ├── oauth/                # MCP authorization server: clients, tokens, JWT│   ├── context/              # Optional PR and ticket context for summaries│   ├── github-app.js         # GitHub App JWT and installation tokens│   ├── crypto-box.js         # AES-256-GCM for stored tracker tokens│   ├── html.js, csrf.js      # Server-rendered pages and form protection│   ├── security.js           # Webhook HMAC verification│   └── retry.js              # Retry with backoff for Claude and Resend├── routes/                   # webhook, mcp, oauth, auth, dashboard, api, email links├── migrations/               # Numbered SQL migrations├── mcp/                      # MCP server, tools, resources, stdio entrypoint├── spec/                     # OpenAPI, JSON Schemas, webhook and MCP contracts├── tests/                    # Jest suites + helpers (per-file Postgres schema)├── extension/                # VS Code extension: registers the remote MCP server├── server.json               # MCP Registry entry├── fly.toml                  # Fly.io deployment (web + worker, migrations on release)├── docs/                     # GitHub App, MCP, summaries, deployment, ADRs, sequence diagram├── docker-compose.yml└── Dockerfile

Security

  • Webhooks are verified with HMAC-SHA256 (constant-time) before anything else reads the body.
  • Delivery IDs are claimed atomically, so duplicates and redeliveries never send twice.
  • Sessions are signed httpOnly cookies with SameSite=Lax. The JSON API only accepts JSON bodies, which blocks cross-site form posts.
  • Tenant data is always queried by installation, and other tenants' installations return 404.
  • Email links are HMAC-signed and bound to the current address. Changing a client's email invalidates old links.
  • Everything rendered into email or pages is HTML-escaped. Commit text is passed to Claude as untrusted data, and replies are schema-validated.
  • No GitHub tokens are stored.
  • MCP access tokens are bound to PUBLIC_URL/mcp (RFC 8707). PKCE is mandatory, authorization codes are single-use, refresh tokens rotate, and both are stored only as hashes. The /mcp endpoint checks the Host header against DNS rebinding.

License

MIT

Source: README.md at commit c454b50

Tools

0
This server asks you to sign in, so SourceWeft could not read its tools without an account and has not indexed them. What a connected account sees can depend on that account and its permissions.

Version history

1
  1. v1.0.1LatestOct 23, 2026

Score

85% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listed15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts