{
  "markdown": "# ResuStack\n\n**ResuStack** is an AI resume builder. Import a PDF or your LinkedIn profile, pick one of 14 designs, and edit by form or by chat — in the browser, or straight from Claude through its MCP server. Every change is reversible, and the PDF you download is rendered from the same template as the live preview.\n\n🔗 **Live:** [resustackapp.com](https://resustackapp.com)\n\n---\n\n## ✨ Features\n\n### Resume builder\n- **PDF & LinkedIn import** — upload an existing resume or a LinkedIn PDF; AI extracts and structures it\n- **Split-pane editor** — the form on the left, a live preview on the right, with page breaks where the PDF will break\n- **14 designs on 6 layouts** — single column, banner, label gutter, header grid, left sidebar and right rail; ATS-safe designs are marked, and switching keeps your content\n- **English and Turkish resumes** — headings, \"Present\", month names and degree phrasing print in the language the resume is written in\n- **\"What I'm working on\"** — an optional section above Education, shown only when you tick it\n- **Sign in with Google** — or with a username and password; email sign-ups confirm their address before using the AI features\n- **PDF export** — rendered with WeasyPrint from the same template the preview uses\n\n### AI\n- **One-click enhance** — rewrites experience and project descriptions into stronger bullet points\n- **Analyze and compare** — score a resume and see where it is weak, or compare two versions\n- **Guided build** — build a resume step by step through questions\n\n### Agentic mode\n- **Edit by chatting** — *\"Make my last role sound more senior\"*; the agent uses tools, streams its progress and asks for approval before destructive actions\n- **Template pane** — pick a design for the active resume without leaving the chat\n- **Undo** — revert the last change from the conversation\n\n### Change history\n- A restore point before every save and every AI or MCP edit\n- Diff any version against the current one, and restore it — on every plan\n\n### Job applications\n- **Match** a resume against a job posting and **tailor** a version for it\n- **Track** applications, each with a snapshot of the exact resume you sent; clone a snapshot back into an editable resume\n\n### Language versions\n- Translate a resume in place, or create a translated copy linked to the original\n\n---\n\n## 🤖 Use ResuStack from Claude (MCP)\n\nResuStack is a [Model Context Protocol](https://modelcontextprotocol.io) server. Claude — or any MCP client with Streamable HTTP and custom headers — writes the resume; ResuStack stores it, versions it and renders it.\n\n**1. Create a token.** Sign in, open **Profile → API token**, and create one. It is shown once; replacing it revokes the old one. The Profile page also shows the endpoint address to use.\n\n**2. Add the server.** With Claude Code:\n\n```bash\nclaude mcp add --transport http resustack https://resustackapp.com/mcp --header \"Authorization: Bearer YOUR_TOKEN\"\n```\n\nAuthentication is a bearer token only; session cookies are not accepted on this endpoint.\n\n**3. Ask.** *\"List my resumes\"*, *\"Switch my CV to the Label Gutter design and give me the PDF\"*, *\"Fill What I'm working on from what we did this month.\"*\n\n### Tools\n\n| Tool | What it does |\n|---|---|\n| `list_resumes` | Resumes on the account: id, title, language, template |\n| `get_resume` | The full stored content of one resume |\n| `create_resume` | Create a resume from structured content |\n| `update_resume` | Replace a resume's content (read it first — this is a replace, not a merge) |\n| `set_focus_areas` | Set only the \"What I'm working on\" section; the rest of the resume is untouched |\n| `list_templates` | The designs, with a description and whether each is ATS-safe |\n| `set_template` | Change a resume's design |\n| `render_pdf` | A download link for the PDF — single use, expires in 10 minutes |\n| `check_quota` | What the account has left this month |\n\n### Prompts\n\n| Prompt | What it does |\n|---|---|\n| `focus_areas_from_my_work` | Has the client's model summarise the work you have actually done — from the conversations it can see — into a few lines, show them to you, and save them with `set_focus_areas` only after you approve |\n\n### Safety rules\n- Every write takes a restore point first; you can undo it on the website\n- There is no delete tool — removing a resume stays on the website, where a person clicks\n- Every query is scoped to the token's owner\n- Rate limited per account\n\n### Listing in the MCP Registry\n\n`server.json` at the repository root describes the server for the [official MCP Registry](https://modelcontextprotocol.io/registry/about) as `com.resustackapp/resustack`. Publishing under that name requires proving ownership of `resustackapp.com` with a file served at `/.well-known/mcp-registry-auth`:\n\n1. Generate a key pair locally. Never commit `key.pem` (it is in `.gitignore`):\n\n   ```bash\n   openssl genpkey -algorithm Ed25519 -out key.pem\n   ```\n\n2. Print the proof record and set it as the `MCP_REGISTRY_AUTH` environment variable in Dokploy, then redeploy:\n\n   ```bash\n   echo \"v=MCPv1; k=ed25519; p=$(openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64)\"\n   ```\n\n3. Check it is live:\n\n   ```bash\n   curl https://resustackapp.com/.well-known/mcp-registry-auth\n   ```\n\n4. Log in and publish from the repository root:\n\n   ```bash\n   mcp-publisher login http --domain resustackapp.com --private-key \"$(openssl pkey -in key.pem -noout -text | grep -A3 'priv:' | tail -n +2 | tr -d ' :\\n')\"\n   ```\n\n   ```bash\n   mcp-publisher publish\n   ```\n\nBump `version` in `server.json` (and `SERVER_INFO` in `mcp_server/protocol.py`) for each new listing.\n\n---\n\n## 📸 Screenshots\n\n### Editor — form, live preview and the template pane\n![Resume editor](screenshots/editor.png)\n\n### Choosing a design\n![Template pane](screenshots/templates.png)\n\n### Agentic mode\n![Agentic mode](screenshots/agentic.png)\n\n### Dashboard\n![Dashboard](screenshots/dashboard.png)\n\n---\n\n## 💳 Plans\n\nFree to start. Pro is a **one-time purchase for a period** — no subscription.\n\n| Free plan | Limit |\n|---|---|\n| Resumes | 3 |\n| PDF or LinkedIn imports | 2 / month |\n| AI enhancements | 10 / month |\n| PDF downloads | 5 / month |\n| Agent chat messages | 10 / month |\n| Tracked applications | 3 |\n| Restore points per resume | 5 |\n\nPro removes these limits. Current prices are on the [pricing page](https://resustackapp.com/pricing/). Limits live in `FREE_TIER_LIMITS` in `core/settings.py`.\n\n---\n\n## 🚀 Running locally\n\n### Prerequisites\n- Docker & Docker Compose\n- An OpenAI API key\n\n### 1. Clone and configure\n\n```bash\ngit clone https://github.com/koksalkapucuoglu/resume-enhance.git\n```\n\n```bash\ncd resume-enhance && cp .env.example .env\n```\n\n| Variable | Description | Example |\n|---|---|---|\n| `OPENAI_API_KEY` | OpenAI API key | `sk-proj-...` |\n| `SECRET_KEY` | Django secret key | any long random string |\n| `DEBUG` | Debug mode | `True` |\n| `ALLOWED_HOSTS` | Allowed hosts | `localhost,127.0.0.1` |\n| `POSTGRES_DB` / `POSTGRES_USER` / `POSTGRES_PASSWORD` | Database credentials | `postgres` |\n| `POSTGRES_HOST` / `POSTGRES_PORT` | Database address | `db` / `5432` |\n| `EMAIL_HOST_USER` / `EMAIL_HOST_PASSWORD` | SMTP credentials for password resets and email verification; for Gmail, an app password | `you@gmail.com` / app password |\n| `EMAIL_HOST` / `EMAIL_PORT` / `EMAIL_USE_TLS` / `EMAIL_USE_SSL` | SMTP server; defaults to Gmail (`smtp.gmail.com`, `587`, TLS). For implicit TLS on 465, set `EMAIL_USE_SSL=True` | `smtp.gmail.com` / `587` / `True` / `False` |\n| `DOWNLOAD_LINK_MAX_AGE` | Seconds a signed PDF link stays valid (optional) | `600` |\n| `GOOGLE_OAUTH_CLIENT_ID` / `GOOGLE_OAUTH_CLIENT_SECRET` | Google sign-in; the button stays hidden until both are set (optional) | from Google Cloud Console |\n| `DEFAULT_FROM_EMAIL` | Sender for account emails; defaults to `EMAIL_HOST_USER` (optional) | `ResuStack <you@gmail.com>` |\n| `MCP_REGISTRY_AUTH` | MCP Registry domain proof served at `/.well-known/mcp-registry-auth` (optional, public key only) | `v=MCPv1; k=ed25519; p=...` |\n| `PAYMENT_STATUS` | `coming_soon` shows plans without taking payment; `live` enables checkout | `coming_soon` |\n| `PAYMENT_PROVIDER`, `PAYMENT_WEBHOOK_SECRET`, `CHECKOUT_URL_*`, `PRODUCT_ID_*` | Payment provider settings (optional) | |\n\n### 2. Start\n\n```bash\ndocker compose up --build\n```\n\nThe app runs at [http://localhost:8000](http://localhost:8000).\n\n### 3. Run the tests\n\n```bash\ndocker compose exec web python manage.py test resume mcp_server\n```\n\nWeasyPrint and OpenAI are mocked in the unit tests; no API calls are made.\n\n---\n\n## ☁️ Deployment\n\nProduction runs on **[Dokploy](https://dokploy.com)**. Every push to `main` triggers a deploy through a GitHub webhook: Dokploy builds the `Dockerfile`, and `entrypoint.sh` runs `migrate` and `collectstatic` before starting Gunicorn. Traefik handles HTTPS.\n\nSetting it up on a new server:\n1. Install Dokploy: `curl -sSL https://dokploy.com/install.sh | sh`\n2. Open `http://YOUR_SERVER_IP:3000` and create an admin account\n3. Create a project → add an **Application** → connect this GitHub repository\n4. Add a **PostgreSQL** service in the same project\n5. Set the environment variables (see `.env.prod.example`) and the domain, then deploy\n\nNotes:\n- Leave Dokploy's **Run Command** empty — the Dockerfile's `ENTRYPOINT` does everything\n- Behind Cloudflare's proxy, set Dokploy's domain encryption to **None** and Cloudflare SSL to **Full**\n- The image installs the fonts the resume designs use; nothing is fetched at render time\n\n`docker-compose.prod.yml` and the `Caddyfile` are kept for self-hosting without Dokploy; they are not what production uses.\n\n---\n\n## 🔑 Google sign-in\n\nSign-in with Google uses [django-allauth](https://docs.allauth.org). ResuStack's own login, sign-up and password pages stay in charge; allauth adds only the Google flow.\n\n1. In [Google Cloud Console](https://console.cloud.google.com/apis/credentials), configure the **OAuth consent screen** (External), with the privacy policy URL `https://resustackapp.com/privacy/` and only the `openid`, `email` and `profile` scopes.\n2. Create an **OAuth client ID** of type *Web application* with:\n   - Authorized JavaScript origin: `https://resustackapp.com`\n   - Authorized redirect URI: `https://resustackapp.com/accounts/google/login/callback/`\n   - For local development, also `http://localhost:8000/accounts/google/login/callback/`\n3. Set `GOOGLE_OAUTH_CLIENT_ID` and `GOOGLE_OAUTH_CLIENT_SECRET` and redeploy.\n\nHow it behaves:\n- A Google account is never attached to an existing ResuStack account because the email matches — local addresses were never verified. Existing users connect Google from their Profile page while signed in.\n- New Google users pass through a short step to pick a username and give consent to transfers abroad.\n- Google accounts with an unverified email are refused.\n- Accounts created with an email address work at once, but AI features stay locked until the address is confirmed (soft verification). Accounts created before this existed are not affected.\n\n---\n\n## 🔒 Privacy\n\nWhat ResuStack collects, who processes it (including OpenAI for AI features) and how to delete it: [resustackapp.com/privacy](https://resustackapp.com/privacy/). The Turkish version, written as the KVKK information notice, is at [resustackapp.com/gizlilik](https://resustackapp.com/gizlilik/). Users can delete their account and all its data from the Profile page.\n\n---\n\n## 🏗️ Architecture\n\nMonolithic Django: views, DRF API, an MCP endpoint, WeasyPrint for PDFs, OpenAI for parsing and writing. Resume content is a single `JSONField`; every design comes from one catalogue in `resume/resume_templates.py`. The full guide — conventions, patterns and pitfalls — is in [`.claude/CLAUDE.md`](.claude/CLAUDE.md).\n\n---\n\n## 🗺️ Roadmap\n\n- [x] Multiple resume designs (14)\n- [x] Job description matching and application tracking\n- [x] Agentic mode with tool calling, approvals and undo\n- [x] Change history with diff and restore\n- [x] MCP server for Claude and other clients\n- [x] English and Turkish resumes\n- [ ] Listing in MCP registries\n- [ ] OAuth for MCP clients, alongside tokens\n- [ ] Payments going live\n\n---\n\n## License\n\nOpen Source.\n",
  "bytes": 12224,
  "sha": "049bb2b6cefdc26881e8569eaa2a066f2f672fa7ef56e47937aa8b17be7b5e86",
  "repo_slug": "koksalkapucuoglu/resume-enhance",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_com_resustackapp_resustack_34c72450/readme"
}