Developers
Job search MCP server for AI apps
OfferHunt provides a hosted Model Context Protocol server over Streamable HTTP at https://www.offerhunt.ai/mcp. Connected assistants can search current employer job postings in the US and Canada and manage the connected user's job search.
Connecting for the first time? Follow the agent connection guide. Choose your AI's tab for setup: ChatGPT installs the published OfferHunt plugin, Claude adds the OfferHunt connector from its directory, Grok uses a custom connector, and Muse uses a prompt. All four connect to the same endpoint through OAuth. Availability depends on the app, plan, and workspace settings. The details below describe authentication, tools, and limits.
Authentication
The server supports OAuth 2.0 authorization with PKCE S256 and the offerhunt scope. Discovery metadata is available at /.well-known/oauth-protected-resource/mcp and /.well-known/oauth-authorization-server. Users sign in to OfferHunt and approve access on our consent page. All AI apps must connect through OAuth. For an account without a resume file or answered preferences, approving opens setup in a separate tab and returns the code and state to the registered redirect URI at once. If the browser cannot open that tab, setup happens first in the same window, so allow the authorization window to stay open for up to thirty minutes. Send the resulting access token as Authorization: Bearer <token>on MCP requests and use refresh tokens to renew access. Users can disconnect apps in account settings.
Clients can identify themselves using a Client ID Metadata Document or register at /oauth/register. Use the authorization-code flow with PKCE; a Google sign-in token is not an OfferHunt MCP access token. Access tokens last one hour. Refresh tokens last 30 days and rotate on use, so store the replacement returned by each refresh.
Verify the connection
Call get_profile after connecting. An account without a resume is a valid response; use save_resume and update_preferences to complete setup. Refresh an expired access token automatically. If the refresh token expires or access is revoked, reconnect through OAuth and approve access again.
Reliable connections and scheduled runs
Client implementers: serialize OAuth renewal per connection and atomically persist the replacement access and refresh credentials before releasing waiting requests. Scheduled workers must acquire the current credentials from the host's supported credential API on each run, not a saved bearer value. If the initial MCP initialize or tools/list check receives 401, use the host's supported renewal/reacquisition API, wait 10 seconds, and retry that check once with newly acquired credentials. Do not implement a second OAuth store alongside a managed host. A persistent 401 requires connection attention; 403 requires a permission check, not a renewal loop. For 503, preserve the connection, respect Retry-After, and allow at most one retry of that initial check within the run's time budget; otherwise report temporary unavailability. Never automatically retry tool mutations or employer submissions. One run has one recovery retry in total, including failures during recovery; do not reset the budget when the error changes. Verify with synthetic accounts across two access-expiry/renewal cycles and a real next-day scheduled run before claiming scheduled renewal works. Documentation updates do not update existing host clients or saved tasks.
A successful check immediately after setup does not verify renewal. Test expired access, a rejected first check followed by success, persistent rejection, temporary service failure, and revoked access. Verify that revoked access stays blocked and that no application or profile change is repeated. Record the client version, time zone, next scheduled run, and observed outcomes without logging credentials or private user data.
Routine messages should say "Your OfferHunt connection needs attention" and request reconnection only after supported recovery cannot restore access. For a temporary outage, say "OfferHunt is temporarily unavailable. I couldn't finish this job check." Do not disable an existing schedule merely because one run encountered a temporary outage.
Tools
get_profile— Read the user's job-search profile and preferences.save_resume— Save a resume file, request an upload link, fall back to text, or retry processing.update_preferences— Update job-search preferences.get_recommendations— Get the user's personalized job matches with fit reasons and concerns, a page at a time; next_cursor reads further down the list.search_jobs— Search current US and Canada job postings.get_job— Read details for a job returned by OfferHunt.rate_job— Save, dismiss, or clear feedback on a job.claim_application— Claim a job with a stored resume file before a browser application, so no other agent applies at the same time.prepare_application_submission— Final check right before submitting: pause state, authorization, the claim and duplicate submissions.track_application— Record a confirmed application and later progress with evidence, including applications made elsewhere.mark_application_uncertain— Mark a submission whose outcome is unknown so it is verified before any retry.mark_application_blocked— Record a CAPTCHA, login or unanswered question that stopped one application.release_application_claim— Free an attempt after the user confirms nothing was submitted.list_my_jobs— List saved jobs and tracked applications.update_profile— Correct facts extracted from your resume.delete_resume— Delete a resume and its private file; a current resume also removes its derived profile.
Search by radius
Call search_jobs with location: "San Francisco, CA" and radius_miles: 100. To save it, call update_preferences with locations: ["San Francisco, CA"], radius_miles: 100. Later searches without a location or radius, and daily recommendations, use that preference. A new location replaces the saved area for a search; radius_miles: null clears its radius. Without a radius, city searches match only that city. Pass a state or province explicitly to search its entire area.
Radii range from 1 to 500 miles and measure straight-line distance between city centers, not driving distance. A posting qualifies if any listed office is in range; unknown city coordinates are excluded. Country eligibility still applies. Remote roles are included separately when remote work is explicitly requested in the search or saved preferences, and have no distance.
Access and limits
A free personal account is required. Search results are capped at 10 jobs per page and 3 pages per query. Recommendations return the user's matches a page at a time: limit takes 1 to 20 and defaults to 10. The first page holds only strong matches, so it can be shorter. more_matches counts the rest of the list, and next_cursor reads its next page, down to weaker matches, in the order the user's Recommended page shows them. A cursor stops working once preferences change or a first page ranks the list again; it then returns list_changed. Repeating the first-page request the same day returns the same strong matches first. Broad requests to list the entire catalog are refused. Search, including searches by company, reveals up to 100 distinct new jobs per day; re-reading a job already returned that day does not use another new-job slot. Recommendations, job details and the user's own records do not count toward it.
Process 2 new resume contents per day and 10 per rolling 30 days; identical content can reuse results. The daily discovery and resume-processing allowances reset at midnight Pacific time. The 30-day resume allowance rolls forward as older usage expires. Your account page shows current usage.
Reading saved jobs and applications with list_my_jobs does not use the daily catalog allowance. Tool calls are also limited to 30 per minute, 300 per hour and 1000 per day, with capacity reserved for personal records. Respect the returned reset_at and retry_after values for request limits.
Resumes and preferences
The connector returns structured data. Your agent presents it in conversation. Save the original English PDF/DOCX resume up to 4 MB. Hosts without file transfer call save_resume with no input for a one-use upload link that lasts 24 hours; an agent that can read the file itself may post it to the returned direct_upload endpoint. Use resume_text only when the user has no file: text supports matching, not applications, and the response asks for the file. Users can also upload on their account page. Authorized agents can retrieve stored files through private links that expire after ten minutes and stop working on deletion or connection revocation.
Preferences distinguish resume facts from user intent: target roles and categories, accepted levels, locations/radius, work_modes, annual salary currency and base/total-compensation basis, sponsorship and employers. Recommendations return needs_preferences with questions until target roles, locations, work_modes, levels, salary and work authorization are answered; record an explicit “no preference” with no_preference. Users can also answer on their account page (answer_on_website); it writes the same record, so read get_profile rather than asking again. Only strong matches are returned, so a list can be shorter than 10. Unknown requirements never imply eligibility. AI reranking degrades to rules when its budget is used; resume parsing can queue.
Daily job searches
The AI app runs scheduled tasks; connecting OfferHunt does not create one. Follow the daily setup guide, confirm the time, time zone, and saved task's next run, then check its first completed run. The landing-page daily prompt requests up to 10 matches; it does not authorize applications.
For a scheduled run that only retrieves matches, call get_recommendations directly. It reads the latest saved matching context, checks pause state, and returns the preferences used. A separate get_profile call is needed only when the agent needs additional profile details, resume status, or files.
Read current preferences and pause state on each run. Pause through update_preferences with search_status: "paused". Pausing, or recording an accepted offer, stops new recommendations and blocks the application submission checks; existing application tracking can continue. Disable the schedule separately in the AI app.
Agent-assisted applications
An authorized agent with browser actions can apply to the jobs the user selects, including a whole shortlist. OfferHunt supplies job data, resume files, and coordination tools; the agent operates the employer's site. Connecting the MCP server does not provide browser or mailbox access. Without browser actions, prepare answers and return each job's apply_link.
Job cards carry apply_url, the employer's posting, and apply_link, an OfferHunt link made for the user and the job. Show apply_link when the user will apply themselves: it opens the application form, and in desktop Chrome it can first offer the OfferHunt Chrome extension, which fills the form for the user to check and submit. Use apply_url when the agent applies in its own browser.
- Check user authorization, the agent's daily application cap, and existing records. Select a stored PDF/DOCX resume from
get_profile. - Call
claim_applicationwith the returnedjob_id, the selectedresume_id, andauthorization_confirmed: truebefore filling the form. Keep the returnedclaim_tokenprivate; ask the user for missing answers. - After the user reviews and approves the prepared application, call
prepare_application_submissionwith theapplication_id,claim_token, and renewedauthorization_confirmed: true. Submit once only ifcan_submitis true and beforesubmit_before; the submission window is 60 seconds. - Record
status: "applied"withtrack_application, the original resume ID, and evidence only after confirmation. For unclear outcomes, callmark_application_uncertainand verify before retrying. Usemark_application_blockedfor a login, CAPTCHA, or unanswered question, andrelease_application_claimonly after the user confirms nothing was submitted.
Application stages are applied, screening, interview, offer, accepted, ended, and withdrawn, with interview details, next action, and history. Email-based updates require separate mailbox access in the agent; OfferHunt itself does not read email.
See our privacy policy and support page for data handling and help.