MCP Tools
Generate valid OTP/OJP documents from any input — resumes, job posting PDFs, plain English descriptions — using Claude and the ADNX MCP server. No manual JSON editing required.
The MCP server exposes 6 tools that handle parsing, validation, and introspection for both protocols. Claude orchestrates the full pipeline: extract structured data from unstructured input, fill the schema skeleton, validate against OTP/OJP v0.2, and optionally submit directly to the sandbox API.
Installation
Section titled “Installation”Claude Code
Section titled “Claude Code”Add the MCP server to your project:
claude mcp add open-talent-protocol -- npx @opentalentprotocol/mcp-serverClaude Desktop
Section titled “Claude Desktop”Add to your claude_desktop_config.json:
{ "mcpServers": { "open-talent-protocol": { "command": "npx", "args": ["@opentalentprotocol/mcp-server"] } }}Workflow
Section titled “Workflow”The tools are designed as a pipeline. Claude calls them in sequence:
1. PARSE Paste resume/job posting text into Claude → otp_parse_resume / ojp_parse_job_posting → Returns skeleton with _EXTRACT_* annotations + field confidence
2. FILL Claude fills the skeleton using its reasoning over the source text → Resolves annotations, normalizes dates/currencies/languages
3. VALIDATE → otp_validate_profile / ojp_validate_job_posting → Returns errors (if any) with exact field paths
4. FIX Claude fixes validation errors and re-validates
5. USE Copy the JSON, download it, or submit directly to the sandbox API → POST /api/v1/talent (OTP) or POST /api/v1/jobs (OJP)Three tools per protocol: parse (unstructured → structured), validate (check against schema), introspect (summarize for agents).
otp_parse_resume
Section titled “otp_parse_resume”Produces an OTP extraction template from raw resume text. Returns a document skeleton with
_EXTRACT_* annotations that Claude fills in, plus confidence levels and a list of gaps (info not typically found on resumes).
| Property | Type | Required | Description |
|---|---|---|---|
| text | string | yes | Raw resume text (plain text, markdown, or extracted PDF text) |
{ "skeleton": { "schema_version": "0.2.0", "otp_id": "_EXTRACT_UUID", "disclosure_tier": "profile", "name": { "given": "_EXTRACT_GIVEN_NAME", "family": "_EXTRACT_FAMILY_NAME" }, "title": "_EXTRACT_CURRENT_TITLE", "skills": "_EXTRACT_SKILLS_ARRAY" }, "fieldConfidence": [ { "field": "name", "confidence": "high" }, { "field": "salary_band", "confidence": "low" } ], "gaps": [ "salary_band — rarely on resumes, ask candidate", "availability — not typically stated", "consent_date — must be provided by submitting agent" ]}otp_validate_profile
Section titled “otp_validate_profile”Validates a JSON document against the OTP v0.2 schema. Returns validity status and field-level errors.
| Property | Type | Required | Description |
|---|---|---|---|
| document | object | no | A pre-parsed OTP document object |
| filePath | string | no | Absolute path to an OTP JSON file |
Provide either document or filePath.
{ "valid": true, "errors": [] }{ "valid": false, "errors": [ { "path": "/skills/0/level", "message": "must be integer between 1 and 5" }, { "path": "/location", "message": "must have required property 'country'" } ]}otp_introspect_profile
Section titled “otp_introspect_profile”Extracts a structured, agent-friendly summary from an OTP document. Returns normalized skills,
work history, preferences, and an agentSummary string suitable for use in a system prompt.
| Property | Type | Required | Description |
|---|---|---|---|
| document | object | no | A pre-parsed OTP document object |
| filePath | string | no | Absolute path to an OTP JSON file |
| sections | string[] | no | Filter: identity, summary, skills, work, preferences (default: all) |
ojp_parse_job_posting
Section titled “ojp_parse_job_posting”Produces an OJP extraction template from raw job posting text. Returns a document skeleton with
_EXTRACT_* annotations, field confidence levels, and a gaps list of information commonly missing from postings.
| Property | Type | Required | Description |
|---|---|---|---|
| text | string | yes | Raw job posting text (plain text, markdown, or extracted HTML) |
| sourceUrl | string | no | Source URL of the job posting, if known |
{ "skeleton": { "schema_version": "0.2.0", "ojp_id": "_EXTRACT_UUID", "status": "active", "title": "_EXTRACT_JOB_TITLE", "must_have": { "skills": "_EXTRACT_REQUIRED_SKILLS", "languages": "_EXTRACT_REQUIRED_LANGUAGES" } }, "fieldConfidence": [ { "field": "title", "confidence": "high" }, { "field": "salary_band", "confidence": "medium" } ], "gaps": [ "salary_band — not always disclosed in postings", "organization.size — rarely stated explicitly", "must_have.experience_years — often vague ('experienced')" ]}ojp_validate_job_posting
Section titled “ojp_validate_job_posting”Validates a JSON document against the OJP v0.2 schema. Returns validity status and field-level errors.
| Property | Type | Required | Description |
|---|---|---|---|
| document | object | no | A pre-parsed OJP document object |
| filePath | string | no | Absolute path to an OJP JSON file |
Provide either document or filePath.
{ "valid": true, "errors": [] }{ "valid": false, "errors": [ { "path": "/must_have/skills/0", "message": "must have required property 'name'" }, { "path": "/employment_type", "message": "must be one of: full_time, part_time, contract, freelance, internship, temporary" } ]}ojp_introspect_job_posting
Section titled “ojp_introspect_job_posting”Extracts a structured, agent-friendly summary from an OJP document. Returns normalized requirements,
compensation, location, team, process details, and an agentSummary string suitable for use in a system prompt.
| Property | Type | Required | Description |
|---|---|---|---|
| document | object | no | A pre-parsed OJP document object |
| filePath | string | no | Absolute path to an OJP JSON file |
Examples
Section titled “Examples”Copy-paste these prompts into Claude (with the MCP server installed) to generate valid documents.
Resume → OTP
Section titled “Resume → OTP”Paste a resume (text or PDF) and ask Claude to convert it:
Parse this resume into an OTP v0.2 profile, validate it, and show me the JSON:
Lena MullerSenior Backend Engineer | Berlin, Germany
Experience:- Senior Backend Engineer at Delivery Hero SE (Mar 2022 - present) Built high-throughput order processing pipeline in Go and Rust.
- Backend Engineer at Zalando SE (Jun 2018 - Feb 2022) PostgreSQL optimization, API gateway development.
Skills: Rust (5 years), Go (6 years), PostgreSQL (8 years)Languages: German (native), English (C1)Looking for: Remote/hybrid, 80-100k EUR, available in 2 weeksClaude will call otp_parse_resume → fill the skeleton → otp_validate_profile → return valid OTP v0.2 JSON.
Job posting → OJP
Section titled “Job posting → OJP”Describe a role in plain English or paste a job posting:
Convert this to OJP v0.2 and validate:
We're hiring a Senior Backend Engineer at Acme Corp (scale-up, Berlin).Hybrid, 85-110k EUR.
Must have:- Go (4+ years, advanced)- PostgreSQL (intermediate+)- 5+ years experience- English C1
Nice to have: Rust
Need work authorization for DE/AT/CH.Claude will call ojp_parse_job_posting → fill the skeleton → ojp_validate_job_posting → return valid OJP v0.2 JSON.
Generate → Submit to sandbox
Section titled “Generate → Submit to sandbox”Combine MCP tools with the sandbox API in a single prompt:
I have a sandbox API key: adnx_test_k1_a3f8e2b1c4d5
1. Parse the job posting below into OJP v0.22. Validate it3. Submit it to https://sandbox.adnx.ai/api/v1/jobs
[paste job posting text here]