mcp server
coldtrail
Discovery-first cold outreach for solo founders — find the companies other tools miss, draft each email in your voice, send from your own Gmail. Local, single Rust binary. Built on Canonical.
Set up
Runs on your computer. Pick your agent and operating system.
This project does not publish an install method we can turn into a config. Follow the README instead.
README
synced Oct 17, 2026coldtrail
Discovery-first cold outreach for solo founders & one-person sales teams. Find the companies other tools miss, draft each touch in your own voice, send from your own email (Gmail) and LinkedIn — all on your machine. Built on Canonical.
Most outreach tools start from a list you already have and optimize the sending. coldtrail starts from the opposite end: discovery. You describe who you want to reach in plain English; Canonical returns verified, long-tail companies the big databases miss; an agent enriches a founder contact, writes a genuinely personalized email from your company profile, and (only if you say so) sends it. No CRM to feed, no seat to buy, nothing leaves your laptop except the emails you approve.
coldtrail is a single binary. Run it and it opens a local app in your browser — a chat that
drives an agent (Claude Code / Codex / opencode, or your own model) to source, enrich, and draft, plus a
pipeline dashboard, an editable company profile, and a drafts view.
Demo
Your company profile → a run in Chat (source → enrich → draft) → the pipeline of verified companies → a personalized draft ready to send. (higher-quality MP4)
Install
curl -fsSL https://raw.githubusercontent.com/dilpreet92/coldtrail/main/install.sh | bash
You need a provider (the brain): Claude Code (claude) or
Codex (codex) — which reuse your existing subscription —
opencode (opencode, with whatever providers you've signed it into), or
any OpenAI-compatible endpoint / local Ollama. The installer checks for one and tells you how
to get it if it's missing. Then:
coldtrail # opens the app at http://127.0.0.1:8787
coldtrail keeps itself current: on launch it checks for a newer release and updates in place
before starting (run coldtrail update to do it on demand, or COLDTRAIL_NO_UPDATE=1 coldtrail
to skip the check).
Getting set up (first run)
The browser opens to a short Setup wizard:
- Provider — pick Claude Code / Codex / opencode, or point at your own OpenAI-compatible/Ollama
model. For opencode, pin the model in
~/.coldtrail/config.toml(opencode_model = "provider/model", any id fromopencode models) so scheduled runs don't depend on whatever you last used in its TUI. - Discovery — Canonical (sourcing). Keyless: click Connect and approve in the browser.
- Destination — Gmail. Easiest is a Gmail app password (keyless, ~2 min): turn on 2-Step Verification, create an app password, enable IMAP. (Advanced: bring your own Google OAuth client instead.) LinkedIn is also a destination — see LinkedIn destination below; connect it anytime from Settings → Destination.
- Company — chat-free, just an editable profile. Describe what you sell, who it helps, your offer, your link, your voice. The agent writes every email from this, in your words — it never invents claims. Edit it anytime in the Company tab; it saves as you type.
Then use Chat to run the loop, Pipeline to watch companies move through statuses, Drafts to review, and Follow-ups to track replies.
How a run works
In Chat, say something like "find companies for <my ICP> and draft intros." The agent runs the whole loop:
- Source (Canonical). It plans several diverse search angles (expanding acronyms/regions into real phrasings), searches them in parallel, and imports the union deduped by domain — so you cover the long tail without double-contacting anyone.
- Enrich. A founder contact per company, working down coldtrail's technique ladder (OSINT tools, GitHub commit metadata, crt.sh, WHOIS, on-domain) — an MX-verified, founder-addressed email, or a verified LinkedIn profile URL; either makes a company reachable.
- Draft. A tailored subject + body per company, composed fresh from your Company profile and what the company actually does. Nothing is sent verbatim.
- Send — your call. By default drafts wait for you in the Drafts tab. If you've turned on auto-send, the agent asks "send these now?" and, on your yes, sends them (under your daily cap). It works in warmup-sized batches (~5 at a time) so you never outrun a healthy pace.
Canonical (sourcing) ← plain-English ICP → verified companies the big DBs miss
│
▼
local SQLite ← deduped by domain, one status per company (no double-contact)
│
▼
enrichment ← founder email or LinkedIn URL per company (OSINT ladder · your key · by hand)
│
▼
draft (your voice) ← personalized from your Company profile; never verbatim
│
▼
send ← drafts by default; opt-in auto-send (capped) when you trust it
Sending: off by default, yours to turn on
The standing default is draft-only — a human reviews and sends every message. When you're confident the drafts are good, flip on Auto-send in Settings → Destination (with a daily cap). Then the Drafts screen sends for real on your click, and the agent can send within a run after you confirm. Sending is gated two ways — it won't fire unless both auto-send is on and you say yes — so nothing goes out by accident.
Cron — scheduled runs
The Cron tab runs coldtrail while you're away. Create any number of named schedules,
each with its own cadence — daily or weekly at a time you pick (weekly also picks a
weekday) — and its own task: either agent decides, where the agent plans fresh, diverse
search queries from your product.md profile and what it's already sourced, or a custom
prompt you write yourself (e.g. "source 20 companies like Linear and draft intros"). Each
schedule installs exactly one OS timer — macOS launchd (ai.coldtrail.run.<id>) or Linux
systemd (coldtrail-<id>) — so schedules survive reboots and don't depend on coldtrail staying
open. The tab shows each schedule's next run and a run history with last run, and two
buttons that jump straight to the run's chat and stream it live: Run now (runs it immediately,
same as its scheduled trigger) and Dry run (drafts only — it hard-gates every send, so nothing
goes out no matter your auto-send settings). Every run uses the agent you picked in Setup — switch
it there (e.g. to opencode) and the schedules follow.
A scheduled run (and a manually triggered "Run now") does the full loop — source → enrich → draft — and then sends per your existing config: emails go out if auto-send is on (under its daily cap), and LinkedIn connection requests go out if LinkedIn auto-send is on (via the same paced, daily- and weekly-capped sender used everywhere else). Leave both off and a schedule only ever produces drafts for you to review.
One caveat worth knowing: LinkedIn sends drive a real, human-visible Chrome window, so a scheduled LinkedIn send only completes if the machine is awake, you're logged in, the screen is unlocked, and LinkedIn is connected at run time — otherwise it fails safe (nothing sent, the draft stays in Drafts for you to send by hand later). Email sends need no browser and aren't affected by machine/screen state.
LinkedIn destination
Contacts don't always have a findable email — coldtrail can also reach a founder on LinkedIn. When enrichment finds only a LinkedIn profile URL (no MX-verified email), the agent writes a short connection note instead of an email draft. One touch per company either way — never both channels.
Connect. In Settings → Destination, click Connect LinkedIn (or run
coldtrail linkedin connect): coldtrail opens a real, human-visible Chrome window at
LinkedIn's login page and waits up to three minutes for you to log in yourself — coldtrail
never sees or stores your password. Once you're in, it saves the connection state and reuses
that Chrome profile for every LinkedIn action after.
Assist by default, gated auto-send. Every LinkedIn note lands in the Drafts tab first. The default hand-off is Open in LinkedIn — coldtrail drives the browser through Connect → Add a note → fill your text, then stops and lets you click Send yourself. If you flip on LinkedIn auto-send in Settings → Destination (a separate toggle from email auto-send), the agent can drive all the way through Send after you say yes in chat — same two-part gate as email (opt-in + explicit yes), just tracked per channel.
Caps, pacing, and account safety. LinkedIn's terms restrict automated activity, and aggressive, bursty, or off-hours connection requests are what gets accounts restricted — so auto-send is deliberately conservative and opt-in: a rolling weekly cap (80 by default) and a daily sub-cap (15 by default), both configurable; sends only inside a daytime local-hours window (08:00–20:00); only one Chrome session driving your profile at a time; and every send is verified on-screen before it's recorded — coldtrail never marks an invite "sent" without observing LinkedIn's own confirmation. Assist mode has no cap because a human is doing the actual clicking.
Where the session lives. LinkedIn's cookies/session live in a coldtrail-owned Chrome
profile directory outside the agent's workspace, next to your other secrets — in your OS
config dir (dirs::config_dir()): ~/Library/Application Support/coldtrail/linkedin-profile
on macOS, ~/.config/coldtrail/linkedin-profile on Linux, %APPDATA%\coldtrail\linkedin-profile
on Windows — created with locked-down (0700) permissions. It holds only the browser session,
never a password. The workspace agent that runs shell commands can't read it.
Guardrails baked in
- Dedupe by domain — you can't double-contact a company.
- Founder-addressed, verified. An email contact is MX-verified — generic (
info@/sales@) and placeholder addresses are rejected, so guessed addresses don't bounce. A LinkedIn-only contact is verified by being a real profile URL instead. - No fabrication — emails are written from your profile and real facts about the company.
- Draft-first, gated send — sending is off until you enable it, capped for warmup, and the
agent can only trigger
coldtrail send(it never touches your credentials or mail APIs directly).
Everything stays local
State lives in ~/.coldtrail/ — the SQLite pipeline, your product.md profile, the agent brief
(CLAUDE.md), the enrichment playbook, and config. Credentials live outside the workspace
(in a sibling secrets dir), so the agent that runs shell commands can't read them. The app binds
127.0.0.1 only, guarded by a one-time token in the URL. Nothing leaves your machine except the
emails you approve.
Command-line surface
Bare coldtrail serves the app; every step also runs headless for power users / CI:
coldtrail serve --port 9000 --no-open # serve without opening a browser
coldtrail setup # terminal setup wizard (idempotent)
coldtrail agent # raw terminal agent in the workspace
coldtrail linkedin connect # open Chrome, log into LinkedIn, save the session
coldtrail linkedin status # print the persisted LinkedIn connect state
| Command | What it does |
|---|---|
coldtrail source "<angle>" ["<angle>" …] | source from Canonical across angles, deduped by domain |
coldtrail add-contact <domain> "<Name>" [email] [--linkedin <url>] [source] | add a founder contact — email (MX-verified), LinkedIn URL, or both |
coldtrail find-emails [max] | best-effort OSINT founder-email finder |
coldtrail draft <domain> --subject "…" --body "…" | store a personalized draft (never sends) |
coldtrail linkedin-note <domain> --note "…" | store a ≤300-char LinkedIn connection note (never sends) |
coldtrail send <domain> | send a reviewed draft for real, either channel (refuses unless that channel's auto-send is on) |
coldtrail followup <domain> --subject "…" --body "…" | store a follow-up touch |
coldtrail mark <domain> <sent|replied|bounced> | advance status |
coldtrail seed | load already-contacted domains from contacted.toml |
Build from source
git clone https://github.com/dilpreet92/coldtrail && cd coldtrail
cargo build --release # -> target/release/coldtrail
cargo test
Powered by Canonical
The sourcing engine is Canonical — verified, long-tail company search, available as an MCP server and a ChatGPT app. Free tier: 250 credits, no card.
License
MIT. Built in public by a solo maintainer — no roadmap or SLAs, but issues and PRs are welcome if the bones are useful for your own outreach.