← Jordi Lluis / Projects

Relay

An evidence desk: four MCP tools and a React UI share one matcher so each skill hit is a quote, not a hiring score.

MCP · Python · FastAPI · React · TypeScript

The problem

An agent or a UI that cites a skill in a job text still needs the sentence it came from. I wanted that quote from one tested service, not a model deciding whether someone qualifies.

My contribution

I connected a React interface and MCP clients to the same Python review service. I implemented source normalization, token-aware matching, duplicate retention and portable exports. The MCP transport uses the official Python SDK. This is not a job-search product.

Skills this work used

Tools and what they did in this project
SkillWhere it was used
Python and FastAPIOne evidence service: normalize text, match tokens, keep duplicate wording.
MCPFour read-only tools that call the same matcher as the web UI. Official Python SDK.
React and TypeScriptPaste or sample-board review, quoted lines and export. No eligibility score.
Testspytest in CI for API validation, duplicate wording and MCP transports.

Try it step by step

  1. Paste a public job description, or load the sample Arbeitnow page to see the matcher work.
  2. Add a listing to the review queue. Enter the skills you want to look for.
  3. Select Review evidence. Read each matching quotation in its original context: a mention is not necessarily a requirement.
  4. Compare duplicate versions without discarding changed text.
  5. Export the review or workspace JSON. Saving on this device is optional; do not paste a CV or private correspondence.

What depends on what

Components, dependencies and responsibility
ComponentDepends onResponsibility
React interfaceFastAPI JSON endpointsSearch, review queue, quote display and export.
Public-board readerArbeitnow public APIA bounded latest-page snapshot, not a search of every employer.
Evidence serviceNormalized text, explicit aliases and content hashesSource quotations and duplicate versions; no LLM, eligibility score or application submission.
MCP toolsOfficial Python MCP SDK and the same evidence serviceThe browser workflow can also be called from an MCP client.
Review stateBrowser memory; optional device-local storage and JSON filesThe job service does not persist reviews in a database.
Historical safety labSeparate SQLite-backed fixture workflowAn older synthetic experiment, not the storage layer for job reviews.

How the data was organised

There is no job-review database on the public tool. Records live in the HTTP request and in the browser. SQLite belongs only to an older synthetic safety lab, not to these reviews.

Review records and where they live
RecordDepends onResponsibility
Job listingArbeitnow snapshot or pasted public textThe source description kept next to each mention.
ReviewChosen skills plus matched quotationsA working set in browser memory; saving on this device is optional.
Quoted evidenceNormalized text, aliases and a content hashKeeps original wording and duplicate versions; not an eligibility score.
Export fileJSON written by the visitorPortable copy. The job service does not persist reviews in PostgreSQL.

Implementation, step by step

  1. Define the job, review and quoted-evidence data models.
  2. Normalize input and validate URLs, sizes and fields before reviewing it.
  3. Match whole tokens and explicit aliases; keep all changed duplicate descriptions.
  4. Expose the same functions through HTTP and MCP instead of maintaining two implementations.
  5. Test API validation, source retention, transport behaviour and search regressions; then exercise the browser workflow.

Run the public code locally

# Backend (inside backend, with a Python virtual environment)
pip install -r requirements.txt
python -m pytest -q
python -m uvicorn app.main:app --host 127.0.0.1 --port 8000

# Frontend (inside frontend, in a second terminal)
npm ci
npm run dev

Use the repository README for environment setup and supported versions.

Limits and unfinished work

This is not a job-search product and not a recruiter ATS. Arbeitnow is a bounded demo snapshot; paste is the path a reviewer will actually use. Matching is literal, not semantic recall: ordinary English such as “react” or “go” can still hit. An agent that calls these tools can still summarise; Relay does not score eligibility or prove a vacancy is open.