Romanian Job Search MCP
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Romanian Job Search MCPsearch for python jobs in Bucuresti"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Romanian Job Search MCP
Cache-first MCP server for Romanian job search. The first provider is Jooble, with a database ledger so Hermes can search locally most of the time and spend Jooble API requests only when asked.
Design
search_logged_jobssearches the local DB only. It never calls Jooble.search_and_log_jooble_jobscan spend one Jooble API request, then upserts every returned job.start_job_search_sessionlets Hermes pass a Jooble key from the agent-owned.env.Raw API keys are not stored in the database. Request logs store only
key_idand a fingerprint.mark_job_intereststores interest/application state so the LLM does not need to remember.get_job_detail_schemadefines the stable structure Hermes should fill after researching a job page.populate_job_detailspersists that LLM-filled structured detail record.
Related MCP server: trackly-cli
Key Ownership
Recommended deployment: keep Jooble keys in the Hermes/agent .env, not in the MCP container/appdata. Hermes should read its fallback keys and pass the selected key as api_key when it calls start_job_search_session.
The MCP keeps that raw key only in process memory for the session. The database stores request counts with a key id/fingerprint, not the secret. Named MCP-side keys via JOOBLE_API_KEYS still exist as an optional mode, mainly for standalone testing or an MCP-owned scheduled worker.
MCP Tools
start_job_search_session(api_key, request_budget?)quota_status(session_id?, key_id?)search_logged_jobs(keywords?, location?, marked_status?)search_and_log_jooble_jobs(session_id, keywords, location?, radius?, salary?, page?, result_on_page?)get_logged_job(job_id?, source_job_id?, include_raw?)get_job_detail_schema()populate_job_details(job_id, details, extracted_by?)mark_job_interest(job_id, status, notes?)list_marked_jobs(status?)create_saved_search(...)refresh_saved_search(session_id, saved_search_id)
Hermes Usage Pattern
Start a session with a key from the Hermes
.env:{"api_key": "${JOOBLE_RO_PRIMARY}", "request_budget": 3}If the primary key hits quota, Hermes can start a new session with its fallback key.
Search locally first:
{"keywords": "python backend", "location": "Bucuresti"}Spend Jooble quota only if local results are missing or stale:
{ "session_id": "returned-session-id", "keywords": "python backend", "location": "Bucuresti", "result_on_page": 50 }Mark jobs instead of remembering them in the LLM context:
{"job_id": 1, "status": "interested", "notes": "Remote-friendly Python API role"}For deeper details, Hermes should inspect the public job page itself, then save a structured extraction:
{ "job_id": 1, "details": { "job_title": "Python Developer", "company_name": "Example SRL", "company_website": null, "location": "Bucuresti", "work_mode": "hybrid", "employment_type": "full_time", "seniority": "mid", "contract_type": "CIM", "salary_text": null, "salary_min": null, "salary_max": null, "salary_currency": null, "description": "Concise role description extracted from the public page.", "responsibilities": ["Build APIs", "Maintain integrations"], "requirements": ["Python", "REST APIs"], "nice_to_have": [], "benefits": [], "technologies": ["Python", "FastAPI"], "languages": ["English"], "application_url": "https://ro.jooble.org/jdp/...", "source_url": "https://ro.jooble.org/jdp/...", "contact": null, "evidence": { "work_mode": "Short supporting note or snippet" }, "missing_fields": ["salary_text"], "confidence": 82 }, "extracted_by": "hermes" }Use
get_job_detail_schemawhen Hermes needs the exact current field contract. Unknown fields are rejected; unknown values should benullor[]and listed inmissing_fields.
Local Development
py -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e ".[test]"
.\.venv\Scripts\python.exe -m pytest
.\.venv\Scripts\python.exe -m uvicorn ro_job_search_mcp.main:app --reloadThe default Docker Compose MCP endpoint is http://localhost:8012/mcp, and health is http://localhost:8012/health.
Docker Compose / Unraid
Copy
.env.exampleto.env.Do not put Jooble keys in this
.envwhen Hermes owns them.On Unraid, set
APPDATA_PATH=/mnt/user/appdata/ro-job-search-mcp.Start:
docker compose up -d --build
The MCP server listens on host port ${MCP_PORT:-8012} and container port 8000.
The worker service is behind the Docker Compose worker profile because it needs an MCP-side key. In the agent-owned key model, let Hermes call refresh_saved_search instead of running the worker.
Publishing Docker Images
GitHub Actions publishes the Docker image to GitHub Container Registry:
ghcr.io/ispas-catalin/ro-job-search-mcpPublish by pushing a version tag:
git tag v0.1.0
git push origin v0.1.0You can also run the Docker workflow manually from the GitHub Actions tab.
Jooble Quota Policy
Default limits are set for a 500-request key:
monthly hard limit:
500monthly soft warning:
430daily limit:
16default cache TTL:
12h
Cached searches do not spend quota. Forced refreshes and stale cache refreshes do.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Ispas-Catalin/ro-job-search-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server