FoundRole Jobs - AI Job Search & Application Tracker
OfficialFoundRole MCP サーバー — ChatGPT、Claude、Cursor での AI 求人検索
ChatGPT や Claude に求人を尋ねると、実際の求人情報が返ってきます。各求人は、実際に募集が続いているか、実際の給与はいくらか、企業がビザをスポンサーしているかがチェック済みです。FoundRole MCP サーバーは、あなたの AI アシスタントを FoundRole のライブ求人ボード、応募トラッカー、キャリア知識ベースに接続するため、求人検索全体が、あなたがすでに使っているチャットの中で完結します。
一度サインインすれば、あとはアシスタントが処理します。 AI が初めて FoundRole を呼び出すと、標準の OAuth サインインが開きます。ブラウザで一度承認すれば、検索、ファクトチェック、トラッカー、リマインダー、アラートのすべてをカバーします。コピーやローテーションが必要な API キーはなく、アカウントは無料です。
アシスタントにできること
質問してライブ求人を検索。 企業の採用ページから直接取得した求人情報を、40以上の業界にわたって毎時更新。自然言語が実際のフィルターにマッピングされます — 職種、勤務地、企業、給与レンジ、掲載日: 「今週掲載された、ニューヨークのリモート React 求人で年収13万ドル以上」
すべての求人を無料でファクトチェック。 応募に一晩費やす前に、3つの質問がそれぞれの根拠とともに回答されます:
実際に採用しているのか? ゴースト掲載リスク — その求人が何ヶ月も再掲載されているか、履歴書収集目的に見えるか。
低い給与で働かされていないか? その市場の雇用主が実際に届け出ている給与との比較。隠れた給与レンジが推測でなくなる。
ビザをスポンサーしてくれるか? その企業が過去にビザをスポンサーしたことがあるか、公開資料から年ごとに集計。
自分との適合度を確認。 履歴書とプロフィールに対するマッチスコアに加え、適合度でランク付けされたパーソナライズ求人レコメンド。
求人を並べて比較。 「この2つを比較して」 で、適合度、給与、スポンサーシップ、掲載リスクが一度に並びます — 選択が感覚ではなくなります。
どこからでも求人を貼り付け。 LinkedIn、採用ページ、友人が送ってくれたリンク — 掲載内容をチャットに貼り付けると、同じチェックが実行され、FoundRole の掲載情報と一緒にトラッカーに置けます。アシスタントはあなたが提供したテキストを読み取ります。サイトをクロールすることはありません。
応募の追跡を見失わない。 求人を カンバン応募トラッカー に保存し、質問するだけで Saved → Applied → Interviewing → Offered → Hired と進められます。メモ、タグ、想定給与、リクルーター連絡先、締切を添付できます。同じボードが Web アプリにも表示されます。
フォローアップを逃さない。 追跡中の求人にリマインダーを設定すると、Google カレンダー、Outlook、Apple カレンダー用のカレンダー(
.ics)招待状付きメールが届きます。検索結果を自動で受け取る。 検索を毎日、毎週、毎月のメールアラートに登録すると、新しいマッチが受信トレイに届きます。
気まずい質問もどうぞ。 面接対策、給与交渉、履歴書のテクニック、企業リサーチ — FoundRole の知識ベースに基づいた回答に、ソースへのリンク付き。
結果がテキストの壁ではなく、実際のパネルとして表示。 MCP Apps をサポートするクライアント(ChatGPT を含む)では、検索結果、求人詳細、トラッカーがチャット内でインタラクティブなパネルとして表示されます。
FoundRole.com と同じアカウントとデータです — MCP サーバーは、あなたの AI がそれを操作できるようにするだけです。
Related MCP server: Civify MCP Server
無料版と Pro 版
検索、すべての求人のファクトチェック、トラッカー、リマインダー、アラートは無料で、利用制限はありません。Pro ではスクリーニングが追加されます: リモートのみ、スポンサーありのみ、最低給与、リスクの高い掲載の非表示、最低マッチ率などを指定すると、アシスタントがリストを表示する前にフィルタリングし、フィルタリングしたことを通知します。無料アカウントでも完全なリストが返されますが、フィルターが適用されなかったという注記が付きます。
初めての方? FoundRole AI 検索ガイド で、各クライアントの接続方法を FAQ 付きでステップバイステップに説明しています。
セットアップ
クライアントに応じて2つの接続方法があります。どちらの場合も、クライアントが初回接続時に FoundRole のサインインを開くので、一度承認すれば完了です。
オプション 1 — リモートサーバー(推奨)
クライアントを FoundRole MCP エンドポイントに向けます:
https://www.foundrole.com/mcpChatGPT、Claude、Cursor、VS Code など、ほとんどの最新クライアントはリモート MCP(Streamable HTTP)をネイティブにサポートしているため、これが設定のすべてです。
オプション 2 — stdio ブリッジ(リモート MCP 非対応クライアント用)
クライアントが stdio トランスポートのみをサポートする場合、このパッケージを npx でローカル実行します。stdio を FoundRole エンドポイントにブリッジし、OAuth サインインも処理します:
npx @foundrole/ai-job-search-mcpAI アシスタントの接続
ChatGPT
所要時間: 約1分
ChatGPT アプリディレクトリ で FoundRole を開きます。
追加 をクリックし、ChatGPT が開く FoundRole サインインを承認します。
任意のチャットで求人を尋ねます — 設定する項目も、貼り付けるものもありません。
Claude Web/デスクトップ
所要時間: 約2分
Claude の設定(プロフィール / 設定アイコン)を開きます。
コネクタ(または ツール)を見つけ、カスタムコネクタを追加 をクリックします。
名前を
FoundRoleにします。リモート MCP サーバー URL フィールドに、以下を貼り付けます:
https://www.foundrole.com/mcp保存し、Claude の接続を許可し、開かれる FoundRole サインインを承認します。その後、チャットで求人を尋ねます。
Cursor
所要時間: 約1分
Cursor Marketplace から FoundRole プラグインをインストールします: サイドバーで Customize を開き、FoundRole を見つけて Install を選択します。Cursor が開く FoundRole サインインを承認し、任意のチャットで求人を尋ねます。
プラグインはこのリポジトリ内にあります — .cursor-plugin/plugin.json で、サーバーは mcp.json で宣言されています。リストに載る前に試すには、このリポジトリを ~/.cursor/plugins/local/ にシンボリックリンクし、ウィンドウをリロードします。
手動セットアップ — Cursor / VS Code / Windsurf
Cursor では、設定 → MCP を開き、~/.cursor/mcp.json に以下を追加します:
{
"mcpServers": {
"foundrole": {
"url": "https://www.foundrole.com/mcp"
}
}
}VS Code では、ワークスペースの .vscode/mcp.json(またはユーザーの mcp.json)に追加します — VS Code は異なるキーを使用し、明示的なトランスポートタイプが必要です:
{
"servers": {
"foundrole": {
"type": "http",
"url": "https://www.foundrole.com/mcp"
}
}
}エディタが開く FoundRole サインインを承認し、チャットで求人を尋ねます。
Antigravity(Google)
所要時間: 約1分
このリポジトリから直接プラグインをインストールします:
agy plugin install https://github.com/foundrole/jobs-mcp-proxyAntigravity が開く FoundRole サインインを承認し、CLI で求人を尋ねます。プラグインは mcp_config.json でサーバーを宣言しています。手動で配線する場合は、同じエントリを ~/.gemini/config/mcp_config.json に追加します:
{
"mcpServers": {
"foundrole": {
"serverUrl": "https://www.foundrole.com/mcp"
}
}
}その他の MCP クライアント
同じアドレスがどこでも使えます: https://www.foundrole.com/mcp をリモートサーバーとして追加するか、stdio のみのクライアントは npx @foundrole/ai-job-search-mcp でブリッジします。
注: サインインを承認した後、一部のクライアントでは接続が有効になる前に再起動(終了して再度開く)が必要です。
試してみるフレーズ
「今週掲載されたサンフランシスコのシニアバックエンドエンジニア求人を探して。」
「この中でゴースト掲載の可能性が最も低いのはどれ?」
「Stripe はビザをスポンサーしていますか? この求人の実際の給与は?」
「Stripe と Vercel の求人を適合度、給与、スポンサーシップで比較して。」
「LinkedIn の掲載を貼ります — 同じチェックを実行して。」
「私の履歴書に合う求人を推薦して。」
「トラッカーに保存して、Applied にマークして。」
「来週の火曜日の朝にフォローアップするようリマインドして。」
「今、Interviewing 列には何がある?」
「リモート React 求人の週次アラートに登録して。」
「『履歴書を説明してください』にどう答えたらいい?」
セキュリティ
PKCE 付き OAuth 2.1。 標準の認可フローで FoundRole にサインインします — 短期間のトークン、即時失効、AI クライアントと資格情報を共有せず、コピー、保存、漏洩する API キーもありません。
HTTPS のみ、動的クライアント登録とリダイレクト URI 検証付き。
Streamable HTTP トランスポート(直接)、またはこのプロキシ経由の stdio。
あなたの代わりに応募やメール送信をすることはありません。
トラブルシューティング
サインインを求められる / 「認証が必要です」:
初回接続時は正常です — サーバーはすべてのセッションを認証します。クライアントが開くブラウザウィンドウで FoundRole サインインを完了してください。
その後もツールが表示されない場合は、クライアントを再起動するか、コネクタを再接続して認可が再送信されるようにしてください。
「接続に失敗しました」:
インターネット接続と、URL が正確に
https://www.foundrole.com/mcpであることを確認してください。クライアントがリモート HTTP MCP をサポートしているか確認してください。サポートしていない場合は、stdio ブリッジ(オプション 2)を使用してください。
「コマンドが見つかりません」(stdio クライアント):
Node.js をインストールし(必要バージョンは
package.jsonのenginesを参照)、再試行するか、グローバルにインストールします:npm install -g @foundrole/ai-job-search-mcpを実行してからai-job-search-mcpを実行します。
コネクタが機能しない:
URL を再確認し、サインインを完了し、AI クライアントを再起動してください — 一部のクライアントは再起動後にのみ接続を認識します。
回答の背後にあるデータを探索
アシスタントが読み取るのと同じデータが FoundRole で閲覧できます:
仕組み — 求人情報の出所と、各掲載がゴースト、給与、ビザのチェックを受ける仕組み
H1B 給与エクスプローラー — 雇用主が米国労働省に届け出た認定賃金を、セクター、業界、地域、職種別にチャート化
H1B スポンサーランキング — 届け出賃金の中央値による主要ビザスポンサー企業を、業界、セクター、都市、州別に閲覧可能
企業ディレクトリ — あらゆる雇用主のオープン求人、給与データ、ビザスポンサーシップ履歴
業界セクター — 40以上の業界で誰が採用しているか
地域別採用情報 — 州と都市圏別の求人情報と賃金ベンチマーク
求人トラッカー — アシスタントが管理するカンバンボードをブラウザで
ライブ求人ボード — 掲載情報を直接閲覧
ヘルプ
🌐 ウェブサイト: www.foundrole.com — 無料の AI 求人検索、応募トラッカー、企業リサーチ
📖 セットアップガイド & FAQ: foundrole.com/ai-search-mcp
🐛 問題報告: GitHub Issues
💬 質問: dev@foundrole.com
AI クライアントを接続し、一度サインインすれば、求人検索全体をチャットから実行できます — 検索、ファクトチェック、追跡、リマインダー、アラートが FoundRole で無料です。
FoundRole チームによる制作。
Available Tools
24 toolsjob_alert_listList job alertsARead-onlyInspect
Lists the authenticated user's job alerts across all subscription sources (regular, company page, MCP).
Input:
status: Filter by status — one of pending, active, unsubscribed (optional, default: all statuses)limit: Number of results to return (default 20, max 50)offset: Number of results to skip (default 0)
Output: Returns the user's job alerts with pagination info and a summary of the underlying job search (query, location, company where available).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of results to return (default 20, max 50) | |
| offset | No | Number of results to skip (default 0) | |
| status | No | Filter by status: pending, active, unsubscribed |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| jobAlerts | No | |
| totalCount | No | |
| frequencies | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so safety is covered. The description adds genuinely new behavioral context: results are scoped strictly to the authenticated user (no cross-user access), the page cap is 50 with a default of 20, and each result carries pagination info plus a summary of the underlying job search.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded scope sentence followed by clearly labeled Input and Output blocks makes it quick to scan. The Input section largely duplicates the schema descriptions, which is mild waste, but nothing is significantly bloated.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-optional-parameter read tool with annotations and an output schema present, the description covers scope, defaults, and output shape adequately. It leaves out what an alert payload contains in detail, but the output schema carries that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description's Input block restates the same limit/offset/status text almost verbatim. The only value added is the 'default: all statuses' clarification for `status`, which the schema omits, so this sits just at the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Lists the authenticated user's job alerts') and scopes it precisely to 'all subscription sources (regular, company page, MCP)', which distinguishes it from the job_alert_subscribe/unsubscribe siblings that act on individual alerts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the verb 'Lists' and the fact that the sibling tools are mutations. There is no explicit statement of when to prefer this over e.g. tracker_list or jobs_recommendations, and no exclusion guidance, so the agent must infer context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
job_alert_subscribeCreate a job alertADestructiveIdempotentInspect
Subscribes the authenticated user to job alerts for a specific saved job search.
Input:
job_search_id: The job search identifier to subscribe to (required). Accepts either the job search UUID or the composite job ID returned byjobs_search/jobs_details(format: "seo_id--job_search_id").delivery: digest, fast (optional). Fast email is not available on every account and needs enough new matches for the exact saved search. Unsupported fast selection returns a validation error and keeps the existing delivery mode.frequency: Alert frequency — one of daily, weekly, monthly (optional, defaults to "weekly")
Output:
Returns the created or updated job alert with id, status, and frequency.
Idempotent: calling this tool for an already-subscribed search updates the existing alert without creating a duplicate. An existing active alert with the same query text, location, company and filters, and at least the same radius, is returned instead of a new one, with the requested frequency applied to it.
A user keeps one alert per query and place. When they already have an active alert for the same query and place with other filters, radius or sort, this tool changes that alert to the new search instead of adding a second one: the returned jobAlert.id is the existing alert, jobSearchId is the new search, and message says the alert was changed.
Delivery:
Digest alerts arrive together in one email, one section per query and place. Opted-in fast alerts are sent separately while the account has them: matches found overnight arrive in one morning email at the hour the user usually starts the day, and later matches follow at least 3 hours after the previous email, up to 3 emails per local day. A fast email carries only jobs found since the previous one, never a job already sent to the user, a role from the same employer sent in the last 30 days, or a job in the user's tracker. When the account no longer has fast alerts they return to the ordinary digest and retain the saved fast preference. Each section applies every filter and the sort of its saved search, the same way jobs_search does for that account. A job appears in the digest once, even when it matches several alerts, and no email is sent when there are no new matches. The digest follows the most frequent alert, and arrives less often when the user has not used FoundRole for a while.
| Name | Required | Description | Default |
|---|---|---|---|
| delivery | No | Delivery mode: digest, fast; fast is not available on every account and needs a qualifying search | |
| frequency | No | Alert frequency: daily, weekly, monthly (defaults to "weekly") | |
| job_search_id | Yes | Job search UUID or composite job id ("seo_id--job_search_id") from jobs_search results |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobAlert | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare destructiveHint=true and idempotentHint=true, but do not explain what is destroyed or how idempotency works. The description adds crucial context: it explains that active alerts can be changed rather than duplicated, details delivery modes and their constraints, describes digest vs fast email behavior, and clarifies the resulting email content. This goes well beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with clear sections (Input, Output, Delivery) and uses bullet points. It is somewhat lengthy, particularly the Delivery section, but every part earns its place by explaining important behavior. It is well front-loaded with the core action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (idempotent updates, delivery options, email scheduling) and the presence of an output schema, the description is remarkably complete. It covers input validation, idempotency, conflict resolution, and delivery mechanics in detail, leaving no critical gaps for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all parameters. The description adds some value by explaining the composite job ID format and the effect of unsupported fast delivery (validation error, keeping existing mode). However, it largely repeats schema details, so a baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource clearly: subscribes the authenticated user to alerts for a saved job search. Distinguishes itself from siblings like job_alert_list and job_alert_unsubscribe by focusing on creation/update of alerts. The idempotent-update semantics further differentiate it from any pure 'create' sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description provides clear context for when to use it (subscribing to a saved search) and describes idempotent behavior on re-call, which implies repeated use is safe. However, it does not explicitly name alternative tools or provide when-not-to-use guidance, such as what to do if the user wants to unsubscribe or list alerts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
job_alert_unsubscribeUnsubscribe from a job alertADestructiveInspect
Unsubscribes the authenticated user from job alerts for a specific job search.
Input:
job_search_id: The job search identifier to unsubscribe from (required). Accepts either the job search UUID or the composite job ID returned byjobs_search/jobs_details(format: "seo_id--job_search_id").
Output: Confirms the alert has been unsubscribed. Idempotent: returns success even when the user was not subscribed or is already unsubscribed.
| Name | Required | Description | Default |
|---|---|---|---|
| job_search_id | Yes | Job search UUID or composite job id ("seo_id--job_search_id") from jobs_search results |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | |
| success | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description explicitly claims 'Idempotent: returns success even when the user was not subscribed or is already unsubscribed,' but the annotations declare idempotentHint=false. This is a direct contradiction of a declared behavioral trait, which is the most consequential kind of error for an agent deciding whether retries are safe.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Roughly four sentences, front-loaded with the action, then clearly delimited Input/Output sections. The Input paragraph carries real information (accepted ID formats and their origin) rather than padding, and nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description still adds the ID-sourcing guidance and the idempotency/error behavior an agent needs. The only gap is the missing contrast with job_alert_unsubscribe_all, and the idempotency claim is contradicted rather than merely incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is already 100%, so the baseline is 3; the description goes slightly beyond by naming the tools that produce the composite 'seo_id--job_search_id' value (jobs_search / jobs_details) and by restating requiredness, which helps an agent source the value correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (unsubscribes), resource (job alerts), and scope (for a specific job search, by the authenticated user), which naturally distinguishes it from job_alert_unsubscribe_all and job_alert_subscribe. An agent can pick this tool over its siblings without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the name and the 'specific job search' scoping, and the description helpfully says where the accepted ID format comes from (jobs_search / jobs_details). However, it never states when to prefer this over job_alert_unsubscribe_all, nor any prerequisites (e.g., auth/scope requirements) or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
job_alert_unsubscribe_allUnsubscribe from all job alertsADestructiveIdempotentInspect
Unsubscribes the authenticated user from ALL of their job alerts at once, across every subscription source (regular, company page, MCP).
Input:
confirm: Must betrueto execute. The call is rejected when omitted or not true — this guards against an unintended bulk unsubscribe.
Output: Confirms how many alerts were unsubscribed. Idempotent: returns success even when the user has no active alerts.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Set to true to confirm unsubscribing from every alert; the call is rejected otherwise |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | |
| success | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, but the description adds real behavioral substance beyond them: the call is rejected unless confirm is true, and it returns success even when no alerts are active. It also states the output shape (a count of alerts unsubscribed). It restates idempotency that annotations already carry, which keeps it from 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Content is front-loaded with the core action in the first sentence and the guard/idempotency details after. The Input/Output headings are slightly heavy for a single-parameter tool, costing a little structure economy, but every sentence carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter destructive bulk operation with an output schema and rich annotations, nothing an agent needs is missing: scope, the confirmation precondition, the rejection behavior, idempotency, and the return summary are all covered.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema already documents that confirm must be true and that the call is rejected otherwise. The description adds only the rationale ('guards against an unintended bulk unsubscribe'), which is useful intent but no new syntax or format information. Baseline 3 is appropriate when the schema carries the parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Unsubscribes ... from ALL of their job alerts') and scopes the operation precisely ('at once, across every subscription source (regular, company page, MCP)'). This cleanly distinguishes it from the sibling job_alert_unsubscribe, which handles a single alert, without the agent needing to open either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'ALL ... at once' framing makes the bulk-use case clear and implicitly routes single-alert requests to job_alert_unsubscribe, and the confirm guard establishes a precondition for execution. However, it never names the alternative tool explicitly or states when NOT to use this bulk operation, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_analyze_externalAnalyze a job from another siteAInspect
Analyzes one job found outside FoundRole using the authenticated user's FoundRole profile and the same signals used for FoundRole jobs: resume match, missing skills, H-1B sponsorship history, E-Verify, ghost-job risk, posted compensation, and market salary estimates. Use tracker_add_external only when the user asks to save without analysis.
The input represents the direct posting URL and all job content already available in the conversation.
The five text identity fields are required; every structured fact field is optional, with a fact the
source does not state simply omitted (or null). 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 the evidence,
stores the client extraction separately, derives missing deterministic facts, and reports which
values were provided, derived, accepted, rejected, or remain unknown.
The output includes comparisonRef; retain it exactly for a later jobs_compare call. The analysis is a
decision aid, not a guarantee about sponsorship, legitimacy, compensation, or hiring outcome.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Direct URL of the specific job posting; a company homepage is invalid | |
| posted_at | No | Posting date as ISO 8601, when the source states it | |
| title_name | Yes | Job title from the posting | |
| description | Yes | Complete posting text available in the conversation; a source summary is valid only when no fuller posting text is available | |
| salary_type | No | Salary period: year, month, week, day, hour | |
| company_name | Yes | Company name from the posting | |
| salary_value | No | Single salary amount, when the posting gives one figure instead of a range | |
| location_name | Yes | Location text from the posting, including Remote when stated | |
| employment_type | No | Employment types: full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other | |
| salary_currency | No | ISO 4217 salary currency code, when stated | |
| salary_max_value | No | Salary range maximum, when stated | |
| salary_min_value | No | Salary range minimum, when stated | |
| client_extraction | No | 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. | |
| experience_months | No | Minimum required experience in months, when stated | |
| work_location_type | No | Work arrangement: on_site, remote, hybrid | |
| education_requirements | No | Education requirements: no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | Yes | |
| mode | Yes | |
| studioUrl | No | |
| statusOrder | Yes | |
| derivedFields | Yes | |
| trackerWebUrl | Yes | |
| unknownFields | Yes | |
| providedFields | Yes | |
| clientExtraction | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses that FoundRole validates evidence, stores the client extraction separately, derives missing deterministic facts, and reports whether each value was provided/derived/accepted/rejected/unknown. It also warns the analysis is a decision aid, not a guarantee on sponsorship, legitimacy, compensation, or hiring. Annotations (readOnlyHint=false, idempotentHint=false) are consistent with the described write-and-store behavior, though the description does not say what happens on validation rejection or whether repeated calls mutate state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and the sibling routing in the first sentence, then input contract, then output/limits. It is dense but each paragraph carries distinct information. Minor deduction for some repetition of the null/omit rule that the schema already encodes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 16-parameter write operation with an output schema and annotations, the description covers input contract, validation behavior, and the key return value (comparisonRef retained for jobs_compare). It stops short of describing failure modes or rate limits, but the output schema covers return shape, so what remains missing is modest.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the per-field baseline is 3; the description adds policy-level meaning beyond it — the five text identity fields are required, all structured facts are optional and should be omitted or null when the source is silent, and client_extraction labels must be evidence-backed. The evidence requirement and the provided/derived/rejected reporting semantics are the kind of guidance the schema alone cannot express.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Analyzes one job found outside FoundRole') and immediately scopes the work: it uses the authenticated user's profile and the same signals as native FoundRole jobs, enumerating them (resume match, missing skills, H-1B history, E-Verify, ghost-job risk, compensation, market salary). This is clearly distinguishable from jobs_details (native job lookup) and tracker_add_external (save).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes the agent away from the sibling: 'Use tracker_add_external only when the user asks to save without analysis,' which defines both when this tool applies and when the alternative applies. It also states the input assumption ('the direct posting URL and all job content already available in the conversation'), removing ambiguity about whether the tool fetches content itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_compareCompare jobsARead-onlyInspect
Compares 2 to 4 jobs side by side using the same FoundRole analysis fields: resume match, missing skills, H-1B and E-Verify signals, ghost-job risk, posted pay, and market salary estimates.
comparison_refs accepts exact FoundRole job IDs returned by jobs_search and exact external
comparisonRef URLs returned by jobs_analyze_external. Analyze each outside job first; a bare URL that
has not been analyzed cannot be compared because FoundRole does not have its posting facts. Preserve
every reference exactly, keep the user's requested order, and do not send duplicates.
| Name | Required | Description | Default |
|---|---|---|---|
| comparison_refs | Yes | Two to four exact FoundRole job IDs or external comparisonRef URLs |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | Yes | |
| mode | Yes | |
| studioUrl | No | |
| statusOrder | Yes | |
| trackerWebUrl | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered; the description adds genuinely new behavioral context about the error mode (unanalyzed URLs fail because FoundRole has no posting facts) and about input fidelity requirements (preserve refs exactly, keep order, no duplicates). It does not describe how the comparison is rendered, but an output schema exists to carry that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded purpose sentence, then a second paragraph scoped entirely to the single parameter. Every sentence carries information, though the 'keep the user's requested order, do not send duplicates' clause is slightly bundled and could be tighter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Single-parameter, read-only tool with full schema coverage, an output schema, and closed-world annotation. The description covers purpose, valid inputs, prerequisites, and the main failure mode — nothing an agent needs in order to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description still adds real meaning: it identifies the two distinct reference formats (exact FoundRole job IDs vs. exact external comparisonRef URLs), their provenance, the 2–4 cardinality, and the no-duplicate/order-preserving contract. That is substantially more than the schema's one-line item description conveys.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (compares jobs, 2–4 at a time) and enumerates the exact analysis dimensions produced, so the agent knows precisely what it gets back. It also implicitly separates itself from jobs_search and jobs_analyze_external by naming them as reference *producers* rather than comparison tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a hard prerequisite: each external job must be analyzed by jobs_analyze_external first, because 'a bare URL that has not been analyzed cannot be compared.' It also states the source of valid refs (jobs_search, jobs_analyze_external) and ordering/dedup rules. It stops short of an explicit when-not-to-use or a direct comparison against a sibling tool like jobs_details.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_detailsGet job detailsAInspect
Fetches full details for one job by the id returned from jobs_search — the deeper view behind a search result.
Input:
job_id: The exact ID string from theidfield of ajobs_searchresult.result_item_id: The matching occurrence ID from that result'sresultItemIdfield, when available.
Output:
Complete job details: description, skills, benefits, requirements, salary benchmark, resume match,
H-1B and E-Verify signals, job-trust analysis, and application link. A posting that passed the
fully-remote check carries remoteCheck: the posting lines that make the role remote and where
the employee may work from, or an unknown scope when the posting does not say. Personalized and extended
insight fields follow the authenticated user's current entitlements.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | The unique identifier of the job from jobs_search results | |
| result_item_id | No | The result occurrence ID returned with the selected job |
Output Schema
| Name | Required | Description |
|---|---|---|
| job | No | |
| studioUrl | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackerWebUrl | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds real context beyond annotations: entitlement-dependent personalization of extended fields and the semantics of the conditional `remoteCheck` field. However, the annotations declare readOnlyHint=false and idempotentHint=false, which sits awkwardly with the purely 'fetches' framing and is never explained (e.g., that the call records analytics or consumes entitlement quotas) – a mild tension rather than a clear contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose, then cleanly sectioned into Input and Output. Each line carries information the agent needs; the output enumeration is long but replaces the need to inspect the output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter read tool with full schema coverage, an output schema, and non-trivial annotations, the description covers purpose, input provenance, output shape, and conditional fields. Nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description earns extra by telling the agent exactly where each value comes from (`id` field of a jobs_search result, `resultItemId` when available), which the schema only states generically.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fetches full details for one job by the `id`') and positions itself relative to a sibling ('the deeper view behind a search result' from jobs_search). An agent can separate it from jobs_search, jobs_compare, or jobs_recommendations without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clear usage context: it must be invoked with an ID produced by jobs_search, optionally with the matching `resultItemId` occurrence. It does not state explicit exclusions (e.g., 'use jobs_compare instead when comparing multiple jobs'), so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_recommendationsRecommend jobs for my profileAIdempotentInspect
Returns the authenticated user's personalized job recommendations built from their resume, skills, target roles, and preferred location. Results are ranked by fit, may include related roles, and carry the same salary, match, H-1B, and job-trust insight payload used by job search. The search filters and sort parameters apply to this personalized feed too. One call returns one answer: there is no next page, and the response links to the same feed on the FoundRole website. An explicit query for a different or unrecognized profession uses the same general job search as jobs_search, preserving the query and filters instead of substituting the profile's target roles. Without a location the feed covers the place saved on the account, and the response names that place as searchedPlace.
A processing status means the personalized feed is still being prepared; a later call returns the completed feed.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Result order (score, posted_at, match, salary): score is relevance and the default, posted_at is newest first, salary is highest pay first, match is best personal fit first and needs a resume. Ordering by salary or match is an advanced option. | |
| query | No | The full job title or skill (e.g., "Ruby Developer", NOT just "Ruby") | |
| radius | No | Search radius in miles around a city location (default 40); not used for state, country or remote searches. | |
| remote | No | Advanced filter: only remote-eligible jobs, matched across the whole country of the requested location rather than its radius. | |
| company | No | The official company name, or the domain of one employer | |
| benefits | No | Advanced filter: benefit names such as "health insurance", "401k" or "parental leave"; a job qualifies only when it states every listed benefit. Names that match no known benefit are ignored. | |
| location | No | Geographic location (e.g., 'Boston, MA') | |
| companies | No | Filter: official company names; a job from any of them qualifies, across every job board each employer posts on. More than one company makes it an advanced filter. Next to company, a job has to match both; hiring_brand narrows company only. | |
| education | No | Filter: jobs whose posting requires one of these education levels (no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree); bachelor_degree means the posting asks for a bachelor degree, not that it suits someone holding one. | |
| min_match | No | Advanced filter: lowest personal FoundRole match grade to keep, the same letter each job shows in insights.match.grade. A and A- are rare even for a strong resume; B keeps good and strong matches; C+ also keeps fair ones. Needs a resume on the account. | |
| work_modes | No | Advanced filter: jobs in any of these work modes (on_site, remote, hybrid). remote is matched across the whole country of the location, the others within the radius. ["remote"] is the same search as remote: true. | |
| bonuses_only | No | Advanced filter: only jobs that state a bonus (sign-on, performance, referral, commission and the like). | |
| hiring_brand | No | Filter: one brand inside the company, for example company "Google" with hiring_brand "YouTube"; used only together with company. | |
| salary_floor | No | Advanced filter: minimum annualized salary in USD; a posting qualifies when the lower bound of its pay band reaches the floor. Jobs without a USD salary are dropped. | |
| posted_days_ago | No | Number of days ago to search for jobs (1-365) | |
| employment_types | No | Filter: jobs offered as any of these employment types (full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other). | |
| exclude_companies | No | Advanced filter: official company names whose jobs are removed from the results, across every job board each employer posts on. | |
| experience_levels | No | Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive, level_not_stated). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years. level_not_stated selects jobs whose level cannot be derived; it can be selected alone or alongside other levels. | |
| h1b_sponsors_only | No | Advanced filter: only companies known to sponsor H1B visas. |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | No | |
| guide | No | |
| preview | No | |
| feedKind | No | |
| savedRole | No | |
| feedStatus | No | |
| totalCount | No | |
| continueUrl | No | |
| jobSearchId | No | |
| resultSetId | No | |
| statusOrder | No | |
| revalidating | No | |
| resultBatchId | No | |
| searchedPlace | No | |
| trackerWebUrl | No | |
| profileSetupUrl | No | |
| profileSetupState | No | |
| lowRelevanceNotice | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses substantial behavior beyond the annotations: ranking, related roles, one-page/no-pagination behavior, default saved location, searchedPlace naming, and that a processing status means the feed is still being prepared. The remaining gap is that annotations mark readOnlyHint=false while the description frames this as a retrieval-style feed without explaining what non-read-only side effect or state change may occur.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then adds the important edge cases: query fallback, location default, one-page behavior, and processing status. It is somewhat long but most sentences earn their place; a few could be tightened without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 19-parameter tool with an output schema and annotations, the description covers the key operational details an agent needs: personalization inputs, fallback to jobs_search, location default, no pagination, and asynchronous preparation status. It is largely complete, though it could say more about authentication or why the tool is not marked read-only.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already carries the detailed parameter semantics. The description adds only a general note that the same search filters and sort parameters apply to this personalized feed, which is useful but does not add parameter-level meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource — returns the authenticated user's personalized job recommendations — and explains the inputs that shape them: resume, skills, target roles, and preferred location. It distinguishes this personalized feed from the general search behavior used by jobs_search when an explicit query targets a different profession.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear usage context and names the fallback relationship to jobs_search when the query targets a different or unrecognized profession. It also clarifies that search filters and sort parameters still apply, but it does not explicitly state the primary 'use this instead of jobs_search when...' rule for ordinary personalized browsing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_searchSearch jobsAInspect
Searches a database for real-time job listings matching the user's criteria.
The query is the full job title or role: "Ruby Developer" rather than a bare keyword like "Ruby", which is too broad and matches unrelated fields. roles_lookup turns words that name no exact role into FoundRole roles with their job counts. Results may be filtered by location, company, and how recently a job was posted.
Each result carries an id and resultItemId; jobs_details takes that id with the corresponding
result_item_id and returns the job's full description, requirements, and benefits. One call returns one answer: there is no next page, and the
response links to the same search on the FoundRole website for the rest of the list.
With a ready profile, a query for the profile's target profession or an omitted query uses the same personalized feed as jobs_recommendations and the website; alternative titles of that same role return that same feed. An account's saved role is reported in every response as savedRole; an omitted query or the saved role's title searches exactly that role. A different or unrecognized profession uses general job search, preserving the explicit query and filters, and leaves the saved role unchanged. A search without a location runs in the place saved on the account, widened to its country when few jobs are posted near that city; an account with no saved place searches where the user is now when the client reports it, otherwise the default country. Such a response names the place searched as searchedPlace. A response for a request that names no exact role can carry a guide question the widget shows to the user. Job details include FoundRole salary benchmarks, H-1B sponsorship signals, E-Verify status, and job-trust analysis; list-level employer signals follow the user's current entitlements.
Constraints in the user's request — remote-only work, H1B sponsorship, a minimum salary, a minimum match grade — are the search parameters remote, h1b_sponsors_only, salary_floor, and min_match; sort orders the results by relevance, newest, salary or personal match. The search enforces only constraints passed as parameters; a constraint left out of the call is not applied to the result set.
Job type, work mode, required education, experience level, benefits, bonuses, employers to include or exclude, and the search radius are the parameters employment_types, work_modes, education, experience_levels, benefits, bonuses_only, companies, exclude_companies and radius. Remote and hybrid are independent work modes: a remote search never returns hybrid jobs. A job that does not state the filtered attribute is left out while that filter is set. One brand inside a company is hiring_brand next to company.
A company name that several employers share covers all of them, and the response names each with its domain; an employer's domain in place of a name (company, companies or exclude_companies) means that employer alone.
When nothing matches, a city search is repeated within 100 miles and the response says so; a search limited by posted_days_ago keeps that limit and reports how many jobs match over a longer period instead of listing them.
Advanced filters (sort, min_match, h1b_sponsors_only, salary_floor, remote, work_modes, benefits, bonuses_only, companies, exclude_companies; sort only when ordering by salary or match, companies only when it names more than one employer) apply for every account. One answer lists the first matching jobs and states how many further jobs match.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Result order (score, posted_at, match, salary): score is relevance and the default, posted_at is newest first, salary is highest pay first, match is best personal fit first and needs a resume. Ordering by salary or match is an advanced option. | |
| query | No | The full job title or skill (e.g., "Ruby Developer", NOT just "Ruby") | |
| radius | No | Search radius in miles around a city location (default 40); not used for state, country or remote searches. | |
| remote | No | Advanced filter: only remote-eligible jobs, matched across the whole country of the requested location rather than its radius. | |
| company | No | The official company name, or the domain of one employer | |
| benefits | No | Advanced filter: benefit names such as "health insurance", "401k" or "parental leave"; a job qualifies only when it states every listed benefit. Names that match no known benefit are ignored. | |
| location | No | Geographic location (e.g., 'Boston, MA') | |
| companies | No | Filter: official company names; a job from any of them qualifies, across every job board each employer posts on. More than one company makes it an advanced filter. Next to company, a job has to match both; hiring_brand narrows company only. | |
| education | No | Filter: jobs whose posting requires one of these education levels (no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree); bachelor_degree means the posting asks for a bachelor degree, not that it suits someone holding one. | |
| min_match | No | Advanced filter: lowest personal FoundRole match grade to keep, the same letter each job shows in insights.match.grade. A and A- are rare even for a strong resume; B keeps good and strong matches; C+ also keeps fair ones. Needs a resume on the account. | |
| work_modes | No | Advanced filter: jobs in any of these work modes (on_site, remote, hybrid). remote is matched across the whole country of the location, the others within the radius. ["remote"] is the same search as remote: true. | |
| bonuses_only | No | Advanced filter: only jobs that state a bonus (sign-on, performance, referral, commission and the like). | |
| hiring_brand | No | Filter: one brand inside the company, for example company "Google" with hiring_brand "YouTube"; used only together with company. | |
| salary_floor | No | Advanced filter: minimum annualized salary in USD; a posting qualifies when the lower bound of its pay band reaches the floor. Jobs without a USD salary are dropped. | |
| posted_days_ago | No | Number of days ago to search for jobs (1-365) | |
| employment_types | No | Filter: jobs offered as any of these employment types (full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other). | |
| exclude_companies | No | Advanced filter: official company names whose jobs are removed from the results, across every job board each employer posts on. | |
| experience_levels | No | Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive, level_not_stated). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years. level_not_stated selects jobs whose level cannot be derived; it can be selected alone or alongside other levels. | |
| h1b_sponsors_only | No | Advanced filter: only companies known to sponsor H1B visas. |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | No | |
| guide | No | |
| preview | No | |
| feedKind | No | |
| savedRole | No | |
| feedStatus | No | |
| continueUrl | No | |
| jobSearchId | No | |
| resultSetId | No | |
| statusOrder | No | |
| revalidating | No | |
| resultBatchId | No | |
| searchedPlace | No | |
| trackerWebUrl | No | |
| profileSetupUrl | No | |
| profileSetupState | No | |
| lowRelevanceNotice | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses behavior well beyond the annotations: saved-role preservation, searchedPlace/savedRole fields in every response, city-to-100-mile fallback and the posted_days_ago widening report, the possible guide question, remote-vs-hybrid independence, exclusion of jobs that don't state a filtered attribute, and entitlement-gated employer signals. None of this is recoverable from readOnlyHint/destructiveHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Roughly 500 words of unstructured, run-on prose with no grouping of the 19 parameters. The final paragraph re-lists the advanced filters (sort, min_match, h1b_sponsors_only, salary_floor, remote, work_modes, benefits, bonuses_only, companies, exclude_companies) that were already explained individually, which is pure redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists and annotations are present, yet the description still carries the genuinely non-obvious parts: personalization rules, fallback widening, and filter gating. Coverage is strong, though the tangle of overlapping rules (personalized feed vs general search vs saved role) is harder to apply than it needs to be, and the readOnlyHint=false annotation for a search is never addressed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real semantic value: it maps user-stated constraints (remote-only, H1B, salary minimum, match grade) onto remote/h1b_sponsors_only/salary_floor/min_match, explains that unpassed constraints are silently not applied, that a shared company name covers all employers while a domain narrows to one, and that hiring_brand modifies company only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource ("Searches a database for real-time job listings") and immediately scopes it against siblings: roles_lookup for vocabulary resolution, jobs_details for full postings, jobs_recommendations for the personalized feed. An agent can route correctly without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit routing rules: use roles_lookup when a word names no exact role, pass `id`/`resultItemId` to jobs_details, and use this tool's personalized path when a profile has a saved role. It also states the non-obvious operating constraints — one call returns one answer with no next page — leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
knowledge_searchSearch career guidesARead-onlyIdempotentInspect
Searches FoundRole's published content by semantic similarity and returns the most relevant sources for a job-search question: career-guidance blog articles plus FoundRole site pages that describe the product's features (job tracker, H1B salary data, AI job search) and industry/sector career landings. Each article carries a title, url, summary, a content excerpt, publication date, and tags; each page carries a title, url, description, and its FAQ entries — enough material to answer the question and link the source.
Two optional facets add further result groups: company returns FoundRole's employer profile pages matching that company name; location returns the market landing page for that city, state, or country — an analytical page about that labour market, not a list of openings. The facets describe what the user is asking about — a company mentioned only in passing does not need the company facet.
Returns empty groups when nothing is relevant rather than padding with off-topic content. Results are the closest matches to the given question, not an index of the site's full coverage; questions about overall topic coverage are answered by knowledge_topics, which lists the blog's categories and tags with article counts. It does not search job listings and reports no open-job counts — jobs_search covers live roles, including questions about openings for a particular job title.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum articles to return (default 5) | |
| query | Yes | The career, job-search, or FoundRole product question to answer | |
| company | No | A company name, when the question is about that employer — returns FoundRole company profile pages | |
| location | No | A city, state, or country, when the question is about that labour market — returns its market landing page |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | No | |
| articles | No | |
| totalCount | No | |
| companyPages | No | |
| landingPages | No | |
| profileSetupUrl | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so safety is covered. The description adds real behavioural context beyond that: empty groups are returned rather than padded with off-topic results, and results are nearest matches rather than an index of site coverage — both affect how an agent should interpret a thin or empty response. It loses a point for spending sentences enumerating returned fields that the output schema already specifies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and corpus, then facets, then exclusions — a logical order with no filler. The enumeration of article and page fields (title, url, summary, excerpt, date, tags) is redundant against the output schema and is the one stretch that does not earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a four-parameter tool with an output schema and full annotation coverage, the description leaves nothing an agent needs unresolved: corpus scope, facet semantics, empty-result behaviour, and sibling routing are all stated. Return-value structure is correctly left to the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters are already documented, giving a baseline of 3. The description does add genuine meaning for the two facets — that `location` returns an analytical labour-market page rather than a list of openings, and that facets map to what the user is actually asking about — but most of that guidance is usage framing rather than per-parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — semantic search over FoundRole's published content — and enumerates exactly what corpus it covers (blog articles, product/feature pages, industry landings, plus company and location facet groups). It is unambiguously separable from jobs_search and knowledge_topics, both of which it names.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-not-to-use routing: jobs_search covers live roles and open-job counts, knowledge_topics covers overall topic coverage. It also gives a decision rule for the optional facets — 'a company mentioned only in passing does not need the company facet' — which is the kind of judgement an agent would otherwise have to guess.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
knowledge_topicsList career guide topicsARead-onlyIdempotentInspect
Lists what FoundRole's published career-guidance blog covers: every category and the most-used tags, each with its published-article count and url, plus the total number of published articles. This is the factual source for questions about the blog's topics or overall coverage. It takes no parameters and reflects the live published corpus. It does not retrieve articles for a specific question; knowledge_search does that.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| tags | No | |
| categories | No | |
| totalArticles | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/closed-world, so the safety profile is covered. The description still adds value beyond them: no parameters, reflects the live published corpus, and summarizes the returned shape (counts, urls, totals). It doesn't discuss pagination or limits, but with zero params and an output schema those gaps are minor.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the resource and scope, then the exclusion and sibling routing. Sentences are long but each carries distinct information — the only mild cost is that the payoff ('what it covers') arrives after a fairly dense clause.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-param read-only listing tool with an output schema and full annotation coverage, the description supplies everything an agent needs: what it returns, that it's live, and which sibling to use for article retrieval.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4; the description correctly reinforces 'It takes no parameters,' removing any doubt that filtering is available. Nothing further is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('lists what FoundRole's published career-guidance blog covers: every category and the most-used tags') and names the distinguishing scope — categories/tags plus counts, not articles. An agent can immediately tell it apart from knowledge_search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says it is 'the factual source for questions about the blog's topics or overall coverage' and names the exclusion plus the alternative: 'It does not retrieve articles for a specific question; knowledge_search does that.' That is the full when/when-not/alternative triad.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profile_role_replaceChange the role I am looking forADestructiveIdempotentInspect
Replaces the roles saved on the user's FoundRole account with the one role the user chose. The previous roles are removed from the account, including a role taken from the user's resume. Recommendations then show the new role's newest jobs in the account's place, and later searches with no title search exactly that role. For an account with no role yet, profile_role_set saves one without removing anything.
| Name | Required | Description | Default |
|---|---|---|---|
| career_profile_id | Yes | The FoundRole role the user chose, as careerProfileId from roles_lookup or a search question |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | |
| success | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, but the description adds specific consequences beyond annotations: previous roles are removed, including a resume-derived role, and recommendations and title-less searches change accordingly. This is exactly the kind of destructive impact detail an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first sentence, followed by relevant destructive consequences and the sibling alternative. Every sentence conveys useful information with no redundant restatement of the tool name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given one parameter, 100% schema coverage, rich annotations, and an output schema, the description supplies the remaining behavioral context an agent needs: what gets removed, how recommendations change, and when to use the alternative tool. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameter is already well documented in the schema, including where careerProfileId comes from. The description adds only a general reference to 'the one role the user chose' and does not meaningfully extend parameter semantics beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: it replaces the roles saved on the user's FoundRole account with one chosen role. It clearly distinguishes itself from the sibling profile_role_set by explaining that replace removes previous roles while set saves one for accounts with no role yet.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly names the alternative profile_role_set and the condition that selects it: an account with no role yet. This gives the agent a clear when-to-use-this-vs-sibling rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
profile_role_setSave the role I am looking forAIdempotentInspect
Saves the one role the user said they are looking for on an account that has no role yet, creating its profile when it has none. Recommendations then show that role's newest jobs in the account's place, and later searches with no title search exactly that role. The FoundRole search panel calls it when the user picks a role there; a role the user names in the chat is saved the same way. It saves only a role the user chose, not a guess from their words. On an account that already has another role it changes nothing and names the saved role; profile_role_replace replaces it.
| Name | Required | Description | Default |
|---|---|---|---|
| career_profile_id | Yes | The FoundRole role the user chose, as careerProfileId from roles_lookup or a search question |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | |
| success | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false), it discloses side effects the annotations cannot: a profile is created when none exists, recommendations and title-less searches are subsequently rewritten to that role, and on an account with another role it is a no-op that names the existing role. That no-op-plus-name return detail is exactly the kind of context annotations omit.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded with the action and scope, and most sentences carry distinct information. A few clauses are slightly redundant — 'a role the user names in the chat is saved the same way' partially restates the 'only a role the user chose' rule — but nothing is wasted enough to obscure the call.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter write tool with annotations and an output schema, the description covers preconditions, side effects, idempotent behavior, return semantics, and the sibling alternative. There is no remaining ambiguity an agent would need to resolve before invoking it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter is already documented as careerProfileId from roles_lookup or a search question. The description still adds real meaning by constraining the value to a user-selected role rather than an inferred one, which is a semantic rule the schema does not encode.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource ('Saves the one role the user said they are looking for') and immediately scopes it to accounts with no role yet. It distinguishes itself from the sibling profile_role_replace by name, so an agent can separate the two without reading schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It names both invocation contexts (the FoundRole search panel and a role named in chat), the precondition (account has no role yet), the explicit exclusion ('saves only a role the user chose, not a guess'), and the fallback behavior plus the alternative tool (profile_role_replace). This is close to a complete decision rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reminder_deleteDelete a reminderBDestructiveInspect
Deletes a reminder from a tracked job.
Input:
tracked_job_id: The tracked job ID —trackedJobs[].idfrom tracker_list output, distinct fromtrackable.idandjob.id(required)
Output: Returns the updated tracked job with reminderAt cleared.
| Name | Required | Description | Default |
|---|---|---|---|
| tracked_job_id | Yes | The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required) |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, and openWorldHint=false, so the safety profile is covered. The description adds one genuinely useful behavioral fact beyond the annotations: the effect is clearing `reminderAt` on the tracked job rather than removing the job. It does not address what happens if no reminder exists, which matters given idempotentHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core sentence is front-loaded and clear, but the Input and Output blocks largely duplicate the input schema's parameter description and the output schema respectively. Those sections dilute rather than sharpen the definition, though the total length remains short.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one required parameter, full schema coverage, an output schema, and annotations, the definition covers the essentials: what it does, which ID to supply, and the resulting state. The remaining gap is failure behavior (deleting a non-existent reminder) for a mutation flagged as non-idempotent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single parameter, so the schema already carries the semantics. The Input section of the description restates the schema text nearly verbatim, adding no syntax, format, or sourcing detail beyond what the schema provides; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Deletes a reminder from a tracked job,' which clearly separates it from sibling verbs like reminder_set or reminder_list without opening a schema. It does not, however, explicitly name an alternative or contrast itself with them, so it stops short of full sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use/when-not-to-use guidance or named alternative (e.g., reminder_set for replacing a reminder). The only guidance is implicit and ID-scoped: the description warns that `tracked_job_id` must come from `tracker_list` output and is distinct from `trackable.id` and `job.id`, which is a partial disambiguation guideline at best.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reminder_listList remindersBRead-onlyInspect
Lists tracked jobs that have reminders set, ordered by reminder time (soonest first).
Input:
limit: Number of results to return (default 20, max 50)
Output: Returns a list of tracked jobs with active reminders.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of results to return (default 20, max 50) |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJobs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description usefully adds the sort order (soonest first) and that only jobs with *active* reminders appear, but says nothing about pagination, total counts, or how to page past the 50-result cap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The lead sentence is front-loaded and earns its place. The Input section duplicates the schema description word-for-word and the Output section restates what the output schema already covers, so roughly a third of the text is redundant padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list with one optional, fully documented parameter and an existing output schema, the description is nearly sufficient — the agent needs no return-value detail. The remaining gap is routing guidance among the many sibling list/search/alert tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single `limit` parameter is fully documented in the schema. The Input block merely restates it verbatim, adding no syntax, ordering, or default behavior beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource with scope ("Lists tracked jobs that have reminders set") plus an ordering guarantee (soonest first), which separates it from tracker_list and jobs_search. It stops short of naming a sibling to prefer or avoid, so it is clear but not fully differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use or when-not-to-use guidance. With siblings like tracker_list and reminder_set/reminder_delete in the same namespace, the description never says which one to pick when an agent wants jobs versus reminders versus alerts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reminder_setSet a follow-up reminderADestructiveInspect
Sets a reminder for a tracked job. Sends a confirmation email with .ics calendar attachment.
Input:
tracked_job_id: The tracked job ID —trackedJobs[].idfrom tracker_list output, distinct fromtrackable.idandjob.id(required)remind_at: Reminder date/time in ISO 8601 format, e.g. "2025-03-15T10:00:00Z" (required, must be in the future)
Output: Returns the updated tracked job with reminderAt field.
| Name | Required | Description | Default |
|---|---|---|---|
| remind_at | Yes | ISO 8601 datetime, e.g. "2025-03-15T10:00:00Z" (must be in the future) | |
| tracked_job_id | Yes | The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required) |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds useful behavioral detail beyond annotations by disclosing the confirmation email with .ics attachment and the returned updated tracked job. However, annotations declare destructiveHint=true and idempotentHint=false, and the description does not explain what may be overwritten/destroyed or how repeated calls behave. This is a gap, but not a contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded, with clear Input and Output sections. It is appropriately sized, though the Input section largely restates information already present in the schema, which is mildly redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter tool with a 100% covered schema and an output schema, the description provides enough context to invoke it correctly. It includes the key side effect and return value, though it could better address the destructive and non-idempotent behaviors signaled by annotations.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents both parameters. The description mirrors the schema's parameter explanations, including the tracked job ID distinction and ISO 8601 future-date requirement, but adds no semantics beyond what is already structured. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: it sets a reminder for a tracked job. This clearly distinguishes it from sibling tools such as reminder_list, reminder_delete, and tracker_update. It also scopes the operation to tracked jobs rather than general jobs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the purpose statement, and the description adds the constraint that remind_at must be in the future. However, it does not explicitly say when to use this versus reminder_list, reminder_delete, or tracker_update, nor does it mention exclusion scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resume_checkCheck how hiring software reads a resumeARead-onlyIdempotentInspect
Checks resume text for machine-readable sections, recognized skills, contact channels, a headline, and experience date ranges using FoundRole's deterministic parser.
Pass resume_text to check plain text supplied in the conversation. If resume_text is omitted, the tool reads the previously extracted text of the primary resume in the authenticated user's FoundRole account. It returns a readability band (strong, good, partial) and the single biggest loss. Depending on the account it also returns additional findings and the parsed facts (headline, years of experience, sections, contact channels, recognized skill count). Each finding includes a suggested fix. A saved report link is returned only when the account already has access to that report. This is FoundRole's text-readability assessment, not a test against a named ATS, a hiring prediction, or a file-layout check. Pasted text does not preserve the original PDF or DOCX layout.
The tool does not upload a file, create a saved resume or report, change the user's profile, submit an application, or fetch URLs found in the text. It may return a FoundRole website link; opening that link and uploading or editing a resume are separate user actions. Operational request records and diagnostics may retain tool inputs; this tool does not promise that submitted text is never stored.
| Name | Required | Description | Default |
|---|---|---|---|
| resume_text | No | Plain text of the resume to check, when it is available in the conversation. Omit to check the resume uploaded to the user's FoundRole account. Minimum 200 characters. |
Output Schema
| Name | Required | Description |
|---|---|---|
| band | No | |
| mode | Yes | |
| findings | No | |
| parsedAs | No | |
| profileSetupUrl | No | |
| studioReportUrl | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive, and closed-world behavior. The description adds crucial context: deterministic parsing, return composition (readability band, biggest loss, additional findings, parsed facts, suggested fix), conditional saved report link, and explicit data retention caveats—far beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized into logical paragraphs, front-loading purpose and usage before return values and limitations. However, it is somewhat verbose for a single-parameter tool, with a long list of negations and a privacy caveat that could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite an output schema existing, the description provides a clear summary of return values. It also covers prerequisites, limitations, and privacy considerations, making it fully complete for an agent to call the tool correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the parameter is fully documented in the schema. The description adds modest value by contrasting 'plain text supplied in the conversation' with 'previously extracted text of the primary resume,' but the fallback behavior is largely already specified in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (checks) and resource (resume text) with precise scope: machine-readable sections, skills, contact channels, headline, and date ranges. It distinguishes itself from siblings (job alerts, searches, profile, etc.) by being the only resume readability tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to pass resume_text versus omit it, and clarifies what the tool is not (not an ATS test, hiring prediction, or layout check). It also lists operations it does not perform (upload, create, change, submit, fetch), leaving no ambiguity about boundaries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roles_lookupLook up rolesARead-onlyIdempotentInspect
Matches the user's own words for the work they want against FoundRole's role list and returns up to 5 roles with open jobs, each with its number of open jobs in the place's state or country, most jobs first, plus the role already saved on the account. It runs no job search and changes nothing on the account. jobs_search returns the jobs for a role.
| Name | Required | Description | Default |
|---|---|---|---|
| words | Yes | The user's own words for the work they want, such as "analyst" or "nurse in a clinic" | |
| location | No | Place to count open jobs in (e.g., 'Austin, TX'); the account's place when omitted |
Output Schema
| Name | Required | Description |
|---|---|---|
| roles | No | |
| region | No | |
| savedRole | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover read-only, idempotent, non-destructive, and closed-world; the description adds genuinely new behavioral facts: result cap of 5, sort order (most jobs first), that counts are scoped to the place's state or country, that the saved role is appended, and that no job search is run. That is substantive context beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Compact and front-loaded: the core action and output come first, then the exclusion and the sibling pointer. Slightly awkward line wrapping and a somewhat overloaded second sentence keep it from a perfect score, but no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain return values, and it still covers scope, ordering, caps, and the side-effect profile. For a two-parameter lookup tool, an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and both parameters are documented in the schema, so the baseline applies. The description adds only a small amount — that 'location' drives an open-job count scoped to a state or country rather than a filter — and adds nothing about the 'words' free-text matching behavior (e.g., matching tolerance, max length).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('matches the user's own words ... against FoundRole's role list') and describes the output shape (up to 5 roles, open-job counts, saved role included). It explicitly names the sibling it is not ('jobs_search returns the jobs for a role'), so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Clearly implies the trigger condition (user describes work in their own words) and explicitly excludes job search, pointing to jobs_search as the alternative. What's missing is an explicit 'use this when the user hasn't named a role yet' framing, but the routing is unambiguous in practice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_addSave a job to the trackerAIdempotentInspect
Tracks a job from jobs_search results in the user's job tracker, identified by its job_id. For a job found elsewhere on the open web (with a URL but no jobs_search job_id), tracker_add_external is the right tool instead.
Fields:
job_id: the job ID from jobs_search results (required)status: initial 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_companynotes: notes about the job
Returns the tracked job with its details. Repeated saves return the existing tracked job. A job that was previously removed from the tracker is restored with its earlier status and notes.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | Notes about this job | |
| job_id | Yes | The job ID from jobs.search results | |
| status | No | Initial tracking status: saved, applied, interviewing, offered, archived | |
| sub_status | No | 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 | |
| result_item_id | No | The result occurrence ID returned with the selected job |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and destructiveHint=false, and the description reinforces this ('repeated saves return the existing tracked job'). More valuable is the non-obvious disclosure that a previously removed job is restored with its earlier status and notes — a side effect an agent could not infer from annotations. It stops short of covering auth or rate-limit behavior, so not 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and the sibling routing rule are front-loaded in the first two sentences, which is the right ordering. The long sub_status enumeration duplicates the schema description nearly verbatim and inflates length, but the field list is otherwise tight and each remaining sentence (idempotency, restore behavior) carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values need not be explained, and the description still summarizes the return shape. Idempotency, restoration semantics, and the external-tool alternative are all covered, so an agent has enough to call it correctly; only the undocumented result_item_id parameter and lack of permission context leave a small gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is already 100%, so the baseline is 3, but the description adds the default value ('status defaults to "saved"') which the schema does not state, plus an enumeration of valid status values in one place. It omits the schema's result_item_id parameter entirely, keeping it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (tracks/saves) and resource (a job from jobs_search results into the user's job tracker), with the identifying key (job_id) named up front. It explicitly differentiates itself from the sibling tracker_add_external, so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit when-to-use and when-not-to-use: jobs with a jobs_search job_id go here, while jobs found on the open web (URL, no job_id) must go to tracker_add_external. That is a concrete routing rule to the correct sibling, not just implied context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_add_externalSave a job from another site to the trackerAIdempotentInspect
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 datesalary_currency: ISO 4217 currency codesalary_type: one of year, month, week, day, houremployment_type: array of full_time, part_time, contractor, temporary, intern, volunteer, per_diem, otherwork_location_type: one of on_site, remote, hybrideducation_requirements: array of no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degreeexperience_months: minimum required experience in months (number)client_extraction: evidence-backed extraction object; fields without source evidence are omittedstatus: 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_companynotes: notes about the job
Returns the tracked job. Repeated saves return the existing tracked job.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Direct URL of the specific job posting; a company homepage is invalid | |
| notes | No | Notes about this job | |
| status | No | Initial tracking status: saved, applied, interviewing, offered, archived | |
| posted_at | No | Posting date as ISO 8601, when the source states it | |
| sub_status | No | 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 | |
| title_name | Yes | Job title from the posting | |
| description | Yes | Complete posting text available in the conversation; a source summary is valid only when no fuller posting text is available | |
| salary_type | No | Salary period: year, month, week, day, hour | |
| company_name | Yes | Company name from the posting | |
| salary_value | No | Single salary amount, when the posting gives one figure instead of a range | |
| location_name | Yes | Location text from the posting, including Remote when stated | |
| employment_type | No | Employment types: full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other | |
| salary_currency | No | ISO 4217 salary currency code, when stated | |
| salary_max_value | No | Salary range maximum, when stated | |
| salary_min_value | No | Salary range minimum, when stated | |
| client_extraction | No | 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. | |
| experience_months | No | Minimum required experience in months, when stated | |
| work_location_type | No | Work arrangement: on_site, remote, hybrid | |
| education_requirements | No | Education requirements: no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes beyond annotations by disclosing that a save never waits on facts the source omits, that FoundRole extractors derive missing salary/employment/education/skills, that client_extraction labels are validated and stored separately, and that repeated saves return the existing record (reinforcing idempotentHint). No auth or rate-limit context, but the mutation/extraction behavior is well covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The opening two paragraphs are tight and front-loaded, but the extended field enumeration largely restates a schema that already has 100% description coverage, repeating enums verbatim. Structured well, yet noticeably longer than it needs to be for an agent that will read the schema anyway.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 19-parameter mutation tool, the description covers required vs optional fields, the derivation/omission policy, the client_extraction evidence contract, and idempotent re-save behavior; return values are covered by the output schema. Nothing an agent needs in order to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds genuine meaning: status 'defaults to saved', the fact that non-source facts are simply omitted or null, and that the description field accepts a short summary. The bulk of the field list duplicates schema enums, so it does not reach the top of the scale.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('saves a job posting found anywhere on the open web into the user's tracker') with explicit scope, and directly names the sibling it is not (tracker_add, which takes a job_id). An agent can distinguish it from tracker_add without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use the alternative ('For jobs that came from jobs_search results, tracker_add ... is the right tool instead') and removes a common false prerequisite ('needs no prior jobs_search call'). Both the selection condition and the exclusion are spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_listList tracked jobsBRead-onlyInspect
Lists the user's tracked jobs with optional filtering and pagination.
Input:
status: Filter by status (saved, applied, interviewing, offered, archived)limit: Number of results per page (default 20, max 50)offset: Number of results to skip (default 0)
Output: Returns a list of tracked jobs grouped by status with pagination info.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of results per page (default 20, max 50) | |
| offset | No | Number of results to skip (default 0) | |
| status | No | Filter by status: saved, applied, interviewing, offered, archived |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered. The description adds that results come back grouped by status with pagination info, but nothing about empty results, ordering, or default sorting behavior — modest added value above the annotations rather than rich behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose line is front-loaded and the Input/Output sections are easy to scan. However, the Input block duplicates schema text that is already fully documented, so a portion of the content does not earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description needn't detail return values, and the annotations cover safety. Combined with full schema coverage, the definition is nearly complete; only usage routing against sibling list/search tools is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the description repeats the three parameters nearly verbatim (including the same default/max notes). No extra semantics such as filter-combination behavior or what happens when status is omitted are provided, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Lists the user's tracked jobs') plus the scope of optional filtering and pagination. The read-vs-mutate distinction from siblings like tracker_add and tracker_update_status is obvious, though it never explicitly distinguishes itself from adjacent read tools such as jobs_search or job_alert_list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use or when-not-to-use guidance and names no alternative, despite living among several similar listing/search tools (jobs_search, job_alert_list, reminder_list). The only steer is the implied 'optional' nature of the filters, which an agent must infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_removeRemove a job from the trackerADestructiveInspect
Removes a job from the user's job tracker.
Input:
tracked_job_id: The tracked job ID —trackedJobs[].idfrom tracker_list output, distinct fromtrackable.idandjob.id(required)
Output: Confirms the job was removed from tracking.
| Name | Required | Description | Default |
|---|---|---|---|
| tracked_job_id | Yes | The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required) |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, non-idempotent, non-read-only, so the safety profile is covered. The description adds only that the operation is confirmed on completion; it does not disclose whether removal is reversible, whether it requires the job to exist, or what happens on repeat calls — useful context given destructiveHint.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action, then cleanly sectioned into Input and Output. Slight redundancy: the Input block duplicates the schema description word-for-word, and the Output line restates what an output schema already conveys.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a single fully documented required parameter, an output schema, and annotations carrying the destructive/idempotency profile, little is missing. The gap is the absence of any note on reversibility or precondition behavior worth having for a destructive single-target operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description's Input block reproduces the schema text verbatim, so no meaning is added beyond the structured field. Baseline 3 applies when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (removes) and resource (a job from the user's job tracker), and the intent is unambiguous against siblings like tracker_add, tracker_update, and tracker_list. An agent can distinguish the removal operation without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No statement of when to use this versus tracker_update or tracker_update_status, and no prerequisites or conditions. The only routing help is implicit — the ID distinction hints that tracker_list should be consulted first, but that is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_updateUpdate a tracked jobADestructiveInspect
Updates details of a tracked job (notes, deadline, salary, tags).
Input:
tracked_job_id: The tracked job ID —trackedJobs[].idfrom tracker_list output, distinct fromtrackable.idandjob.id(required)notes: Updated notesdeadline: Deadline date (ISO 8601 format)salary_offered: Salary amountsalary_offered_type: Salary type: year, month, week, day, hourtags: Comma-separated tags (e.g., "remote,startup,tech")reminder_at: Reminder date/time in ISO 8601 format, e.g. "2025-03-15T10:00:00Z" (must be in the future, or empty to clear)
Output: Returns the updated tracked job.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Comma-separated tags (e.g., "remote,startup,tech") | |
| notes | No | Notes about this job | |
| deadline | No | Deadline date in ISO 8601 format | |
| reminder_at | No | ISO 8601 datetime, e.g. "2025-03-15T10:00:00Z" (must be in the future, or empty to clear) | |
| salary_offered | No | Salary amount | |
| tracked_job_id | Yes | The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required) | |
| salary_offered_type | No | Salary type: year, month, week, day, hour |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=false, so the safety profile is carried by structured data. The description adds modest value by listing the mutable fields and the reminder 'must be in the future, or empty to clear' rule, but it never addresses the key non-idempotent-update question: whether omitting a field preserves or clears it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The header/Input/Output structure front-loads the operation and the fields, and the required ID guidance comes first. It is somewhat verbose because it duplicates the schema field descriptions line for line, but nothing is incoherent or buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter mutation tool with full schema coverage and an output schema, the description covers the required ID sourcing, the field set, and the one datetime constraint. The main remaining gap is partial-update semantics for omitted fields, which matters given idempotentHint=false.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already documented in the schema, and the description largely restates those same descriptions verbatim. It adds no new syntax, format, or interaction detail beyond what the schema provides, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (updates a tracked job) and enumerates which fields can be changed, which implicitly separates it from tracker_update_status and tracker_remove. It never names those siblings explicitly, so the differentiation is inferable rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It usefully tells the agent where the required ID comes from (tracker_list output) and warns it is distinct from trackable.id and job.id, which is real guidance. However, there is no explicit when-to-use vs tracker_update_status, nor any statement of when not to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_update_statusMove a tracked job to another stageCDestructiveInspect
Updates the status of a tracked job.
Input:
tracked_job_id: The tracked job ID —trackedJobs[].idfrom tracker_list output, distinct fromtrackable.idandjob.id(required)status: New status: saved, applied, interviewing, offered, archived (required)sub_status: Sub-status within the main status, valid only for that status (optional): 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
Output: Returns the updated tracked job.
| Name | Required | Description | Default |
|---|---|---|---|
| status | Yes | New status: saved, applied, interviewing, offered, archived | |
| sub_status | No | 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 | |
| tracked_job_id | Yes | The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required) |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true, readOnlyHint=false and idempotentHint=false, so the safety profile is covered by structured data. The description does add one genuinely useful behavioral constraint — that sub_status is 'valid only for that status' — plus the fact that the updated tracked job is returned. It does not say whether the prior status is lost, whether the transition is reversible, or any auth requirements, but with rich annotations a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in one clean sentence, but the 'Input' section re-enumerates every parameter and its full enum value list, all of which already exist verbatim in the schema. That duplication roughly triples the length without adding information, which is padding rather than concision.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description is not obligated to describe return values, and annotations carry the safety profile, so the core coverage is adequate. The missing piece is routing: for a status-mutation tool sitting beside tracker_update, the absence of any when-to-use guidance leaves the main decision an agent faces unresolved.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description restates the parameter list essentially verbatim from the schema, adding no syntax, format, or edge-case guidance beyond what is already structured — notably it does not explain what happens if a mismatched sub_status is supplied.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific verb and resource ('Updates the status of a tracked job'), and the title adds the 'move to another stage' framing, which separates it from tracker_update. However, it never explicitly names tracker_update or explains what that sibling does differently, so the differentiation is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to use this tool versus the many siblings, most notably tracker_update and tracker_add. The description only lists inputs and outputs; an agent must guess whether status changes belong here or in tracker_update.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
13 tool updates
v1.1.19- Changed
job_alert_list2 fields changed- added
Output schema / properties / jobAlerts / items / properties / deliveryAdded value: +{ + "type": "string" +} - added
Output schema / properties / jobAlerts / items / properties / fastActiveAdded value: +{ + "type": "boolean" +}
- Changed
job_alert_subscribe3 fields changed- added
Input schema / properties / deliveryAdded value: +{ + "description": "Delivery mode: digest, fast; fast is not available on every account and needs a qualifying search", + "type": "string" +} - added
Output schema / properties / jobAlert / properties / deliveryAdded value: +{ + "type": "string" +} - added
Output schema / properties / jobAlert / properties / fastActiveAdded value: +{ + "type": "boolean" +}
- Changed
jobs_analyze_external5 fields changed- removed
Output schema / properties / jobs / items / properties / companyRatingRemoved value: -{ - "type": [ - "number", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / insights / properties / employerFilingHistoryAdded value: +{ + "properties": { + "attribution": { + "enum": [ + "FILED_BY" + ], + "type": "string" + }, + "availability": { + "enum": [ + "AVAILABLE", + "NO_FILINGS", + "UNRESOLVED_EMPLOYER", + "NOT_READY" + ], + "type": "string" + }, + "bindingStatus": { + "enum": [ + "LEGACY_UNREVIEWED", + "UNRESOLVED" + ], + "type": "string" + }, + "coverage": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "current": { + "properties": { + "filings": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "workerPositions": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "currentPeriod": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "history": { + "properties": { + "access": { + "enum": [ + "AVAILABLE", + "RESTRICTED", + "UNAVAILABLE" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "points": { + "items": { + "properties": { + "filings": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "period": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "workerPositions": { + "type": "integer" + } + }, + "type": "object" + }, + "type": [ + "array", + "null" + ] + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "subject": { + "properties": { + "domain": { + "type": "string" + }, + "domainDictionaryId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] + }, + "wageLevel": { + "properties": { + "availability": { + "enum": [ + "AVAILABLE", + "NO_FILINGS", + "INSUFFICIENT_SAMPLE", + "NOT_STATED", + "NOT_READY", + "UNRESOLVED_EMPLOYER" + ], + "type": "string" + }, + "breakdown": { + "properties": { + "level1Pct": { + "type": [ + "number", + "null" + ] + }, + "level2Pct": { + "type": [ + "number", + "null" + ] + }, + "level3Pct": { + "type": [ + "number", + "null" + ] + }, + "level4Pct": { + "type": [ + "number", + "null" + ] + }, + "notStatedPct": { + "type": [ + "number", + "null" + ] + } + }, + "type": [ + "object", + "null" + ] + }, + "id": { + "type": "string" + }, + "period": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "sampleSize": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / jobs / items / properties / lastSeenAtAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / jobs / items / properties / trackerInput / properties / location_name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - removed
Output schema / properties / system_instructionRemoved value: -{ - "type": [ - "string", - "null" - ] -}
- Changed
jobs_compare5 fields changed- removed
Output schema / properties / jobs / items / properties / companyRatingRemoved value: -{ - "type": [ - "number", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / insights / properties / employerFilingHistoryAdded value: +{ + "properties": { + "attribution": { + "enum": [ + "FILED_BY" + ], + "type": "string" + }, + "availability": { + "enum": [ + "AVAILABLE", + "NO_FILINGS", + "UNRESOLVED_EMPLOYER", + "NOT_READY" + ], + "type": "string" + }, + "bindingStatus": { + "enum": [ + "LEGACY_UNREVIEWED", + "UNRESOLVED" + ], + "type": "string" + }, + "coverage": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "current": { + "properties": { + "filings": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "workerPositions": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "currentPeriod": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "history": { + "properties": { + "access": { + "enum": [ + "AVAILABLE", + "RESTRICTED", + "UNAVAILABLE" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "points": { + "items": { + "properties": { + "filings": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "period": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "workerPositions": { + "type": "integer" + } + }, + "type": "object" + }, + "type": [ + "array", + "null" + ] + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "subject": { + "properties": { + "domain": { + "type": "string" + }, + "domainDictionaryId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] + }, + "wageLevel": { + "properties": { + "availability": { + "enum": [ + "AVAILABLE", + "NO_FILINGS", + "INSUFFICIENT_SAMPLE", + "NOT_STATED", + "NOT_READY", + "UNRESOLVED_EMPLOYER" + ], + "type": "string" + }, + "breakdown": { + "properties": { + "level1Pct": { + "type": [ + "number", + "null" + ] + }, + "level2Pct": { + "type": [ + "number", + "null" + ] + }, + "level3Pct": { + "type": [ + "number", + "null" + ] + }, + "level4Pct": { + "type": [ + "number", + "null" + ] + }, + "notStatedPct": { + "type": [ + "number", + "null" + ] + } + }, + "type": [ + "object", + "null" + ] + }, + "id": { + "type": "string" + }, + "period": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "sampleSize": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / jobs / items / properties / lastSeenAtAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / jobs / items / properties / trackerInput / properties / location_name / typePrevious value: -"string"New value: +[ + "string", + "null" +] - removed
Output schema / properties / system_instructionRemoved value: -{ - "type": [ - "string", - "null" - ] -}
- Changed
jobs_details5 fields changed- added
Input schema / properties / job_id / minLengthAdded value: +1 - removed
Output schema / properties / job / properties / companyRatingRemoved value: -{ - "type": [ - "number", - "null" - ] -} - added
Output schema / properties / job / properties / insights / properties / employerFilingHistoryAdded value: +{ + "properties": { + "attribution": { + "enum": [ + "FILED_BY" + ], + "type": "string" + }, + "availability": { + "enum": [ + "AVAILABLE", + "NO_FILINGS", + "UNRESOLVED_EMPLOYER", + "NOT_READY" + ], + "type": "string" + }, + "bindingStatus": { + "enum": [ + "LEGACY_UNREVIEWED", + "UNRESOLVED" + ], + "type": "string" + }, + "coverage": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "current": { + "properties": { + "filings": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "workerPositions": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "currentPeriod": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "history": { + "properties": { + "access": { + "enum": [ + "AVAILABLE", + "RESTRICTED", + "UNAVAILABLE" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "points": { + "items": { + "properties": { + "filings": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "period": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "workerPositions": { + "type": "integer" + } + }, + "type": "object" + }, + "type": [ + "array", + "null" + ] + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "subject": { + "properties": { + "domain": { + "type": "string" + }, + "domainDictionaryId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] + }, + "wageLevel": { + "properties": { + "availability": { + "enum": [ + "AVAILABLE", + "NO_FILINGS", + "INSUFFICIENT_SAMPLE", + "NOT_STATED", + "NOT_READY", + "UNRESOLVED_EMPLOYER" + ], + "type": "string" + }, + "breakdown": { + "properties": { + "level1Pct": { + "type": [ + "number", + "null" + ] + }, + "level2Pct": { + "type": [ + "number", + "null" + ] + }, + "level3Pct": { + "type": [ + "number", + "null" + ] + }, + "level4Pct": { + "type": [ + "number", + "null" + ] + }, + "notStatedPct": { + "type": [ + "number", + "null" + ] + } + }, + "type": [ + "object", + "null" + ] + }, + "id": { + "type": "string" + }, + "period": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "sampleSize": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / job / properties / lastSeenAtAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / job / properties / sourceAdded value: +{ + "enum": [ + "external", + "foundrole" + ], + "type": "string" +}
- Changed
jobs_recommendations17 fields changed- changed
Input schema / properties / company / descriptionPrevious value: -"The official company name"New value: +"The official company name, or the domain of one employer" - removed
Input schema / properties / confirmed_work_fromRemoved value: -{ - "description": "Advanced filter: with strict_remote, also leaves out postings that do not say where the work can be done from.", - "type": "boolean" -} - changed
Input schema / properties / experience_levels / descriptionPrevious value: -"Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years."New value: +"Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive, level_not_stated). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years. level_not_stated selects jobs whose level cannot be derived; it can be selected alone or alongside other levels." - changed
Input schema / properties / experience_levels / items / enumPrevious value: -[ - "entry_level", - "mid_level", - "senior_level", - "executive" -]New value: +[ + "entry_level", + "mid_level", + "senior_level", + "executive", + "level_not_stated" +] - removed
Input schema / properties / hide_low_qualityRemoved value: -{ - "description": "Advanced filter: hides postings with a risky ghost grade (D/F); ungraded postings stay.", - "type": "boolean" -} - removed
Input schema / properties / pageRemoved value: -{ - "description": "Recommendation page number", - "minimum": 1, - "type": "integer" -} - removed
Input schema / properties / strict_remoteRemoved value: -{ - "description": "Advanced filter: only postings checked as fully remote that can be worked from the requested location: the posting names that area, allows anywhere, or does not say where. Stricter than remote; work_modes other than remote do not apply with it.", - "type": "boolean" -} - changed
Output schema / properties / feedStatus / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / guideAdded value: +{ + "properties": { + "otherLabel": { + "type": "string" + }, + "otherPrompt": { + "type": "string" + }, + "steps": { + "items": { + "type": "object" + }, + "type": "array" + } + }, + "type": [ + "object", + "null" + ] +} - removed
Output schema / properties / jobs / items / properties / companyRatingRemoved value: -{ - "type": [ - "number", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / insights / properties / employerFilingHistoryAdded value: +{ + "properties": { + "attribution": { + "enum": [ + "FILED_BY" + ], + "type": "string" + }, + "availability": { + "enum": [ + "AVAILABLE", + "NO_FILINGS", + "UNRESOLVED_EMPLOYER", + "NOT_READY" + ], + "type": "string" + }, + "bindingStatus": { + "enum": [ + "LEGACY_UNREVIEWED", + "UNRESOLVED" + ], + "type": "string" + }, + "coverage": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "current": { + "properties": { + "filings": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "workerPositions": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "currentPeriod": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "history": { + "properties": { + "access": { + "enum": [ + "AVAILABLE", + "RESTRICTED", + "UNAVAILABLE" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "points": { + "items": { + "properties": { + "filings": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "period": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "workerPositions": { + "type": "integer" + } + }, + "type": "object" + }, + "type": [ + "array", + "null" + ] + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "subject": { + "properties": { + "domain": { + "type": "string" + }, + "domainDictionaryId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] + }, + "wageLevel": { + "properties": { + "availability": { + "enum": [ + "AVAILABLE", + "NO_FILINGS", + "INSUFFICIENT_SAMPLE", + "NOT_STATED", + "NOT_READY", + "UNRESOLVED_EMPLOYER" + ], + "type": "string" + }, + "breakdown": { + "properties": { + "level1Pct": { + "type": [ + "number", + "null" + ] + }, + "level2Pct": { + "type": [ + "number", + "null" + ] + }, + "level3Pct": { + "type": [ + "number", + "null" + ] + }, + "level4Pct": { + "type": [ + "number", + "null" + ] + }, + "notStatedPct": { + "type": [ + "number", + "null" + ] + } + }, + "type": [ + "object", + "null" + ] + }, + "id": { + "type": "string" + }, + "period": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "sampleSize": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / jobs / items / properties / lastSeenAtAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / jobs / items / properties / sourceAdded value: +{ + "enum": [ + "external", + "foundrole" + ], + "type": "string" +} - added
Output schema / properties / lowRelevanceNoticeAdded value: +{ + "type": [ + "string", + "null" + ] +} - removed
Output schema / properties / nextPageRemoved value: -{ - "type": [ - "integer", - "null" - ] -} - added
Output schema / properties / savedRoleAdded value: +{ + "properties": { + "careerProfileId": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "usedForThisSearch": { + "type": "boolean" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / searchedPlaceAdded value: +{ + "properties": { + "name": { + "type": "string" + }, + "source": { + "enum": [ + "account", + "current", + "default" + ], + "type": "string" + } + }, + "type": [ + "object", + "null" + ] +}
- Changed
jobs_search15 fields changed- changed
Input schema / properties / company / descriptionPrevious value: -"The official company name"New value: +"The official company name, or the domain of one employer" - removed
Input schema / properties / confirmed_work_fromRemoved value: -{ - "description": "Advanced filter: with strict_remote, also leaves out postings that do not say where the work can be done from.", - "type": "boolean" -} - removed
Input schema / properties / cursorRemoved value: -{ - "description": "Pagination cursor. Treat as an opaque string. COPY EXACTLY.", - "type": "string" -} - changed
Input schema / properties / experience_levels / descriptionPrevious value: -"Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years."New value: +"Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive, level_not_stated). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years. level_not_stated selects jobs whose level cannot be derived; it can be selected alone or alongside other levels." - changed
Input schema / properties / experience_levels / items / enumPrevious value: -[ - "entry_level", - "mid_level", - "senior_level", - "executive" -]New value: +[ + "entry_level", + "mid_level", + "senior_level", + "executive", + "level_not_stated" +] - removed
Input schema / properties / hide_low_qualityRemoved value: -{ - "description": "Advanced filter: hides postings with a risky ghost grade (D/F); ungraded postings stay.", - "type": "boolean" -} - removed
Input schema / properties / strict_remoteRemoved value: -{ - "description": "Advanced filter: only postings checked as fully remote that can be worked from the requested location: the posting names that area, allows anywhere, or does not say where. Stricter than remote; work_modes other than remote do not apply with it.", - "type": "boolean" -} - added
Output schema / properties / guideAdded value: +{ + "properties": { + "otherLabel": { + "type": "string" + }, + "otherPrompt": { + "type": "string" + }, + "steps": { + "items": { + "type": "object" + }, + "type": "array" + } + }, + "type": [ + "object", + "null" + ] +} - removed
Output schema / properties / jobs / items / properties / companyRatingRemoved value: -{ - "type": [ - "number", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / insights / properties / employerFilingHistoryAdded value: +{ + "properties": { + "attribution": { + "enum": [ + "FILED_BY" + ], + "type": "string" + }, + "availability": { + "enum": [ + "AVAILABLE", + "NO_FILINGS", + "UNRESOLVED_EMPLOYER", + "NOT_READY" + ], + "type": "string" + }, + "bindingStatus": { + "enum": [ + "LEGACY_UNREVIEWED", + "UNRESOLVED" + ], + "type": "string" + }, + "coverage": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "current": { + "properties": { + "filings": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "workerPositions": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "currentPeriod": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "history": { + "properties": { + "access": { + "enum": [ + "AVAILABLE", + "RESTRICTED", + "UNAVAILABLE" + ], + "type": "string" + }, + "id": { + "type": "string" + }, + "points": { + "items": { + "properties": { + "filings": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "period": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "workerPositions": { + "type": "integer" + } + }, + "type": "object" + }, + "type": [ + "array", + "null" + ] + } + }, + "type": "object" + }, + "id": { + "type": "string" + }, + "subject": { + "properties": { + "domain": { + "type": "string" + }, + "domainDictionaryId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": [ + "object", + "null" + ] + }, + "wageLevel": { + "properties": { + "availability": { + "enum": [ + "AVAILABLE", + "NO_FILINGS", + "INSUFFICIENT_SAMPLE", + "NOT_STATED", + "NOT_READY", + "UNRESOLVED_EMPLOYER" + ], + "type": "string" + }, + "breakdown": { + "properties": { + "level1Pct": { + "type": [ + "number", + "null" + ] + }, + "level2Pct": { + "type": [ + "number", + "null" + ] + }, + "level3Pct": { + "type": [ + "number", + "null" + ] + }, + "level4Pct": { + "type": [ + "number", + "null" + ] + }, + "notStatedPct": { + "type": [ + "number", + "null" + ] + } + }, + "type": [ + "object", + "null" + ] + }, + "id": { + "type": "string" + }, + "period": { + "properties": { + "complete": { + "type": "boolean" + }, + "coveredQuarters": { + "items": { + "properties": { + "fiscalYear": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "quarter": { + "type": "integer" + } + }, + "type": "object" + }, + "type": "array" + }, + "endFiscalYear": { + "type": "integer" + }, + "endQuarter": { + "type": "integer" + }, + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "startFiscalYear": { + "type": "integer" + }, + "startQuarter": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] + }, + "sampleSize": { + "type": "integer" + } + }, + "type": "object" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / jobs / items / properties / lastSeenAtAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / jobs / items / properties / sourceAdded value: +{ + "enum": [ + "external", + "foundrole" + ], + "type": "string" +} - added
Output schema / properties / savedRoleAdded value: +{ + "properties": { + "careerProfileId": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "usedForThisSearch": { + "type": "boolean" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / searchedPlaceAdded value: +{ + "properties": { + "name": { + "type": "string" + }, + "source": { + "enum": [ + "account", + "current", + "default" + ], + "type": "string" + } + }, + "type": [ + "object", + "null" + ] +} - removed
Output schema / properties / system_instructionRemoved value: -{ - "type": "string" -}
- Changed
knowledge_search2 fields changed- removed
Output schema / properties / proUrlRemoved value: -{ - "type": [ - "string", - "null" - ] -} - removed
Output schema / properties / system_instructionRemoved value: -{ - "type": "string" -}
- Changed
knowledge_topics1 field changed- removed
Output schema / properties / system_instructionRemoved value: -{ - "type": "string" -}
- Added
profile_role_replace - Added
profile_role_set - Changed
resume_check4 fields changed- added
Output schema / properties / findings / items / properties / fixAdded value: +{ + "type": "string" +} - added
Output schema / properties / profileSetupUrlAdded value: +{ + "type": [ + "string", + "null" + ] +} - removed
Output schema / properties / system_instructionRemoved value: -{ - "type": "string" -} - removed
Output schema / properties / uploadUrlRemoved value: -{ - "type": [ - "string", - "null" - ] -}
- Added
roles_lookup
8 tool updates
v1.1.16- Changed
jobs_analyze_external4 fields changed- removed
Output schema / properties / jobs / items / properties / estimatedSalary / properties / basedOnRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / estimatedSalary / properties / currencyAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / studioUrlAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / system_instructionAdded value: +{ + "type": [ + "string", + "null" + ] +}
- Changed
jobs_compare4 fields changed- removed
Output schema / properties / jobs / items / properties / estimatedSalary / properties / basedOnRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / estimatedSalary / properties / currencyAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / studioUrlAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / system_instructionAdded value: +{ + "type": [ + "string", + "null" + ] +}
- Changed
jobs_details6 fields changed- added
Input schema / properties / result_item_idAdded value: +{ + "description": "The result occurrence ID returned with the selected job", + "type": "string" +} - removed
Output schema / properties / job / properties / estimatedSalary / properties / basedOnRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / job / properties / estimatedSalary / properties / currencyAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / job / properties / remoteCheckAdded value: +{ + "properties": { + "quotes": { + "items": { + "properties": { + "source": { + "type": "string" + }, + "text": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "workFrom": { + "properties": { + "allowedPlaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "excludedPlaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "quotes": { + "items": { + "properties": { + "source": { + "type": "string" + }, + "text": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "scope": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / job / properties / resultItemIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / studioUrlAdded value: +{ + "type": [ + "string", + "null" + ] +}
- Changed
jobs_recommendations30 fields changed- added
Input schema / properties / benefitsAdded value: +{ + "description": "Advanced filter: benefit names such as \"health insurance\", \"401k\" or \"parental leave\"; a job qualifies only when it states every listed benefit. Names that match no known benefit are ignored.", + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" +} - added
Input schema / properties / bonuses_onlyAdded value: +{ + "description": "Advanced filter: only jobs that state a bonus (sign-on, performance, referral, commission and the like).", + "type": "boolean" +} - added
Input schema / properties / companiesAdded value: +{ + "description": "Filter: official company names; a job from any of them qualifies, across every job board each employer posts on. More than one company makes it an advanced filter. Next to company, a job has to match both; hiring_brand narrows company only.", + "items": { + "type": "string" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / companyAdded value: +{ + "description": "The official company name", + "type": "string" +} - added
Input schema / properties / confirmed_work_fromAdded value: +{ + "description": "Advanced filter: with strict_remote, also leaves out postings that do not say where the work can be done from.", + "type": "boolean" +} - added
Input schema / properties / educationAdded value: +{ + "description": "Filter: jobs whose posting requires one of these education levels (no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree); bachelor_degree means the posting asks for a bachelor degree, not that it suits someone holding one.", + "items": { + "enum": [ + "no_requirements", + "high_school", + "associate_degree", + "bachelor_degree", + "professional_certificate", + "postgraduate_degree" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / employment_typesAdded value: +{ + "description": "Filter: jobs offered as any of these employment types (full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other).", + "items": { + "enum": [ + "full_time", + "part_time", + "contractor", + "temporary", + "intern", + "volunteer", + "per_diem", + "other" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / exclude_companiesAdded value: +{ + "description": "Advanced filter: official company names whose jobs are removed from the results, across every job board each employer posts on.", + "items": { + "type": "string" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / experience_levelsAdded value: +{ + "description": "Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years.", + "items": { + "enum": [ + "entry_level", + "mid_level", + "senior_level", + "executive" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / h1b_sponsors_onlyAdded value: +{ + "description": "Advanced filter: only companies known to sponsor H1B visas.", + "type": "boolean" +} - added
Input schema / properties / hide_low_qualityAdded value: +{ + "description": "Advanced filter: hides postings with a risky ghost grade (D/F); ungraded postings stay.", + "type": "boolean" +} - added
Input schema / properties / hiring_brandAdded value: +{ + "description": "Filter: one brand inside the company, for example company \"Google\" with hiring_brand \"YouTube\"; used only together with company.", + "type": "string" +} - changed
Input schema / properties / location / descriptionPrevious value: -"Optional preferred location name or slug"New value: +"Geographic location (e.g., 'Boston, MA')" - added
Input schema / properties / min_matchAdded value: +{ + "description": "Advanced filter: lowest personal FoundRole match grade to keep, the same letter each job shows in insights.match.grade. A and A- are rare even for a strong resume; B keeps good and strong matches; C+ also keeps fair ones. Needs a resume on the account.", + "enum": [ + "A", + "A-", + "B+", + "B", + "B-", + "C+", + "C" + ], + "type": "string" +} - added
Input schema / properties / posted_days_agoAdded value: +{ + "description": "Number of days ago to search for jobs (1-365)", + "maximum": 365, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / queryAdded value: +{ + "description": "The full job title or skill (e.g., \"Ruby Developer\", NOT just \"Ruby\")", + "type": "string" +} - added
Input schema / properties / radiusAdded value: +{ + "description": "Search radius in miles around a city location (default 40); not used for state, country or remote searches.", + "maximum": 100, + "minimum": 5, + "type": "integer" +} - added
Input schema / properties / remoteAdded value: +{ + "description": "Advanced filter: only remote-eligible jobs, matched across the whole country of the requested location rather than its radius.", + "type": "boolean" +} - added
Input schema / properties / salary_floorAdded value: +{ + "description": "Advanced filter: minimum annualized salary in USD; a posting qualifies when the lower bound of its pay band reaches the floor. Jobs without a USD salary are dropped.", + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / sortAdded value: +{ + "description": "Result order (score, posted_at, match, salary): score is relevance and the default, posted_at is newest first, salary is highest pay first, match is best personal fit first and needs a resume. Ordering by salary or match is an advanced option.", + "enum": [ + "score", + "posted_at", + "match", + "salary" + ], + "type": "string" +} - added
Input schema / properties / strict_remoteAdded value: +{ + "description": "Advanced filter: only postings checked as fully remote that can be worked from the requested location: the posting names that area, allows anywhere, or does not say where. Stricter than remote; work_modes other than remote do not apply with it.", + "type": "boolean" +} - added
Input schema / properties / work_modesAdded value: +{ + "description": "Advanced filter: jobs in any of these work modes (on_site, remote, hybrid). remote is matched across the whole country of the location, the others within the radius. [\"remote\"] is the same search as remote: true.", + "items": { + "enum": [ + "on_site", + "remote", + "hybrid" + ], + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / continueUrlAdded value: +{ + "type": "string" +} - removed
Output schema / properties / jobs / items / properties / estimatedSalary / properties / basedOnRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / estimatedSalary / properties / currencyAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / jobs / items / properties / relatedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / jobs / items / properties / resultItemIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / previewAdded value: +{ + "properties": { + "continueUrl": { + "type": [ + "string", + "null" + ] + }, + "hidden": { + "type": "integer" + }, + "hiddenAtLeast": { + "type": "boolean" + }, + "shown": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / resultBatchIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / resultSetIdAdded value: +{ + "type": [ + "string", + "null" + ] +}
- Changed
jobs_search30 fields changed- added
Input schema / properties / benefitsAdded value: +{ + "description": "Advanced filter: benefit names such as \"health insurance\", \"401k\" or \"parental leave\"; a job qualifies only when it states every listed benefit. Names that match no known benefit are ignored.", + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" +} - added
Input schema / properties / bonuses_onlyAdded value: +{ + "description": "Advanced filter: only jobs that state a bonus (sign-on, performance, referral, commission and the like).", + "type": "boolean" +} - added
Input schema / properties / companiesAdded value: +{ + "description": "Filter: official company names; a job from any of them qualifies, across every job board each employer posts on. More than one company makes it an advanced filter. Next to company, a job has to match both; hiring_brand narrows company only.", + "items": { + "type": "string" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / confirmed_work_fromAdded value: +{ + "description": "Advanced filter: with strict_remote, also leaves out postings that do not say where the work can be done from.", + "type": "boolean" +} - added
Input schema / properties / educationAdded value: +{ + "description": "Filter: jobs whose posting requires one of these education levels (no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree); bachelor_degree means the posting asks for a bachelor degree, not that it suits someone holding one.", + "items": { + "enum": [ + "no_requirements", + "high_school", + "associate_degree", + "bachelor_degree", + "professional_certificate", + "postgraduate_degree" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / employment_typesAdded value: +{ + "description": "Filter: jobs offered as any of these employment types (full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other).", + "items": { + "enum": [ + "full_time", + "part_time", + "contractor", + "temporary", + "intern", + "volunteer", + "per_diem", + "other" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / exclude_companiesAdded value: +{ + "description": "Advanced filter: official company names whose jobs are removed from the results, across every job board each employer posts on.", + "items": { + "type": "string" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / experience_levelsAdded value: +{ + "description": "Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years.", + "items": { + "enum": [ + "entry_level", + "mid_level", + "senior_level", + "executive" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / hiring_brandAdded value: +{ + "description": "Filter: one brand inside the company, for example company \"Google\" with hiring_brand \"YouTube\"; used only together with company.", + "type": "string" +} - changed
Input schema / properties / min_match / descriptionPrevious value: -"Advanced filter: minimum personal FoundRole match score (0-100); needs a resume on the account."New value: +"Advanced filter: lowest personal FoundRole match grade to keep, the same letter each job shows in insights.match.grade. A and A- are rare even for a strong resume; B keeps good and strong matches; C+ also keeps fair ones. Needs a resume on the account." - added
Input schema / properties / min_match / enumAdded value: +[ + "A", + "A-", + "B+", + "B", + "B-", + "C+", + "C" +] - removed
Input schema / properties / min_match / maximumRemoved value: -100 - removed
Input schema / properties / min_match / minimumRemoved value: -0 - changed
Input schema / properties / min_match / typePrevious value: -"integer"New value: +"string" - added
Input schema / properties / radiusAdded value: +{ + "description": "Search radius in miles around a city location (default 40); not used for state, country or remote searches.", + "maximum": 100, + "minimum": 5, + "type": "integer" +} - changed
Input schema / properties / remote / descriptionPrevious value: -"Advanced filter: only remote-eligible jobs (respects the location/region scope)."New value: +"Advanced filter: only remote-eligible jobs, matched across the whole country of the requested location rather than its radius." - changed
Input schema / properties / salary_floor / descriptionPrevious value: -"Advanced filter: minimum annualized salary in USD; a posting qualifies when the midpoint of its pay band reaches the floor. Jobs without salary data are dropped."New value: +"Advanced filter: minimum annualized salary in USD; a posting qualifies when the lower bound of its pay band reaches the floor. Jobs without a USD salary are dropped." - added
Input schema / properties / sortAdded value: +{ + "description": "Result order (score, posted_at, match, salary): score is relevance and the default, posted_at is newest first, salary is highest pay first, match is best personal fit first and needs a resume. Ordering by salary or match is an advanced option.", + "enum": [ + "score", + "posted_at", + "match", + "salary" + ], + "type": "string" +} - added
Input schema / properties / strict_remoteAdded value: +{ + "description": "Advanced filter: only postings checked as fully remote that can be worked from the requested location: the posting names that area, allows anywhere, or does not say where. Stricter than remote; work_modes other than remote do not apply with it.", + "type": "boolean" +} - added
Input schema / properties / work_modesAdded value: +{ + "description": "Advanced filter: jobs in any of these work modes (on_site, remote, hybrid). remote is matched across the whole country of the location, the others within the radius. [\"remote\"] is the same search as remote: true.", + "items": { + "enum": [ + "on_site", + "remote", + "hybrid" + ], + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / continueUrlAdded value: +{ + "type": "string" +} - removed
Output schema / properties / jobs / items / properties / estimatedSalary / properties / basedOnRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / estimatedSalary / properties / currencyAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / jobs / items / properties / relatedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / jobs / items / properties / resultItemIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / previewAdded value: +{ + "properties": { + "continueUrl": { + "type": [ + "string", + "null" + ] + }, + "hidden": { + "type": "integer" + }, + "hiddenAtLeast": { + "type": "boolean" + }, + "shown": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] +} - removed
Output schema / properties / proFilterUpsellUrlRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / resultBatchIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / resultSetIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / system_instructionAdded value: +{ + "type": "string" +}
- Changed
knowledge_search4 fields changed- removed
Input schema / properties / job_titleRemoved value: -{ - "description": "A job title or role, when the question is about openings for it — returns job-listing landing pages", - "type": "string" -} - changed
Input schema / properties / location / descriptionPrevious value: -"A city, state, or country refining job_title, or alone when the question is about jobs in that place"New value: +"A city, state, or country, when the question is about that labour market — returns its market landing page" - removed
Output schema / properties / companyPages / items / properties / openJobsRemoved value: -{ - "type": [ - "integer", - "null" - ] -} - removed
Output schema / properties / landingPages / items / properties / openJobsRemoved value: -{ - "type": [ - "integer", - "null" - ] -}
- Added
resume_check - Changed
tracker_add1 field changed- added
Input schema / properties / result_item_idAdded value: +{ + "description": "The result occurrence ID returned with the selected job", + "type": "string" +}
20 tool updates
v1.1.9- First observed
job_alert_list - First observed
job_alert_subscribe - First observed
job_alert_unsubscribe - First observed
job_alert_unsubscribe_all - First observed
jobs_analyze_external - First observed
jobs_compare - First observed
jobs_details - First observed
jobs_recommendations - First observed
jobs_search - First observed
knowledge_search - First observed
knowledge_topics - First observed
reminder_delete - First observed
reminder_list - First observed
reminder_set - First observed
tracker_add - First observed
tracker_add_external - First observed
tracker_list - First observed
tracker_remove - First observed
tracker_update - First observed
tracker_update_status
TDQS
Scored across 24 tools
Most tools target a clearly distinct resource+action, and closely related pairs (tracker_add vs tracker_add_external, jobs_search vs jobs_recommendations vs roles_lookup, profile_role_set vs profile_role_replace) are explicitly cross-referenced in their descriptions. The main soft spot is reminder handling: reminders can be set/cleared both via reminder_set/reminder_delete and via the reminder_at field on tracker_update, which an agent could reasonably confuse.
The server follows a consistent resource-prefix convention (tracker_*, reminder_*, job_alert_*, jobs_*, knowledge_*, profile_role_*) with snake_case throughout, so grouping is predictable. A few names break the verb suffix pattern (jobs_details, jobs_recommendations, knowledge_topics are noun-only or noun_noun), which is a minor deviation rather than a real inconsistency.
At 24 tools this sits at the heavy end of the scale for what is essentially a job-search plus tracker product. Each sub-domain (resume check, tracker CRUD, reminders, alerts, search/details/analysis, knowledge) is coherent, but some consolidation is plausible — for example folding the three reminder tools into the tracker tools and merging the two unsubscribe variants into one with an optional flag.
Coverage is strong across the stated domain: search, detail fetch, personalized recommendations, external job analysis and comparison, full tracker lifecycle, reminders, alerts, profile role management, resume readability, and knowledge/content lookup. Minor gaps exist — there is no tool to list or manage saved searches directly (only via job_alert_list), no resume ingestion/update, and no application-material generation — but these are workable around.
Maintenance
Related MCP Connectors
Job search for your AI: save jobs, research companies, keep stories, track applications.
Your own job search in any AI: next steps, matches, résumés, applications, reminders. Free.
Manage job applications — jobs, companies, boards, notes, and profile — from your AI client.
AI job matching in your assistant: ranked offers, tailored resumes, application tracking.
Related MCP Servers
- AlicenseAqualityCmaintenanceAn MCP server for searching UK tech jobs from the winterchill catalog, enabling job search, company lookup, and CV matching/tailoring via LLM agents.6MIT

Civify MCP Serverofficial
AlicenseAqualityBmaintenanceEnables AI agents to parse resumes, tailor CVs, score ATS compatibility, redact PII, scrape job postings, and track applications through a career platform.818 npmAGPL 3.0
hirly MCP serverofficial
AlicenseNot gradedqualityCmaintenanceConnects an AI assistant to a job-matching account so it can read roles matched to your resume, pull full job details and hiring contacts, and save tailored resume versions. With explicit opt-in and per-job confirmation in the chat, it can also start applications, relay questions only you can answer, and report each application's status.MIT
Dreamwork MCP Serverofficial
AlicenseAqualityBmaintenanceEnables AI clients to browse public job listings, save and rank roles into a pipeline, tailor resumes and cover letters, submit applications, and track replies, interviews, and escalations over time. Works anonymously for job browsing or with a scoped API key for full account, apply, and recruiter-outreach capabilities.7414MIT