A minimalist CLI that turns Claude Code or OpenAI Codex into your research intern. Run one command, get a browser terminal where you can tell an AI agent:
"Start a new project on transformer attention sinks."
…and watch it create the GitHub repo, scaffold a LaTeX paper on Overleaf, and start drafting — all from a clean black-and-white terminal in your browser.
╭───────────────────────────────╮
│ │
│ ⌁ c o r a l - i n t e r n │
│ │
╰───────────────────────────────╯
your research, on autopilot
A research project usually lives in two places: code on GitHub and the paper on Overleaf.
coral-intern is the thinnest possible glue layer that lets a coding agent (Claude Code or Codex) drive both, while you talk to it from a browser terminal that looks and feels like a real shell.
No web app to deploy. No accounts to create. One CLI, one localhost page.
One-line (recommended). Handles Node setup too — no prerequisites:
curl -fsSL https://raw.githubusercontent.com/Human-Agent-Society/coral-intern/main/install.sh | shOr, if you already have Node 20+:
npm install -g coral-internYou'll also need one of the two coding-agent backends installed locally
(coral-intern init will offer to install it for you):
| Backend | Install | Auth |
|---|---|---|
| Claude Code | npm i -g @anthropic-ai/claude-code |
claude login or ANTHROPIC_API_KEY |
| OpenAI Codex | npm i -g @openai/codex |
codex then "Sign in with ChatGPT" or OPENAI_API_KEY |
Run coral-intern doctor any time to check what's installed and configured.
# 1. One-time setup — pick an agent, paste a GitHub token, done.
coral-intern init
# 2. Start a project.
coral-intern start my-paper
# Your browser opens at http://localhost:7878
# A terminal shows up. Talk to your intern:
#
# > Read the paper outline in README.md and draft the introduction.
# > Push the code, then update the LaTeX on Overleaf.
# > Find three related papers and add them to references.bib.That's it. Close the browser tab to end the session.
The main view in your browser is a meeting — the kind of standup you'd hold with a human research intern. Your intern (the agent) works asynchronously between meetings. When you open the app, they've drafted an agenda for the next standup:
- Since last meeting — bullets of what got done, with commit SHAs / files / links as evidence.
- Open questions — uncertainties they hit, each with their own recommendation and the reasoning behind it. Never a bare question.
- Proposals — 3–7 concrete next steps, each with a why and an acceptance criterion.
- Discussion — a chat transcript that grows turn by turn as you talk.
You speak to your intern via Wispr Flow (or type — one big always-focused input at the bottom). Confirm proposals with a click, drop the ones you don't want, add new ones mid-discussion. When you're satisfied, hit Wrap up ✓ — the confirmed proposals become the intern's work queue, they go off to execute them, and the next meeting is auto-drafted while you're away.
Why this matters. Todos never appear out of nowhere: every action item comes from a meeting where you agreed to it. The intern never disturbs you between meetings; uncertainties get filed and surface as questions next round. And because everything runs through a plain textarea, any OS dictation tool (Wispr Flow is our default) makes voice interactions natural.
If you ever want to see what the agent is doing under the hood, hit Cmd/Ctrl + ` to reveal a debug terminal attached to the live PTY.
- Creates
./<name>/with a minimal LaTeX template (main.tex,references.bib,README.md). - Initializes a git repo, creates a public GitHub repo under your account, pushes the first commit.
- Either builds an Overleaf import URL (using Overleaf's documented
snip_uriendpoint) — one click and Overleaf clones the GitHub zip into a new project for you, works on free Overleaf accounts — or links the existing Overleaf project you passed via--overleaf-url. - Starts a local web server (default
http://localhost:7878) with a terminal page. From the sidebar you can change the linked Overleaf URL at any time. - Launches
claudeorcodexinside the project directory under a PTY, with MCP servers pre-wired so the agent can act on GitHub and Overleaf without leaving the chat.
| Command | What it does |
|---|---|
coral-intern |
Default — re-attach to the coral-intern project in this directory (or the most recent one). Just type this when you cd into a project. |
coral-intern init |
Interactive one-time setup. Pick agent, save GitHub token + (optional) Overleaf token to ~/.coral-intern/config.json. |
coral-intern doctor |
Verify backends, tokens, and dependencies. |
coral-intern start <name> |
Scaffold a new project, link GitHub + Overleaf, launch browser terminal. Refuses if you're already inside a coral-intern project (nested projects aren't supported, like git init in an existing repo). |
coral-intern start <name> --here |
Use the current directory instead of creating ./<name>/. |
coral-intern start <name> --port 8000 |
Override the web server port. |
coral-intern start <name> --agent codex |
Override the agent for this session. |
coral-intern start <name> --overleaf-url <url> |
Link an existing Overleaf project instead of being prompted. |
coral-intern start <name> --skip-overleaf |
Skip the Overleaf prompt entirely. |
coral-intern start <name> --private |
Create the GitHub repo as private. (Note: this disables one-click Overleaf import.) |
coral-intern open |
Same as bare coral-intern — re-attach to the project here, or the last one. |
coral-intern --help |
Show all commands. |
Stored at ~/.coral-intern/config.json:
{
"agent": "claude",
"github": { "token": "ghp_…", "username": "you" },
"overleafGitToken": null,
"port": 7878,
"lastProject": "/Users/you/projects/my-paper"
}Anything sensitive (the GitHub PAT) is chmod 600. Delete the file to start over.
Create a fine-grained PAT at https://github.com/settings/personal-access-tokens with:
- Repository permissions: Contents (R/W), Metadata (R), Pull requests (R/W)
- Account permissions: leave default
- Or use a classic PAT with
reposcope.
By default coral-intern uses zero Overleaf API — it just stores a link to your project so the agent knows where the paper lives, and (for new projects) generates Overleaf's documented snip_uri import URL. Free Overleaf accounts work end-to-end.
To let the agent push edits directly to Overleaf (so you don't have to re-import or copy/paste), you need an Overleaf Premium git token:
- Get the token: Overleaf → Account Settings → Git Integration → New Token. Overleaf Premium is required — MIT, Stanford, and many other schools provide it free at overleaf.com/edu.
- Save it: either re-run
coral-intern init(4th step), or — easier — from the web terminal sidebar click "Connect for direct edits" and paste the token. - Refresh the page so the agent picks up the new token, then ask it to push.
When configured, the Overleaf row in the sidebar shows a green "direct push enabled" badge. The agent uses the overleaf_push MCP tool to clone your project, overlay your local .tex/.bib/figures, commit, and push back — no duplicate projects.
The sidebar's resource rows are fully interactive:
- GitHub · click the pencil → modal lets you (a) link any existing repo by URL or
owner/repo, (b) create a new repo under your account and push initial content, or (c) unlink. - Overleaf · same pattern — link an existing project URL, generate a new one from your GitHub repo, or unlink. Plus the Connect for direct edits affordance for the premium token.
Both modals validate input, use your saved tokens, update CLAUDE.md / AGENTS.md so the agent sees the change immediately, and surface clear errors when something is wrong.
For maintainers / forkers:
# 1. Bump version
npm version patch # or minor / major
# 2. Build & test locally
npm run build
node dist/cli.js --help
# 3. Login to npm (one time)
npm login
# 4. Publish (runs tsc cleanly first via prepublishOnly)
npm publish --access publicTo test before publishing:
npm pack # produces coral-intern-x.y.z.tgz
npm i -g ./coral-intern-*.tgz # try itTo unpublish a broken patch within 72h:
npm unpublish coral-intern@<version>install.sh lives at the repo root. The curl | sh one-liner in the install
section just fetches it from GitHub's raw endpoint, so no extra hosting is
needed — push the repo and the URL works.
Want a prettier URL like curl get.coral-intern.dev | sh? Two options:
- Cloudflare Worker / Netlify redirect pointing your custom domain to the GitHub raw URL. Five-minute setup.
- GitHub Pages: enable Pages on the repo and
install.shis served athttps://human-agent-society.github.io/coral-intern/install.sh.
Either way, update the install-section URL in this README and you're done.
git clone <your-fork>
cd coral-intern
npm install
npm run dev -- --help # run via tsx, no build needed
npm run build && node dist/cli.js doctorLayout:
src/
cli.ts commander entry
commands/
init.ts first-run wizard
doctor.ts health check
start.ts main project launcher
open.ts re-open last project
config.ts ~/.coral-intern/config.json reader/writer
integrations/
github.ts octokit + simple-git
overleaf.ts snip_uri builder
server/
server.ts express + ws on localhost
pty.ts spawns the agent under node-pty
public/ xterm.js terminal page
mcp/
config.ts builds the MCP servers JSON the agent sees
overleaf-server.mjs tiny stdio MCP server exposing overleaf tools
templates/research/ LaTeX skeleton copied into new projects
util/
log.ts chalk + ora wrappers
MIT