The guide
From zero to your first tailored PDF.
The rest of this site explains why Maestro works the way it does. This is the how: install it, find your way around, and run one real application through it — in the order that actually works. It assumes no Docker or terminal experience beyond copy-pasting.
Had an agent do the install?
Then steps 1 and 2 are already done — the clone, the .env and the running stack. Skip to Find your way around, and come back here only if something looks wrong.
Step 1 — doing it yourself
What you need first
Docker
Docker Desktop on macOS or Windows; Docker Engine with Compose v2 on Linux. Start it and leave it running — the most common first-run error, “Cannot connect to the Docker daemon”, just means Docker Desktop isn't open.
docker infoAny output that ends without an error means you're fine.
About 4 GB of disk
For the three images. The backend carries a minimal TeX Live, Typst and the pinned embedding model, which is most of it.
An API key — not yet, though
OpenAI or Gemini. You add it inside the app after first boot, not now. Without one the deterministic core still runs: ATS scoring, PDF rendering, tracking.
Python 3.12+ — only for MCP
Needed for the MCP server in step 6. The app itself doesn't need it.
Step 2 — doing it yourself
Install and first boot
git clone https://github.com/seinun-ai/maestro-career-studio.git
cd maestro-career-studio
cp .env.example .envdocker compose up -d --buildThe first build takes several minutes — it installs TeX Live and downloads the embedding model, once. Then open http://localhost:3000.
First boot starts PostgreSQL on port 55432, runs migrations, seeds a demo resume with rendered previews, and — if a key is present — builds a demo Career KB from it.
If something goes wrong
| You see | It means | Do |
|---|---|---|
Cannot connect to the Docker daemon | Docker isn't running | Start Docker Desktop, wait for “running”, re-run the command |
port is already allocated | Another app owns 3000, 8001 or 55432 | Change the matching *_HOST_PORT in .env |
Build sits at TeX Live or the model download | Normal on a first build | Wait it out. Later builds are fast. |
Page loads but everything errors | Backend still starting | curl -s localhost:8001/health answers {"status":"ok"} when it's ready |
Added a key to .env after starting | Keys are read at process start | docker compose restart backend — and remember an in-app key overrides .env |
Calls fail 401 though Settings says Configured | A stale key. The label says where it lives. | Re-enter it in Settings → Models and press Test |
Starting over, properly
Deleting the project folder does not delete your data, and neither does docker compose down. The database lives in a Docker volume named after the folder, inside Docker itself.
Re-cloning into a folder with the same name re-attaches the old database. Your resumes, applications and even a saved key come back. That's the right default — an accidental deletion never costs you data — but it means “delete and clone again” is not a fresh install. Clone into a differently named folder to test one.
Deleting only the folder leaves your state half-gone: the database survives, but rendered PDFs under applications/ and base_resumes/ don't, so the app may list documents whose files are missing. Re-render them; the content is safe.
docker compose down -vWhen you do want everything gone — demo data, your data, stored keys — this is the one command. Run it from the project folder. It cannot be undone.
Step 3
Find your way around
The sidebar, top to bottom.
New application
Capture a job and start tailoring against it.
Applications
Every job you've captured, from saved to signed.
Agent Proposals
The triage inbox for jobs an agent hunted.
Referrals
Contacts and their company careers pages.
Career KB
Your evidence: work history as approved, reusable points.
Base Resumes
One resume per career track, composed from the KB.
Templates
The LaTeX and Typst designs your PDFs render through.
Chat
The scoped in-app assistant. Pin a resume, section or bullet.
Analytics
What the market you're applying into keeps asking for.
Profile
Persona, job preferences, and your autofill contact details.
Settings
Models and keys, prompts, quick-tailor defaults, hunt caps.
Step 4
Your first session, in order
The order matters. Everything downstream composes from the Career KB, so feed that first and the rest gets easier.
- 1
Import every resume you have
Up to 10 files a batch. Old versions, role-specific variants, the too-long one — they all carry evidence.
- 2
Approve the KB inbox
Imported points arrive as drafts. Only approved points ever land on a resume. Merge the duplicates once and every future application benefits.
- 3
Fill in your Profile
Contact details, persona, and job preferences — roles, seniority, location, work authorization. Those drive scoring warnings and agent hunts.
- 4
Add your API key and pick models
Settings → Models. Press Test on each: it measures what the model can actually do before you depend on it.
- 5
Pick a default template
Every render uses it unless a resume overrides it. You can switch any time without touching content.
- 6
Build a base resume per career track
Base Resumes → New → From Career KB. Then run the Health check: fixing its findings now beats fixing them after every tailoring run.
- 7
Capture a job
Paste the posting text or URL, or use the side panel. Extraction structures it; the deterministic engine scores it against every base.
- 8
Tailor through the gap workflow
Each gap names a requirement your resume doesn't evidence. Answer honestly and true-but-unwritten material becomes permanent KB evidence. Every AI edit is a revertible diff — read it.
- 9
Set quick-tailor preferences
Once you've done a few manual passes. Then Quick Tailor handles the already-know-the-answer cases in one step.
- 10
Generate the package and read it
Cover letter, screening answers, the PDF. Every render is filed on disk under applications/ in a company-and-role folder, so you can verify exactly what you sent.
- 11
Track it
Mark applied, record outcomes. Analytics starts paying off after about ten captured jobs.
Step 5
The browser side panel
Save the posting in front of you, score your bases against it, fill the form from your autofill profile, and mark it applied — without leaving the tab.
Open chrome://extensions and switch on Developer mode, top right.
Load unpacked → select the repo's extension/ folder.
Pin the icon, then click it on any job page to open the panel.
If you changed the app's ports in .env, set the backend and app URLs under the panel's ⋯ menu.
Drive it from your assistant
With the backend running, one command prepares everything. The venv it creates is the server — there's nothing else to install.
./scripts/setup-mcp.shClaude Code
Nothing more to do for sessions opened in this repo — the script writes a repo-level .mcp.json and the session offers the server automatically. Approve it when prompted. It registers user-wide too, for sessions elsewhere.
Claude Desktop
Quit the app first with Cmd+Q. Then Settings → Developer → Edit Config, paste the block the script printed into mcpServers, save, and reopen. Quitting first matters: a running app rewrites that file on exit and will silently drop your edit.
ChatGPT desktop / Codex CLI
Both read ~/.codex/config.toml. Append the TOML block the script printed, then restart the app.
Step 7
Where it can go next
Once the server is registered, your assistant can run the whole loop. The repo ships the author's own prompts as adaptable starting points.
A scheduled daily hunt
Capture, score and propose only. You triage the results on Agent Proposals.
Referral-first hunting
Add contacts and their careers pages under Referrals, then point a hunt at those URLs specifically.
Attended apply runs
Working the accepted-proposal queue with a browser, one consent per application, always stopping before submit.
Whatever the agent does, the consent posture holds: nothing is submitted without your explicit per-application yes, and everything is written down.
Step 8
Keeping it up to date
One command, run from inside the folder you cloned. It takes a database backup, moves your checkout to the newest released version, brings the images to that same version, and waits until the stack is healthy again.
cd ~/maestro-career-studio # wherever you cloned it
./scripts/update.sh./scripts/update.sh --checkChanges nothing. Answers only: am I up to date?
It's bash, so on Windows run it under WSL — or use the manual command-by-command form in the README.
Your data is not involved
Resumes, applications, KB documents and settings are files on disk no update step touches, and the database lives in a Docker volume that survives all of this. The backup guards the migration specifically.
Migrations run themselves
They run when the backend starts, so the first boot after an update takes longer than usual. The script tells you it's waiting.
Two things stay manual
Docker can't reach them: reload the extension at chrome://extensions and reload any open job tab, then restart your MCP client. The script prints both reminders when it finishes.
Your checkout and your images move together, always. An install here is a git checkout — the unpacked extension loads from extension/ and the MCP server's venv sits over backend/. Pulling images alone would update two of the four surfaces and leave the extension and MCP client running code your API no longer has.
It's early. I'd rather hear about it.
I built this because I needed it, and I use it every day. It also has the rough edges of software with one user, especially that first boot from a fresh clone. If something breaks, tell me. A clear bug report is a contribution and right now it's the most useful kind. Pull requests welcome too.
— Ajey Dhayashanker Loganathan
Career tooling should be infrastructure, not a rental.
Clone it, run it, keep everything it produces. Nothing here was built to make leaving hard.
Apache-2.0 · no account · no subscription · your data stays on your disk