Inspiration

I kept seeing resume tools that either rewrite everything behind your back or leave you hunting for keywords at 1 a.m. Neither felt honest. If an AI is going to touch something as personal as a resume, I want to see the before and after on the actual bullet — and I want a button that says no.

WebMCP clicked because the agent and I share the same page. It can read the job I pasted and the bullets already on screen, then propose a change. It cannot quietly replace my experience with something I never agreed to.

What it does

Upload a PDF or Word resume, paste a job posting. The agent can pull out the role and required skills, point out gaps, score ATS coverage, pull in a public GitHub or Medium profile, and suggest a rewritten bullet or a cover-letter opener.

Every suggestion shows up as a diff. I accept or reject it myself. Review and Export only include what I accepted.

I recorded the demo with ChatGPT desktop. It found the page tools, ran the flow, and the diffs showed up the way they should — that’s the video I’m uploading.

Live demo: https://resumematch-617103164879.us-central1.run.app

How I built it

Python on the server (FastAPI, Jinja2, SQLite). One small JavaScript file registers the WebMCP tools and updates the page. The real work stays in Python so I can sanitize and length-cap it.

Intake forms use WebMCP’s declarative form tools, without auto-submit. Analysis and rewrites use document.modelContext.registerTool(). Because the tools live on the page, ChatGPT desktop could drive them the same way Chrome’s inspector can — I didn’t have to build a custom ChatGPT plugin.

Only three tools call a model: analyze the job, propose a bullet rewrite, draft a cover opener. Gap finding and ATS scoring are plain skill matching:

$$\text{coverage} = \frac{|\text{JD skills} \cap \text{resume skills}|}{|\text{JD skills}|} \times 100$$

Original bullet text is never overwritten. A proposal sits as its own row until I accept it.

Running on Google Cloud Run. Session secret and the server Gemini key are in Secret Manager.

What I learned

The agent in the desktop app and the Gemini/Vertex key on the server are not the same job. ChatGPT picks which tool to call. Our server is what actually writes a proposal. That split is why the demo could look “agentic” without letting ChatGPT silently rewrite the resume.

Tools belong to the current page. Stay on Edit for matching and diffs. analyze_job_description taking {} is fine — the job text is already in the session.

Challenges

Session cookies once split so submit saved a job and analyze couldn’t see it. A prompt on the Upload page also looks like nothing works until you actually click Upload & Parse. I hit both while testing, including with ChatGPT desktop, and had to fix the session path and the copy on the page before the recording was worth keeping.

Cloud Run with SQLite wipes sessions on a new deploy, so I recorded against a stable revision. Job descriptions are still untrusted text I treat them as data and never commit a generation without a click.

Built With

Share this project:

Updates

Submission history