save_conditions
Save desired conditions
All MCP toolsWrite
Update one person's desired conditions by SECTION MERGE — only the fields you pass change; absent fields keep their stored value; passing null for desiredOfficeFrequency or currentSalary clears that value. Narrowing desiredLocations also drops, in the same save, the desiredSalaries rows whose currency only the removed locations derived — value and all — while rows whose currency no previous location derived stay. Prefer this over update_candidate_profile for condition edits: no whole-document replace, no risk to unrelated sections. The desired conditions are five axes: desiredOccupations ({ id } references to occupation rows, resolved via search_occupations; a name riding along is not stored), desiredLocations (country / region codes), desiredSalaries (per-currency annual lower-bound rows), desiredOfficeFrequency (the accepted office-frequency range), and desiredEmploymentTypes (the employment forms accepted when moving jobs; at least one — [] is rejected, and selecting every form spells not limiting; not used for matching while mobility is not_looking). Resolve occupation phrases with search_occupations first and save a hit as { id } (name may ride along; it is not stored — reads return it in the person's language). A word the vocabulary does not know may be passed as { name } alone: an occupation row is created for it and its number stored (it joins other people's suggestions only after the nightly tidy). Occupations are counted by id. Read get_candidate_profile first and pass its version as expectedVersion. A person's conditions are theirs and service-global, so no organization's field settings gate what they may state. After saving, count_jobs_in_frame shows how many published postings fit the new conditions. An { id } that names no occupation row refuses the whole call (error reason occupation_unknown, details.ids naming the numbers) and nothing is saved — take ids only from search_occupations hits or from what a { name } element returned.
Input schema
{
"type": "object",
"properties": {
"personId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "The person whose conditions to update (persons.id — self)."
},
"expectedVersion": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991,
"description": "The version you loaded (get_candidate_profile.version) — a stale value refuses with a version conflict; re-read and retry."
},
"desiredOccupations": {
"description": "Desired-occupations replacement list: { id } references to occupation rows (a search_occupations hit's id; name may ride along and is not stored — reads return it in the person's language), or { name } alone for a word the vocabulary does not know — a row is created for it and its number stored. Unique by id. Absent = keep the stored list.",
"maxItems": 20,
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
"description": "The occupation's number (an `occupations` row) — the identity predicates count on."
},
"name": {
"description": "The row's display name in the reader's language, added when a read answers (trimmed, non-empty). Optional on a write and never stored — a stored reference carries the number alone.",
"type": "string",
"pattern": "^\\S(?:[\\s\\S]*\\S)?$"
}
},
"required": [
"id"
],
"additionalProperties": false,
"description": "Occupation reference: { id, name? } — the row's number, plus the display name a read adds in the reader's language (a write may carry one; it is not stored)."
},
{
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 256,
"pattern": "^\\S(?:[\\s\\S]*\\S)?$",
"description": "A word the vocabulary does not know, as typed (trimmed, non-empty): the tool creates its occupation row and stores its number."
}
},
"required": [
"name"
],
"additionalProperties": false,
"description": "A bare typed word: { name } without a number — becomes a row on save."
}
]
}
},
"desiredLocations": {
"description": "Non-empty desired-locations replacement list. Absent = keep the stored list.",
"minItems": 1,
"type": "array",
"items": {
"anyOf": [
{
"type": "string",
"pattern": "^[A-Z]{2}$",
"description": "ISO 3166-1 alpha-2 country code: exactly two uppercase letters, e.g. \"JP\". Three-letter codes (\"JPN\"), subdivision codes (\"JP-13\"), country names, and lowercase are rejected."
},
{
"type": "string",
"pattern": "^[A-Z]{2}-[A-Z0-9]{1,3}$",
"description": "ISO 3166-2 subdivision code: two uppercase letters, a hyphen, then 1-3 uppercase alphanumerics, e.g. \"JP-13\" (Tokyo). Country-only codes (\"JP\"), place names, and lowercase are rejected."
}
],
"description": "Desired-location entry: a whole country as an ISO 3166-1 alpha-2 code (e.g. \"US\") or one region as an ISO 3166-2 subdivision code (e.g. \"JP-13\"). Names, lowercase, and three-letter codes are rejected."
}
},
"desiredSalaries": {
"description": "Desired-salary per-currency annual lower-bound rows, replaced wholesale (compiled currencies: min/max must sit on the currency's step grid). Absent = keep the stored rows.",
"type": "array",
"items": {
"type": "object",
"properties": {
"currency": {
"type": "string",
"pattern": "^[A-Z]{3}$",
"description": "ISO 4217 currency code (exactly three uppercase letters). Required — no default."
},
"min": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991,
"description": "Desired annual lower bound in raw currency units (non-negative integer). Required — a row without a lower bound does not exist in the contract."
},
"max": {
"description": "Optional annual upper bound in raw currency units; the posting↔row match never reads it, while the shared internal candidate facet fold reads it as the row's upper bound. Must be >= min when present.",
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"unit": {
"default": "YEAR",
"description": "Salary period unit; rows are always annual (\"YEAR\").",
"type": "string",
"const": "YEAR"
}
},
"required": [
"currency",
"min"
],
"additionalProperties": false,
"description": "One per-currency desired-salary lower-bound row (annual): matching is strict against postings in this row's currency only — never converted, never compared across currencies."
}
},
"desiredOfficeFrequency": {
"description": "Desired office frequency. null = clear back to no condition; absent = keep the stored value.",
"anyOf": [
{
"type": "object",
"properties": {
"min": {
"type": "string",
"enum": [
"remote_only",
"office_monthly",
"office_1_2_days",
"office_3_4_days",
"office_daily_remote_ok",
"office_daily"
],
"description": "The most remote-leaning end of the accepted range (inclusive)."
},
"max": {
"type": "string",
"enum": [
"remote_only",
"office_monthly",
"office_1_2_days",
"office_3_4_days",
"office_daily_remote_ok",
"office_daily"
],
"description": "The most office-leaning end of the accepted range (inclusive)."
}
},
"required": [
"min",
"max"
],
"additionalProperties": false,
"description": "Desired office frequency: the accepted CONTIGUOUS range on the ordered 6-level office-frequency scale, given by its two ends — min = most remote-leaning, max = most office-leaning, both inclusive. Absent = no constraint on this axis."
},
{
"type": "null"
}
]
},
"desiredEmploymentTypes": {
"description": "Non-empty desired-employment-types replacement list over the shared vocabulary ([] is rejected — the axis always carries at least one form). Absent = keep the stored list.",
"minItems": 1,
"maxItems": 5,
"type": "array",
"items": {
"type": "string",
"enum": [
"FULL_TIME",
"PART_TIME",
"CONTRACTOR",
"TEMPORARY",
"INTERN"
],
"description": "Employment type (schema.org vocabulary): \"FULL_TIME\", \"PART_TIME\", \"CONTRACTOR\", \"TEMPORARY\", or \"INTERN\". Other values are rejected."
}
},
"currentSalary": {
"description": "Current annual salary. null = clear back to unset; absent = keep the stored value.",
"anyOf": [
{
"type": "object",
"properties": {
"currency": {
"default": "JPY",
"description": "ISO 4217 currency code (exactly three uppercase letters). Defaults to \"JPY\".",
"type": "string",
"pattern": "^[A-Z]{3}$"
},
"amount": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991,
"description": "Current annual salary as a non-negative integer in `currency`."
},
"provenance": {
"default": "provided",
"description": "How this claim entered the system: \"provided\" (self-reported, the default), \"observed\", or \"inferred\". Verification is orthogonal and lives in verification_annotations, never inside the profile.",
"type": "string",
"enum": [
"provided",
"observed",
"inferred"
]
}
},
"required": [
"amount"
],
"additionalProperties": false,
"description": "Current annual salary: a non-negative integer amount in an ISO 4217 currency."
},
{
"type": "null"
}
]
}
},
"required": [
"personId",
"expectedVersion"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}Output schema
{
"type": "object",
"properties": {
"personId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991,
"description": "The newly appended profile version."
}
},
"required": [
"personId",
"version"
],
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": false
}