Skip to main content
Glama

FoundRole — AI Job Search & Application Tracker MCP for Claude & ChatGPT

Save a job from another site to the tracker

tracker_add_external
Idempotent

Saves a job posting found anywhere on the open web into the user's tracker. For jobs that came from jobs_search results, tracker_add (which takes a job_id) is the right tool instead. A job seen elsewhere in the conversation needs no prior jobs_search call — its URL and details from the conversation are sufficient input.

url, company_name, title_name, location_name, and description identify the posting and are the only required fields. Every structured fact field (salary, dates, employment type, education, experience) is optional: a fact the source does not state is simply omitted (or null), and FoundRole's own extractors derive missing salary, employment, work-arrangement, education, experience, skills, benefits, and bonuses from the description. A save never waits on facts the source did not provide. The optional client_extraction object carries evidence-backed skills, technology, benefits, bonuses, seniority, industry, management, clearance, visa, and remote-scope labels when source excerpts for them exist; FoundRole validates and stores those labels separately.

Fields:

  • url: the job posting's direct URL (required; not a company homepage)

  • company_name: company name (required)

  • title_name: job title (required)

  • location_name: location, e.g. "New York, NY" (required)

  • description: the posting's description from the source result; a short summary is acceptable (required)

  • salary_min_value / salary_max_value: salary range bounds (numbers)

  • salary_value: a single salary figure when there is no range (number)

  • posted_at: ISO 8601 posting date

  • salary_currency: ISO 4217 currency code

  • salary_type: one of year, month, week, day, hour

  • employment_type: array of full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other

  • work_location_type: one of on_site, remote, hybrid

  • education_requirements: array of no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree

  • experience_months: minimum required experience in months (number)

  • client_extraction: evidence-backed extraction object; fields without source evidence are omitted

  • status: initial tracking status (saved, applied, interviewing, offered, archived); defaults to "saved"

  • sub_status: sub-status within the main status: saved: interested, researching_company, preparing_application, ready_to_apply; applied: application_submitted, followed_up; interviewing: interview_scheduled, phone_screen, technical, onsite, final_round, pending_feedback; offered: negotiating, considering, offer_received, accepted; archived: ghosted, rejected_by_company, withdrawn_by_candidate, not_interested, employed_by_this_company, employed_by_another_company

  • notes: notes about the job

Returns the tracked job. Repeated saves return the existing tracked job.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "url": "<url>",
      "company_name": "<company_name>",
      "title_name": "<title_name>",
      "location_name": "<location_name>",
      "description": "<description>"
    },
    "name": "tracker_add_external"
  }
}

Input Schema

NameRequiredDescriptionDefault
urlYesDirect URL of the specific job posting; a company homepage is invalid
notesNoNotes about this job
statusNoInitial tracking status: saved, applied, interviewing, offered, archived
posted_atNoPosting date as ISO 8601, when the source states it
sub_statusNoSub-status within the main status, valid only for that status — saved: interested, researching_company, preparing_application, ready_to_apply; applied: application_submitted, followed_up; interviewing: interview_scheduled, phone_screen, technical, onsite, final_round, pending_feedback; offered: negotiating, considering, offer_received, accepted; archived: ghosted, rejected_by_company, withdrawn_by_candidate, not_interested, employed_by_this_company, employed_by_another_company
title_nameYesJob title from the posting
descriptionYesComplete posting text available in the conversation; a source summary is valid only when no fuller posting text is available
salary_typeNoSalary period: year, month, week, day, hour
company_nameYesCompany name from the posting
salary_valueNoSingle salary amount, when the posting gives one figure instead of a range
location_nameYesLocation text from the posting, including Remote when stated
employment_typeNoEmployment types: full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other
salary_currencyNoISO 4217 salary currency code, when stated
salary_max_valueNoSalary range maximum, when stated
salary_min_valueNoSalary range minimum, when stated
client_extractionNoEvidence-backed facts extracted by the client model from the posting; non-null evidence is a short source excerpt rather than an inference. Fields absent from the source are omitted or null.
experience_monthsNoMinimum required experience in months, when stated
work_location_typeNoWork arrangement: on_site, remote, hybrid
education_requirementsNoEducation requirements: no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree

Output Schema

NameRequiredDescriptionDefault
hasMoreNo
totalCountNo
trackedJobNo
statusOrderNo
trackedJobsNo
figureSourcesNo
trackerWebUrlNo
subStatusOrderNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changed
    • addedOutput schema / properties / trackedJob / properties / appliedDateUnknown
      Added value: +{
      +  "description": "True for a job at the applied status with no stored applied date, unless the person said they do not remember it. FoundRole never fills that date in by itself; it comes from the person and tracker_update stores it in applied_at, or records in applied_date_declined that they do not remember it.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / trackedJob / properties / daysSinceApplied
      Added value: +{
      +  "description": "Whole days since the applied date, counted in the user's time zone; null without an applied date.",
      +  "type": [
      +    "integer",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / trackedJob / properties / followUpDay
      Added value: +{
      +  "description": "Latest follow-up point, in days after applying, that a job still at the applied status has reached; null before the first point and for every other status. FoundRole never moves or archives a job by itself.",
      +  "enum": [
      +    7,
      +    14,
      +    21,
      +    null
      +  ],
      +  "type": [
      +    "integer",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / trackedJobs / items / properties / appliedDateUnknown
      Added value: +{
      +  "description": "True for a job at the applied status with no stored applied date, unless the person said they do not remember it. FoundRole never fills that date in by itself; it comes from the person and tracker_update stores it in applied_at, or records in applied_date_declined that they do not remember it.",
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / trackedJobs / items / properties / daysSinceApplied
      Added value: +{
      +  "description": "Whole days since the applied date, counted in the user's time zone; null without an applied date.",
      +  "type": [
      +    "integer",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / trackedJobs / items / properties / followUpDay
      Added value: +{
      +  "description": "Latest follow-up point, in days after applying, that a job still at the applied status has reached; null before the first point and for every other status. FoundRole never moves or archives a job by itself.",
      +  "enum": [
      +    7,
      +    14,
      +    21,
      +    null
      +  ],
      +  "type": [
      +    "integer",
      +    "null"
      +  ]
      +}
  2. Changed1 schema field changed
    • addedOutput schema / properties / figureSources
      Added value: +{
      +  "properties": {
      +    "estimatedSalary": {
      +      "properties": {
      +        "basis": {
      +          "type": "string"
      +        },
      +        "methodologyUrl": {
      +          "type": "string"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "ghostScore": {
      +      "properties": {
      +        "basis": {
      +          "type": "string"
      +        },
      +        "methodologyUrl": {
      +          "type": "string"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "methodologyUrl": {
      +      "type": "string"
      +    },
      +    "source": {
      +      "enum": [
      +        "FoundRole"
      +      ],
      +      "type": "string"
      +    },
      +    "visaRecords": {
      +      "properties": {
      +        "basis": {
      +          "type": "string"
      +        },
      +        "falseMeans": {
      +          "type": "string"
      +        },
      +        "methodologyUrl": {
      +          "type": "string"
      +        }
      +      },
      +      "type": "object"
      +    }
      +  },
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
  3. Added
  4. Removed
  5. Changed1 schema field changed
    • changedInput schema / properties / sub_status / description
      Previous value: -"Sub-status within the main status"New value: +"Sub-status within the main status, valid only for that status — saved: interested, researching_company, preparing_application, ready_to_apply; applied: application_submitted, followed_up; interviewing: interview_scheduled, phone_screen, technical, onsite, final_round, pending_feedback; offered: negotiating, considering, offer_received, accepted; archived: ghosted, rejected_by_company, withdrawn_by_candidate, not_interested, employed_by_this_company, employed_by_another_company"
  6. Changed16 schema fields changed
    • changedOutput schema / properties / trackedJob / properties / appliedAt / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJob / properties / createdAt / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJob / properties / deadline / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJob / properties / notes / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJob / properties / reminderAt / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJob / properties / salaryOfferedType / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJob / properties / subStatus / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJob / properties / updatedAt / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJobs / items / properties / appliedAt / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJobs / items / properties / createdAt / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJobs / items / properties / deadline / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJobs / items / properties / notes / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJobs / items / properties / reminderAt / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJobs / items / properties / salaryOfferedType / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJobs / items / properties / subStatus / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedOutput schema / properties / trackedJobs / items / properties / updatedAt / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
  7. Changed17 schema fields changed
    • addedInput schema / $schema
      Added value: +"https://json-schema.org/draft/2020-12/schema"
    • addedInput schema / additionalProperties
      Added value: +false
    • removedInput schema / properties / client_extraction / allOf
      Removed value: -[
      -  {
      -    "required": [
      -      "skills",
      -      "tech_stack",
      -      "benefits",
      -      "bonuses",
      -      "seniority",
      -      "industry",
      -      "management",
      -      "security_clearance",
      -      "visa_sponsorship",
      -      "remote_scope"
      -    ]
      -  }
      -]
    • changedInput schema / properties / client_extraction / description
      Previous value: -"Evidence-backed facts extracted by the client model from the posting. Every nested field is present and nullable; non-null evidence is a short source excerpt rather than an inference."New value: +"Evidence-backed facts extracted by the client model from the posting; non-null evidence is a short source excerpt rather than an inference. Fields absent from the source are omitted or null."
    • changedInput schema / properties / client_extraction / type
      Previous value: -"object"New value: +[
      +  "object",
      +  "null"
      +]
    • changedInput schema / properties / education_requirements / description
      Previous value: -"Education requirements: no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree, or null"New value: +"Education requirements: no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree"
    • changedInput schema / properties / employment_type / description
      Previous value: -"Employment types: full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other, or null"New value: +"Employment types: full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other"
    • changedInput schema / properties / experience_months / description
      Previous value: -"Minimum required experience in months, or null when not stated"New value: +"Minimum required experience in months, when stated"
    • changedInput schema / properties / posted_at / description
      Previous value: -"Posting date as ISO 8601, or null when the source does not state it"New value: +"Posting date as ISO 8601, when the source states it"
    • changedInput schema / properties / salary_currency / description
      Previous value: -"ISO 4217 salary currency code, or null when not stated"New value: +"ISO 4217 salary currency code, when stated"
    • changedInput schema / properties / salary_max_value / description
      Previous value: -"Salary range maximum, or null when not stated"New value: +"Salary range maximum, when stated"
    • changedInput schema / properties / salary_min_value / description
      Previous value: -"Salary range minimum, or null when not stated"New value: +"Salary range minimum, when stated"
    • changedInput schema / properties / salary_type / description
      Previous value: -"Salary period: year, month, week, day, hour, or null"New value: +"Salary period: year, month, week, day, hour"
    • changedInput schema / properties / salary_value / description
      Previous value: -"Single salary amount, or null when the posting gives a range or no salary"New value: +"Single salary amount, when the posting gives one figure instead of a range"
    • changedInput schema / properties / work_location_type / description
      Previous value: -"Work arrangement: on_site, remote, hybrid, or null"New value: +"Work arrangement: on_site, remote, hybrid"
    • changedInput schema / required
      Previous value: -[
      -  "url",
      -  "company_name",
      -  "title_name",
      -  "location_name",
      -  "description",
      -  "posted_at",
      -  "salary_min_value",
      -  "salary_max_value",
      -  "salary_value",
      -  "salary_type",
      -  "salary_currency",
      -  "employment_type",
      -  "work_location_type",
      -  "education_requirements",
      -  "experience_months",
      -  "client_extraction"
      -]New value: +[
      +  "url",
      +  "company_name",
      +  "title_name",
      +  "location_name",
      +  "description"
      +]
    • addedOutput schema / $schema
      Added value: +"https://json-schema.org/draft/2020-12/schema"
  8. Changed6 schema fields changed
    • addedOutput schema / properties / hasMore
      Added value: +{
      +  "type": "boolean"
      +}
    • addedOutput schema / properties / statusOrder
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / subStatusOrder
      Added value: +{
      +  "type": "object"
      +}
    • addedOutput schema / properties / totalCount
      Added value: +{
      +  "type": "integer"
      +}
    • addedOutput schema / properties / trackedJobs
      Added value: +{
      +  "items": {
      +    "properties": {
      +      "appliedAt": {
      +        "type": "string"
      +      },
      +      "contacts": {
      +        "items": {
      +          "type": "object"
      +        },
      +        "type": "array"
      +      },
      +      "createdAt": {
      +        "type": "string"
      +      },
      +      "deadline": {
      +        "type": "string"
      +      },
      +      "id": {
      +        "type": "string"
      +      },
      +      "isStarred": {
      +        "type": "boolean"
      +      },
      +      "job": {
      +        "type": [
      +          "object",
      +          "null"
      +        ]
      +      },
      +      "notes": {
      +        "type": "string"
      +      },
      +      "reminderAt": {
      +        "type": "string"
      +      },
      +      "salaryOffered": {
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "salaryOfferedType": {
      +        "type": "string"
      +      },
      +      "status": {
      +        "type": "string"
      +      },
      +      "subStatus": {
      +        "type": "string"
      +      },
      +      "tags": {
      +        "items": {
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "trackable": {
      +        "type": [
      +          "object",
      +          "null"
      +        ]
      +      },
      +      "updatedAt": {
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "id"
      +    ],
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / trackerWebUrl
      Added value: +{
      +  "type": "string"
      +}
  9. Changed27 schema fields changed
    • addedInput schema / properties / client_extraction
      Added value: +{
      +  "additionalProperties": false,
      +  "allOf": [
      +    {
      +      "required": [
      +        "skills",
      +        "tech_stack",
      +        "benefits",
      +        "bonuses",
      +        "seniority",
      +        "industry",
      +        "management",
      +        "security_clearance",
      +        "visa_sponsorship",
      +        "remote_scope"
      +      ]
      +    }
      +  ],
      +  "description": "Evidence-backed facts extracted by the client model from the posting. Every nested field is present and nullable; non-null evidence is a short source excerpt rather than an inference.",
      +  "properties": {
      +    "benefits": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "evidence": {
      +            "maxLength": 500,
      +            "minLength": 8,
      +            "type": "string"
      +          },
      +          "value": {
      +            "maxLength": 255,
      +            "minLength": 1,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "value",
      +          "evidence"
      +        ],
      +        "type": "object"
      +      },
      +      "maxItems": 30,
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    },
      +    "bonuses": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "evidence": {
      +            "maxLength": 500,
      +            "minLength": 8,
      +            "type": "string"
      +          },
      +          "value": {
      +            "maxLength": 255,
      +            "minLength": 1,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "value",
      +          "evidence"
      +        ],
      +        "type": "object"
      +      },
      +      "maxItems": 20,
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    },
      +    "industry": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "evidence": {
      +          "maxLength": 500,
      +          "minLength": 8,
      +          "type": "string"
      +        },
      +        "value": {
      +          "maxLength": 255,
      +          "minLength": 1,
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "value",
      +        "evidence"
      +      ],
      +      "type": [
      +        "object",
      +        "null"
      +      ]
      +    },
      +    "management": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "evidence": {
      +          "maxLength": 500,
      +          "minLength": 8,
      +          "type": "string"
      +        },
      +        "value": {
      +          "type": "boolean"
      +        }
      +      },
      +      "required": [
      +        "value",
      +        "evidence"
      +      ],
      +      "type": [
      +        "object",
      +        "null"
      +      ]
      +    },
      +    "remote_scope": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "evidence": {
      +          "maxLength": 500,
      +          "minLength": 8,
      +          "type": "string"
      +        },
      +        "value": {
      +          "maxLength": 255,
      +          "minLength": 1,
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "value",
      +        "evidence"
      +      ],
      +      "type": [
      +        "object",
      +        "null"
      +      ]
      +    },
      +    "security_clearance": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "evidence": {
      +          "maxLength": 500,
      +          "minLength": 8,
      +          "type": "string"
      +        },
      +        "value": {
      +          "type": "boolean"
      +        }
      +      },
      +      "required": [
      +        "value",
      +        "evidence"
      +      ],
      +      "type": [
      +        "object",
      +        "null"
      +      ]
      +    },
      +    "seniority": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "evidence": {
      +          "maxLength": 500,
      +          "minLength": 8,
      +          "type": "string"
      +        },
      +        "value": {
      +          "maxLength": 255,
      +          "minLength": 1,
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "value",
      +        "evidence"
      +      ],
      +      "type": [
      +        "object",
      +        "null"
      +      ]
      +    },
      +    "skills": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "evidence": {
      +            "maxLength": 500,
      +            "minLength": 8,
      +            "type": "string"
      +          },
      +          "importance": {
      +            "enum": [
      +              "required",
      +              "preferred",
      +              "mentioned"
      +            ],
      +            "type": "string"
      +          },
      +          "value": {
      +            "maxLength": 255,
      +            "minLength": 1,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "value",
      +          "evidence",
      +          "importance"
      +        ],
      +        "type": "object"
      +      },
      +      "maxItems": 50,
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    },
      +    "tech_stack": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "evidence": {
      +            "maxLength": 500,
      +            "minLength": 8,
      +            "type": "string"
      +          },
      +          "value": {
      +            "maxLength": 255,
      +            "minLength": 1,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "value",
      +          "evidence"
      +        ],
      +        "type": "object"
      +      },
      +      "maxItems": 30,
      +      "type": [
      +        "array",
      +        "null"
      +      ]
      +    },
      +    "visa_sponsorship": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "evidence": {
      +          "maxLength": 500,
      +          "minLength": 8,
      +          "type": "string"
      +        },
      +        "value": {
      +          "enum": [
      +            "offered",
      +            "not_offered",
      +            "conditional"
      +          ],
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "value",
      +        "evidence"
      +      ],
      +      "type": [
      +        "object",
      +        "null"
      +      ]
      +    }
      +  },
      +  "type": "object"
      +}
    • changedInput schema / properties / company_name / description
      Previous value: -"Company name"New value: +"Company name from the posting"
    • changedInput schema / properties / description / description
      Previous value: -"The posting's description from the source result; a short summary is acceptable"New value: +"Complete posting text available in the conversation; a source summary is valid only when no fuller posting text is available"
    • changedInput schema / properties / education_requirements / description
      Previous value: -"Array of: no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree"New value: +"Education requirements: no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree, or null"
    • changedInput schema / properties / education_requirements / type
      Previous value: -"array"New value: +[
      +  "array",
      +  "null"
      +]
    • changedInput schema / properties / employment_type / description
      Previous value: -"Array of: full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other"New value: +"Employment types: full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other, or null"
    • changedInput schema / properties / employment_type / type
      Previous value: -"array"New value: +[
      +  "array",
      +  "null"
      +]
    • changedInput schema / properties / experience_months / description
      Previous value: -"Minimum required experience in months"New value: +"Minimum required experience in months, or null when not stated"
    • changedInput schema / properties / experience_months / type
      Previous value: -"number"New value: +[
      +  "integer",
      +  "null"
      +]
    • changedInput schema / properties / location_name / description
      Previous value: -"Location text, e.g. \"New York, NY\""New value: +"Location text from the posting, including Remote when stated"
    • addedInput schema / properties / posted_at
      Added value: +{
      +  "description": "Posting date as ISO 8601, or null when the source does not state it",
      +  "format": "date-time",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedInput schema / properties / salary_currency
      Added value: +{
      +  "description": "ISO 4217 salary currency code, or null when not stated",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • changedInput schema / properties / salary_max_value / description
      Previous value: -"Salary range maximum"New value: +"Salary range maximum, or null when not stated"
    • changedInput schema / properties / salary_max_value / type
      Previous value: -"number"New value: +[
      +  "number",
      +  "null"
      +]
    • changedInput schema / properties / salary_min_value / description
      Previous value: -"Salary range minimum"New value: +"Salary range minimum, or null when not stated"
    • changedInput schema / properties / salary_min_value / type
      Previous value: -"number"New value: +[
      +  "number",
      +  "null"
      +]
    • changedInput schema / properties / salary_type / description
      Previous value: -"One of: year, month, week, day, hour"New value: +"Salary period: year, month, week, day, hour, or null"
    • changedInput schema / properties / salary_type / enum
      Previous value: -[
      -  "year",
      -  "month",
      -  "week",
      -  "day",
      -  "hour"
      -]New value: +[
      +  null,
      +  "year",
      +  "month",
      +  "week",
      +  "day",
      +  "hour"
      +]
    • changedInput schema / properties / salary_type / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedInput schema / properties / salary_value / description
      Previous value: -"Single salary figure when there is no range"New value: +"Single salary amount, or null when the posting gives a range or no salary"
    • changedInput schema / properties / salary_value / type
      Previous value: -"number"New value: +[
      +  "number",
      +  "null"
      +]
    • changedInput schema / properties / title_name / description
      Previous value: -"Job title"New value: +"Job title from the posting"
    • changedInput schema / properties / url / description
      Previous value: -"The job posting URL"New value: +"Direct URL of the specific job posting; a company homepage is invalid"
    • changedInput schema / properties / work_location_type / description
      Previous value: -"One of: on_site, remote, hybrid"New value: +"Work arrangement: on_site, remote, hybrid, or null"
    • changedInput schema / properties / work_location_type / enum
      Previous value: -[
      -  "on_site",
      -  "remote",
      -  "hybrid"
      -]New value: +[
      +  null,
      +  "on_site",
      +  "remote",
      +  "hybrid"
      +]
    • changedInput schema / properties / work_location_type / type
      Previous value: -"string"New value: +[
      +  "string",
      +  "null"
      +]
    • changedInput schema / required
      Previous value: -[
      -  "url",
      -  "company_name",
      -  "title_name",
      -  "location_name",
      -  "description"
      -]New value: +[
      +  "url",
      +  "company_name",
      +  "title_name",
      +  "location_name",
      +  "description",
      +  "posted_at",
      +  "salary_min_value",
      +  "salary_max_value",
      +  "salary_value",
      +  "salary_type",
      +  "salary_currency",
      +  "employment_type",
      +  "work_location_type",
      +  "education_requirements",
      +  "experience_months",
      +  "client_extraction"
      +]
  10. Changed4 schema fields changed
    • addedInput schema / properties / education_requirements / items
      Added value: +{
      +  "enum": [
      +    "no_requirements",
      +    "high_school",
      +    "associate_degree",
      +    "bachelor_degree",
      +    "professional_certificate",
      +    "postgraduate_degree"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / employment_type / items
      Added value: +{
      +  "enum": [
      +    "full_time",
      +    "part_time",
      +    "contractor",
      +    "temporary",
      +    "intern",
      +    "volunteer",
      +    "per_diem",
      +    "other"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / salary_type / enum
      Added value: +[
      +  "year",
      +  "month",
      +  "week",
      +  "day",
      +  "hour"
      +]
    • addedInput schema / properties / work_location_type / enum
      Added value: +[
      +  "on_site",
      +  "remote",
      +  "hybrid"
      +]
  11. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "trackedJob": {
      +      "properties": {
      +        "appliedAt": {
      +          "type": "string"
      +        },
      +        "contacts": {
      +          "items": {
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "createdAt": {
      +          "type": "string"
      +        },
      +        "deadline": {
      +          "type": "string"
      +        },
      +        "id": {
      +          "type": "string"
      +        },
      +        "isStarred": {
      +          "type": "boolean"
      +        },
      +        "notes": {
      +          "type": "string"
      +        },
      +        "reminderAt": {
      +          "type": "string"
      +        },
      +        "salaryOffered": {
      +          "type": [
      +            "number",
      +            "null"
      +          ]
      +        },
      +        "salaryOfferedType": {
      +          "type": "string"
      +        },
      +        "status": {
      +          "type": "string"
      +        },
      +        "subStatus": {
      +          "type": "string"
      +        },
      +        "tags": {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "trackable": {
      +          "type": [
      +            "object",
      +            "null"
      +          ]
      +        },
      +        "updatedAt": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "id"
      +      ],
      +      "type": "object"
      +    }
      +  },
      +  "type": "object"
      +}
  12. Changed1 schema field changed
    • changedInput schema / properties / description / description
      Previous value: -"Full job description text as stated by the source"New value: +"The posting's description from the source result; a short summary is acceptable"
  13. Changed2 schema fields changed
    • changedInput schema / properties / description / description
      Previous value: -"Full job description text"New value: +"Full job description text as stated by the source"
    • changedInput schema / required
      Previous value: -[
      -  "url",
      -  "company_name",
      -  "title_name",
      -  "location_name"
      -]New value: +[
      +  "url",
      +  "company_name",
      +  "title_name",
      +  "location_name",
      +  "description"
      +]
  14. Added

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it explains that omitted facts are backfilled by FoundRole's own extractors, that a save never blocks on missing facts, that client_extraction is validated and stored separately, and that repeated saves return the existing tracked job (a behavioral consequence of idempotentHint, not a restatement of it). It does not discuss authorization requirements, failure modes, or what validation rejects, which keeps it off a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The routing guidance is correctly front-loaded and the two opening paragraphs earn their place. The subsequent bulleted re-listing of all 19 parameters largely duplicates full-coverage schema descriptions, including the 32-value sub_status enumeration, which adds length without adding meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 19-parameter save tool with an output schema and idempotency annotations, the description covers the required identification set, defaults, deduplication, and the derived-facts pipeline — enough to call it correctly. Missing only peripheral context such as whether a user profile must exist or what validation rejects.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so most of the field list is redundant restatement. What it does add: status defaults to "saved" (absent from the schema), a clear grouping of which five fields identify the posting versus everything being optional, and the semantic that client_extraction labels require source excerpts because FoundRole validates and stores them separately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource: saves an externally-found job posting into the user's tracker. It immediately distinguishes itself from the sibling that handles the other intake path (tracker_add with a job_id from jobs_search), so an agent can route without inspecting either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use (a job seen anywhere in the conversation, including places other than jobs_search results) and when-not-to-use (jobs that came from jobs_search should go to tracker_add). It also removes a likely false prerequisite by stating no prior jobs_search call is needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.