Free open-source email gateway: connect Gmail/Microsoft 365 via OAuth, use them from sequencers (SMTP+IMAP), AI agents (MCP) and apps (REST) — AGPL
Drift inferred · capture-to-capture
No drift recorded — single capability capture; advisories appear once its surface changes.
transport streamable-http · http counts 14 tools · 0 res
· 0 prompts
permission surface via code analysis
tools
-
bulk_warmup
-
create_connect_link
-
export_sequencer_csv
-
get_message
-
get_send_status
-
get_warmup_status
-
list_accounts
-
list_folders
-
list_messages
-
list_send_jobs
-
list_warmup_messages
-
revoke_connect_links
-
send_email
-
set_warmup
prompt-surface
shipped agent-instruction files + hidden-content / dangerous-code findings —
quoted from the analyzed source
analyzed commit 2c37313 · analyzer v33 · 4h ago
danger signals6
- suspicious endpoint 169.254.169.254 (cloud metadata) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/webhook-ssrf.test.ts :17
'http://169.254.169.254/latest/meta-data', - suspicious endpoint 8.8.8.8 BreazyLabs-OutreachEmailMCP-2c37313/src/tests/webhook-ssrf.test.ts :27
expect(await isPrivateWebhookTarget('http://8.8.8.8/hook')).toBe(false); - over-broad OAuth scope gmail.modify BreazyLabs-OutreachEmailMCP-2c37313/src/providers/oauth.ts :20
'https://www.googleapis.com/auth/gmail.modify', - over-broad OAuth scope gmail.modify BreazyLabs-OutreachEmailMCP-2c37313/src/tests/imap-e2e.test.ts :84
supportsWrite: (scopes: string) => scopes.includes('gmail.modify'), - over-broad OAuth scope gmail.modify BreazyLabs-OutreachEmailMCP-2c37313/src/tests/tenancy.test.ts :130
'openid email https://www.googleapis.com/auth/gmail.send https://www.googleapis.com/auth/gmail.modify'; - over-broad OAuth scope gmail.modify BreazyLabs-OutreachEmailMCP-2c37313/src/tests/warmup-flow.test.ts :90
.values({ accountId: id, accessTokenEnc: 'x', refreshTokenEnc: 'y', expiresAt: now + 1e9, scopes: 'gmail.modify Mail.ReadWrite', updatedAt: now })
evidence-backed
findings quoted directly from the published source artifact — not inferred
code files: 123
filesystem 11
- fs BreazyLabs-OutreachEmailMCP-2c37313/src/config.ts :3
import fs from 'node:fs'; - fs BreazyLabs-OutreachEmailMCP-2c37313/src/domains/service.ts :22
import fs from 'node:fs'; - fs BreazyLabs-OutreachEmailMCP-2c37313/src/imap/index-store.ts :1
import fs from 'node:fs'; - fs BreazyLabs-OutreachEmailMCP-2c37313/src/imap/session.ts :1
import fs from 'node:fs'; - fs BreazyLabs-OutreachEmailMCP-2c37313/src/observability/healthcheck.ts :1
import fs from 'node:fs'; - fs BreazyLabs-OutreachEmailMCP-2c37313/src/queue/sendQueue.ts :1
import fs from 'node:fs'; - fs BreazyLabs-OutreachEmailMCP-2c37313/src/queue/worker.ts :1
import fs from 'node:fs'; - fs BreazyLabs-OutreachEmailMCP-2c37313/src/smtp/certs.ts :2
import fs from 'node:fs'; - fs (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/warmup-flow.test.ts :8
import fs from 'node:fs'; - fs BreazyLabs-OutreachEmailMCP-2c37313/src/ui/domains-routes.ts :28
import fs from 'node:fs'; - fs BreazyLabs-OutreachEmailMCP-2c37313/vitest.globalSetup.ts :1
import { rmSync } from 'node:fs';
network 11
- net BreazyLabs-OutreachEmailMCP-2c37313/src/auth/sso.ts :60
const res = await fetch('https://oauth2.googleapis.com/token', { - net BreazyLabs-OutreachEmailMCP-2c37313/src/billing/stripe.ts :29
const res = await fetch(`${STRIPE_API}${path}`, { - net BreazyLabs-OutreachEmailMCP-2c37313/src/imap/server.ts :1
import net from 'node:net'; - net BreazyLabs-OutreachEmailMCP-2c37313/src/imap/session.ts :3
import net from 'node:net'; - net BreazyLabs-OutreachEmailMCP-2c37313/src/inbound/webhooks.ts :3
import net from 'node:net'; - net BreazyLabs-OutreachEmailMCP-2c37313/src/providers/google.ts :34
res = await fetch(url, { - net BreazyLabs-OutreachEmailMCP-2c37313/src/providers/microsoft.ts :43
res = await fetch(url, { - net BreazyLabs-OutreachEmailMCP-2c37313/src/providers/oauth.ts :121
res = await fetch(ep.tokenUrl, { - net (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/imap-e2e.test.ts :2
import net from 'node:net'; - net (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/send-reliability.test.ts :22
it('a thrown fetch (ECONNRESET / timeout) surfaces as RetryableError from a send', async () => { - net BreazyLabs-OutreachEmailMCP-2c37313/src/warmup/content/llm.ts :238
const res = await fetch(url, {
secrets 19
- secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/bounce-classify.test.ts :4
process.env.MASTER_KEY = Buffer.alloc(32, 5).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/bounce-stats.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 9).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/crypto.test.ts :4
process.env.MASTER_KEY = Buffer.alloc(32, 7).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/domains-api.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 13).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/domains.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 11).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/imap-e2e.test.ts :4
process.env.MASTER_KEY = Buffer.alloc(32, 7).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/internal-network.test.ts :4
process.env.MASTER_KEY = Buffer.alloc(32, 5).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/lease.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 13).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/partner-sso.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 3).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/provider-retry.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 7).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/reputation.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 9).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/send-idempotency.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 21).toString('base64');
show 7 more
- secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/send-reliability.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 23).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/sequencer-csv.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 7).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/tags.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 7).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/tenancy.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 7).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/warmup-core.test.ts :3
process.env.MASTER_KEY = Buffer.alloc(32, 9).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/warmup-flow.test.ts :10
process.env.MASTER_KEY = Buffer.alloc(32, 11).toString('base64'); - secrets (weak) BreazyLabs-OutreachEmailMCP-2c37313/src/tests/webhook-ssrf.test.ts :4
process.env.MASTER_KEY = Buffer.alloc(32, 7).toString('base64');
database 1
- db BreazyLabs-OutreachEmailMCP-2c37313/src/db/index.ts :1
import Database from 'better-sqlite3';
tool registrations 14
- list_accounts BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :84
- list_folders BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :107
- list_messages BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :117
- get_message BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :136
- list_send_jobs BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :166
- get_send_status BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :192
- send_email BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :212
- create_connect_link BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :279
- revoke_connect_links BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :305
- get_warmup_status BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :317
- list_warmup_messages BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :350
- set_warmup BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :362
show 2 more
- bulk_warmup BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :392
- export_sequencer_csv BreazyLabs-OutreachEmailMCP-2c37313/src/mcp/server.ts :405
declared dependencies 29
- @modelcontextprotocol/sdk@^1.29.0
- @fastify/cookie@^10.0.1
- @fastify/formbody@^8.0.1
- @fastify/view@^10.0.1
- better-sqlite3@^11.7.0
- drizzle-orm@^0.38.2
- ejs@^3.1.10
- fast-xml-parser@^4.5.7
- fastify@^5.2.0
- mailparser@^3.7.2
- nanoid@^5.0.9
- nodemailer@^6.9.16
show 17 more
- openid-client@^6.8.7
- pino@^9.5.0
- selfsigned@^2.4.1
- smtp-server@^3.13.6
- tsx@^4.19.2
- zod@^3.24.1
- @types/better-sqlite3@^7.6.12
- @types/ejs@^3.1.5
- @types/mailparser@^3.4.5
- @types/node@^22.10.2
- @types/nodemailer@^6.4.17
- @types/smtp-server@^3.5.10
- drizzle-kit@^0.30.1
- imapflow@^1.4.7
- pino-pretty@^13.0.0
- typescript@^5.7.2
- vitest@^2.1.8