An MCP tool-calling schema for job applying is a JSON Schema definition attached to each function (like search_jobs, submit_application, or get_application_status) that tells an AI model exactly what inputs a tool accepts, what it returns, and what constraints govern it. The model never touches your resume file or a browser DOM directly. It reads the schema, decides which tool to call, fills in arguments that validate against that schema, and the MCP server executes the real work.
If you've used function calling in the OpenAI or Anthropic APIs, this will feel familiar. MCP (Model Context Protocol) just standardizes that pattern across servers, so any client (Claude Desktop, ChatGPT desktop, a custom agent) can discover and call the same tools without custom glue code for each one. That standardization is the whole point, and it's also where things get interesting for anyone building or auditing a job-search agent.
Most people evaluating an MCP job agent ask "does it work?" The better question, especially if you write code for a living, is "what can it actually do, and what stops it from doing something dumb?" The answer lives entirely in the schema. Let's open it up.
What does an MCP tool definition actually look like?
Every MCP tool is a JSON object with four parts: a name, a description the model reads to decide when to use it, an inputSchema written in JSON Schema, and an implicit output contract (MCP doesn't formally type outputs the way it types inputs, but well-built servers document the return shape in the description anyway). Here's a stripped-down but realistic version of what a job-search tool looks like:
{
"name": "search_jobs",
"description": "Search live job postings by title, location, and posting recency. Use this before submit_application.",
"inputSchema": {
"type": "object",
"properties": {
"title_keywords": { "type": "array", "items": { "type": "string" } },
"location": { "type": "string" },
"remote_ok": { "type": "boolean" },
"posted_within_hours": { "type": "integer", "minimum": 1, "maximum": 168 },
"employment_type": { "type": "string", "enum": ["full_time", "contract", "c2c"] }
},
"required": ["title_keywords"]
}
}
Notice the constraints: enum on employment type, minimum/maximum on the recency window. Those aren't decoration. They're the fence that keeps a language model from inventing a value it shouldn't, like a made-up job board or an out-of-range date filter. The model can only pass what the schema allows, and the server validates before executing anything.
In plain terms: the schema is a contract. The model proposes arguments, the server checks them against the contract, and only valid calls run.
How does the job-search tool schema differ from the submit-application tool schema?
This is where most explainers stop too early. Searching and applying are not the same risk category, and their schemas should not look the same.
A search_jobs call is read-only. Worst case, the model queries badly and you get irrelevant results. A submit_application call is a write action with real-world consequences: your name goes on a recruiter's desk, sometimes with a cover letter the model generated in the last few seconds. That asymmetry should show up directly in the schema design.
| Aspect | search_jobs schema | submit_application schema |
|---|---|---|
| Risk level | Read-only, reversible | Write action, often irreversible |
| Required fields | Loose (keywords optional in some servers) | Strict (job_id, resume_version_id, consent_token typically required) |
| Enum constraints | Light (sort order, employment type) | Heavy (application_channel, cover_letter_source) |
| Confidence gating | Not applicable | Often tied to a confidence score before auto-submit |
| Human-in-the-loop hook | Rarely needed | Common: requires_confirmation: true flag |
A well-designed submit_application schema usually includes a consent_token or session-scoped permission field, because a responsible server should never let a model fire off an application purely on its own initiative. If you want the deeper mechanics of how that gating decision gets made, see our breakdown of the MCP job agent confidence score, which determines whether the agent auto-applies or stops to ask you first.
Short version: search tools are loose because they're safe. Apply tools are strict because a bad call costs you a real application.
How does the AI model decide which tool to call and when?
The model doesn't have special knowledge of your job server's internals. It only sees the tool list (names plus descriptions plus schemas) at the start of a conversation or session, exactly like a menu. Given a user instruction like "find me remote backend contract roles posted this week," the model matches that intent against tool descriptions, picks search_jobs, and constructs a JSON payload that satisfies the inputSchema.
This matters because description quality is doing real work here, not just the schema shape. Two tools with identical parameters but vague descriptions will get called incorrectly far more often than tools with sharp, example-driven descriptions. This is a prompt-engineering problem disguised as a schema problem, and it's why serious MCP servers write descriptions like documentation, not like comments.
- Client connects to the MCP server and requests the tool list.
- Server returns tool definitions including names, descriptions, and input schemas.
- Model reads the user's request and matches intent to the closest tool description.
- Model drafts a JSON payload that it believes satisfies the tool's
inputSchema. - Client validates the payload against the schema before sending it anywhere.
- Server executes the underlying action (a search query, a form fill, a submission) only after validation passes.
- Server returns a structured result the model can read and summarize back to the user.
In short: schemas don't just constrain arguments, they steer which tool gets picked in the first place.
What fields should a job-apply tool schema include to be safe?
If you're building or auditing an MCP job server, here's the field list that separates a careful implementation from a reckless one:
- job_id (string, required): ties the call to a specific, already-fetched posting, not a freeform description the model could hallucinate.
- resume_version_id (string, required): points to a resume you've explicitly approved, not a document the model generates on the fly.
- cover_letter_source (enum:
user_provided,ai_generated,none): forces transparency about who wrote the words attached to your name. - employment_type (enum): especially important for the C2C market, where a mismatch between contract type and application channel wastes both your time and the recruiter's.
- confidence_threshold (number, optional): lets the client refuse to auto-submit below a set score, deferring to you instead.
- requires_confirmation (boolean): the single most important safety field in the whole schema, because it's the one that can force a pause before a write action fires.
Compare that against a naive schema that just takes { "job_url": "string", "resume_text": "string" } and fires. That version works in a demo. It falls apart the moment the model misreads a job URL or the resume text drifts from what you actually approved. The strict version costs a little more engineering effort and prevents the exact failure mode that makes people distrust auto-apply agents.
Plain summary: a safe schema forces the model to reference things you already approved, instead of letting it invent them.
How does GiraffyReach implement this in practice?
GiraffyReach's MCP server, part of what we call MCP Agent Connect, follows the strict-schema pattern above: search tools are loose, apply tools are gated behind confidence scoring and resume-version references, and every submission carries a data trail back to a specific job posting and a specific approved resume. That's what lets an assistant like Claude or ChatGPT desktop apply on your behalf the moment a posting goes live, without you waking up to a mystery application you never reviewed.
If you want the setup walkthrough rather than the internals, we cover that in how to connect ChatGPT desktop to GiraffyReach's MCP server. And if you're comparing MCP-compatible agents before committing to one, our head-to-head on GiraffyReach vs Simplify.jobs for software engineering roles breaks down schema-level differences that matter more than the marketing copy suggests.
The broader lesson: speed is the whole value proposition of an MCP job agent, since postings get buried under a wave of applicants within hours. But speed without a well-fenced schema is just a fast way to submit mistakes. The schema is what lets an agent move first and still be trusted to move correctly. Be first, or be forgotten, works only if "first" is also right.