An open-source resume editor with a self-hosted AI agent.
Your resumes stay in your browser. The AI runs on your own model key.
Kenmet (formerly Magic Resume) is an open-source AI job-search workbench: the AI proposes resume edits in place and you accept or skip each one. MIT-licensed core, 20 templates, six modes (create, optimize, analyze, translate, interview, export), cloud sync.
Kenmet (formerly Magic Resume, magic-resume.cn) and the Magic Resume at magicv.art (魔方简历) are two independent projects maintained by different teams.
This repository is the open-source edition. It contains the editor and Polaris, the AI resume assistant, together with the agent service that powers it. There is no account and no resume library on a server: resumes and one conversation per resume live in your browser's IndexedDB, and Polaris calls the model provider you configure with your own key. Interviews and multi-device cloud sync are part of the hosted product at magic-resume.cn.
Table of contents
- Live preview at print fidelity. The page re-renders as you type; exports match what you see.
- 20 templates. ATS-friendly, each with its own color, font, density, spacing and layout controls, on A4 or Letter.
- Flexible sections. Add, rename, reorder and hide sections; rich text with Tiptap; custom fields.
- Import and export. Open Kenmet JSON offline. Export to PDF, PNG or JSON.
- Local-first. Everything is stored in IndexedDB. Nothing leaves the browser unless you use AI.
- Light and dark themes, English and Chinese.
- Proposals, not overwrites. Every change the AI makes appears as a diff on the canvas, with a reason for each edit. You accept or skip changes one by one; nothing is saved until you accept.
- Skills. Create a resume from scratch, optimize it for a job description, analyze it, score its fit against a role, or translate it. Each skill is a plain Markdown file you can read and change.
- Three modes. Co-create proposes edits, Plan reads the resume and proposes a plan without changing it, and Ask answers general questions without seeing your resume at all. The boundary is enforced by the backend, not only by the prompt.
- Asks when it needs to. When a fact is missing, such as the target role, the agent shows a structured form, pauses, and continues once you answer. The pause survives a page reload or a server restart.
- Import any resume. PDF, Word, images, Markdown or plain text. Scanned documents are read by a vision model.
- Your own model. Any OpenAI-compatible API, with presets for common providers. The key is encrypted in the browser and sent only with each request; the server never stores it.
- No made-up experience. The agent checks every proposed resume against your source material and flags employers, dates, credentials or numbers it cannot find there.
Runs the editor and the agent together. Requires Docker with Compose v2.
git clone https://github.com/Magic-Resume/Magic-Resume.git
cd Magic-Resume
docker compose up --buildOpen http://localhost:3000, go to Settings → Model, choose a provider, enter your API key and model, test the connection and save. Polaris is then ready.
The editor listens on 127.0.0.1:3000. The agent has no published port and is reachable only from the editor container; its sessions are kept in the agent-data volume.
Requires Node.js 22.13 or later and pnpm 10.28.
git clone https://github.com/Magic-Resume/Magic-Resume.git
cd Magic-Resume
pnpm install
cp apps/web/.env.example apps/web/.env.local # then uncomment AI_BACKEND_URL=http://localhost:4000
pnpm devpnpm dev starts the editor on http://localhost:3000 and the agent on http://127.0.0.1:4000. Editing works without the agent; only Polaris needs it.
To point the agent at a model server on your own machine or network (for example a local OpenAI-compatible proxy), start it with AGENT_ALLOW_PRIVATE_MODEL_HOSTS=true. This switch is ignored when NODE_ENV=production.
The editor is a standard Next.js app and runs without the agent:
docker build -f apps/web/Dockerfile -t magic-resume-web .
docker run -p 3000:3000 magic-resume-webTo enable Polaris later, run the agent somewhere the editor can reach and set AI_BACKEND_URL on the editor.
flowchart LR
browser["Browser<br/>editor · IndexedDB"] -->|same-origin requests| web["Next.js routes<br/>apps/web"]
web -->|AI_BACKEND_URL| agent["Agent<br/>apps/agent"]
agent -->|your key| provider["Your model provider<br/>OpenAI-compatible API"]
agent --- store[("SQLite<br/>session checkpoints")]
- The browser owns the resume. Each request carries a snapshot of the current resume (except in Ask mode). The agent works on a draft and returns proposals; the browser saves what you accept. The draft lives only in the session's checkpoint and is deleted with it.
- The agent (
apps/agent) is a DeepAgents harness on LangGraph with a Fastify HTTP layer. It mounts the skills directory read-only, gives the model a scratch workspace holding the resume draft, and runs a middleware chain that enforces the run budget, mode boundaries, each skill's tool allowlist, resume schema validation and the fabrication check. - Sessions are LangGraph checkpoints in SQLite, so a paused form, a page reload or a restart resumes where it left off. Idle sessions expire after seven days.
- Your key stays in the request: it is never logged, written to a checkpoint or stored on disk. The agent resolves the provider's address once per request, pins the connection to it, refuses private network addresses and does not follow redirects.
- The protocol between the editor and the agent is documented in docs/reference/ai-backend.md, and the agent's design in docs/specs/agent-backend/design.md. You can replace the agent with your own implementation of the same contract.
Important
The agent has no user accounts. Keep it on a private network, as Docker Compose does, or put authentication in front of it before exposing it to other people.
Model settings (provider, key, base URL, model, output limit, reasoning strength) are configured per browser in Settings → Model. Server settings are environment variables; all are optional.
Editor (apps/web)
| Variable | Default | Purpose |
|---|---|---|
AI_BACKEND_URL |
— | Server-only origin of the agent, without /api. AI requests return 503 when it is unset. |
NEXT_PUBLIC_APP_URL |
http://localhost:3000 |
Public origin, used for robots.txt and page metadata. |
APP_PUBLIC_URL |
— | Same as above, read at request time so one image can serve several domains. |
NEXT_PUBLIC_DOCS_URL |
— | Target of the "Help center" menu item; hidden when unset. |
Agent (apps/agent)
| Variable | Default | Purpose |
|---|---|---|
HOST / PORT |
127.0.0.1 / 4000 |
Listen address. |
AGENT_DATA_DIR |
./data |
SQLite checkpoints and other runtime state. |
AGENT_SKILLS_DIR |
bundled skills/ |
Directory of skills to mount. |
AGENT_MAX_MODEL_CALLS / AGENT_MAX_TOOL_CALLS |
40 / 60 |
Budget per turn, shared with sub-agents. |
AGENT_IDLE_TIMEOUT_MS |
120000 |
Longest silence from the model before a turn fails. |
AGENT_RUN_TIMEOUT_MS |
900000 |
Upper bound for one turn. |
AGENT_SESSION_TTL_HOURS |
168 |
Idle sessions are deleted after this. |
AGENT_ATTACHMENT_TTL_HOURS |
24 |
Uploaded conversation files expire after this many hours. |
AGENT_ATTACHMENT_SECRET |
random at startup | Optional stable HMAC secret, at least 32 characters; read URLs last up to 15 minutes. |
AGENT_MAX_SEARCHES |
5 |
Search calls per turn, within the shared tool budget. |
SEARCH_PROVIDER |
— | Optional tavily, brave or searxng; incomplete settings disable search and research skills. |
SEARCH_API_KEY |
— | Required for Tavily and Brave. |
SEARCH_BASE_URL |
provider default | Optional API base override; required for SearXNG, with no default public instance. Private hosts follow the model opt-in rule. |
AGENT_BODY_LIMIT_BYTES |
2097152 |
Largest accepted JSON request. |
AGENT_RATE_LIMIT_PER_MINUTE |
300 |
Requests per client address per minute; 0 disables the limit. |
AGENT_ALLOW_PRIVATE_MODEL_HOSTS |
false |
Allow model servers on private networks. Ignored in production. |
See apps/agent/README.md for the full list, how to write a skill, and a smoke test against a real model.
The editor and templates are the same; the hosted product runs the AI for you and adds accounts, sync and interviews.
| Open source (this repository) | magic-resume.cn | |
|---|---|---|
| License | MIT | Free tier and paid plans |
| Account | Not required | Required |
| Resume storage | Your browser (IndexedDB) | Encrypted cloud storage, exportable at any time |
| Multi-device sync | — | Yes |
| AI | Polaris with your own model key, on the bundled agent | Managed models, mock interviews and memory |
| Templates | 20 | 20 |
A pnpm and Turborepo monorepo. The shared schema, templates, design system, icons, utilities and the MCP server are published from magic-resume-kit as @magic-resume-kit/* and pinned here by exact version.
| Path | Description |
|---|---|
apps/web |
The editor and Polaris (Next.js) |
apps/agent |
The agent behind Polaris (Fastify, DeepAgents, SQLite) |
apps/agent/skills |
Skills and the agent's standing instructions, as Markdown |
apps/landing |
Marketing site for magic-resume.cn (Astro) |
apps/docs |
Documentation site (Mintlify) |
packages/genui |
Polaris cards and widgets |
packages/tsconfig |
Shared TypeScript configuration |
pnpm dev # editor and agent
pnpm build # build every workspace
pnpm lint # lint and architecture checks
pnpm test # tests
pnpm --filter @magic-resume/agent test # one workspace| Area | Technology |
|---|---|
| Editor | Next.js 16, React 19, TypeScript, Tailwind CSS 4, Radix UI, Tiptap, Zustand, i18next |
| Documents | React-PDF, PDF.js, Zod schemas |
| Agent | DeepAgents, LangGraph, LangChain, Fastify, SQLite |
| Tooling | pnpm, Turborepo, ESLint, Docker |
@magic-resume-kit/mcp is a Model Context Protocol server that lets AI coding tools such as Claude Code, Codex and Cursor read and edit resumes through schema-aware JSON Patch. It connects to a magic-resume.cn account; the local editor in this repository has no account API for it to reach.
npx -y @magic-resume-kit/mcp@1.0.1 --help- Local-first editor with 20 templates
- Polaris on your own model key, with a self-hosted agent
- Resumable sessions, structured forms and approvals
- Import from PDF, Word, images and Markdown
- Attachments in conversations
- Optional web search with your own search API key, for company and role research
Ideas and requests are welcome in issues.
Contributions of every size are welcome: bug fixes, templates, skills, translations, docs and features. Read the contributing guide for local setup, the branch workflow and the commit convention (gitmoji with Conventional Commits). For anything non-trivial, open an issue first to agree on the approach.
MIT © 2026 Kenmet Team

