Skip to main content
Glama
CaseyTTS

Bullhorn MCP Agent

by CaseyTTS

Bullhorn MCP Agent

A Python Model Context Protocol (MCP) server for Bullhorn, extended into a recruiting-domain operating layer for AI agents and enterprise workflows.

This project began from the open-source osherai/bullhorn-mcp-python project and has been substantially expanded with tenant-aware schema mapping, per-user Bullhorn authentication, controlled writes, recruiting activity models, audit and approval controls, and agent-oriented workflow tooling.

The goal is to provide a governed layer between AI systems and Bullhorn rather than giving a model direct access to credentials, unrestricted REST endpoints, or tenant-specific business logic.


Current Status

This project is currently in active POC and test-stage development.

It is not yet distributed for production use.

The current focus is validating:

  • authentication and session isolation

  • tenant configuration and mapping

  • permission boundaries

  • recruiting-domain semantics

  • safe read/write patterns

  • auditability

  • security controls

  • historical analytics architecture

  • enterprise Workspace integration

Bullhorn remains the system of record.


Related MCP server: HireFrog MCP

What This Project Is Becoming

This is no longer just a thin REST wrapper around Bullhorn.

The MCP is being developed as a recruiting-domain operating layer that sits between AI systems and Bullhorn.

Its responsibilities include:

  • authenticating users

  • isolating Bullhorn sessions

  • enforcing permissions

  • translating canonical recruiting concepts into tenant-specific Bullhorn fields

  • validating workflows

  • controlling writes

  • auditing actions

  • exposing structured recruiting data

  • supporting analytics and historical intelligence

  • keeping the model away from raw credentials and unrestricted API access

Conceptually:

ChatGPT Workspace / AI Agent
            |
            | MCP
            v
Bullhorn Recruiting Orchestrator
    |
    |-- Authentication / session isolation
    |-- Permissions
    |-- Tenant mappings
    |-- Canonical recruiting schema
    |-- Safe reads
    |-- Controlled writes
    |-- Approval gates
    |-- Audit
    |-- Activity / analytics
    |
    | Bullhorn REST API
    v
Bullhorn

License

License: Source-available for self-use, internal organizational use, modification, forking, and open development. Resale, white-labeling, commercial packaging, or offering the software itself as a paid hosted service requires prior express written permission. Portions derived from upstream MIT-licensed projects remain subject to their original licenses.

See LICENSE (CaseyTTS Source-Available No-Resale License 1.0) and THIRD_PARTY_LICENSES/ for the preserved upstream MIT License of osherai/bullhorn-mcp-python. This license is not an OSI-approved open-source license.

Available Tools

23 tools
bullhorn_sessionA

Show, start, complete or end your own Bullhorn sign-in for this workspace.

Sign-in happens in your browser through Bullhorn (including SSO/MFA); never give passwords or MFA codes to the assistant. After the browser step, the page shows a one-time code: the user enters it here with action="complete_link".

Args: action: "status" (default), "login" (returns a sign-in link), "complete_link" (finish linking with the code from the browser page) or "logout". confirmation: The one-time code from the browser page; only for "complete_link".

Returns: JSON with the session status, the sign-in link, {"linked": true} or {"logged_out": true}.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionNostatus
confirmationNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does it well: it explains the out-of-band browser/SSO/MFA flow, warns never to hand passwords or MFA codes to the assistant, and describes what each action yields. It omits session lifetime/expiry and what happens to existing sessions on login, which are the main remaining behavioral gaps.

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

Conciseness4/5

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

Front-loaded with the purpose, then structured Args/Returns sections; every line earns its place, including the security warning. The blank-line layout is slightly airy but not wasteful.

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

Completeness5/5

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

For a two-parameter session tool with an output schema present, the description covers purpose, per-action semantics, the security constraint, and a brief return summary. An agent has everything needed to call it correctly without further context.

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

Parameters5/5

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

Schema coverage is 0%, and the description fully compensates: it gives the default for action, lists all four allowed values, and explains that confirmation is the one-time code from the browser page and applies only to complete_link. That is more than the schema contains.

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

Purpose4/5

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

The description states a specific verb set and resource ('Show, start, complete or end your own Bullhorn sign-in for this workspace'), so the tool's job is unambiguous. It does not, however, name or contrast itself with plausible siblings like connection_status or setup_status, leaving the boundary to inference.

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

Usage Guidelines4/5

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

Each action value is enumerated with its purpose (status default, login returns a link, complete_link finishes with the browser code, logout), which tells the agent exactly which mode to pick. It stops short of explicit when-not guidance or routing versus the sibling status tools.

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

commit_mapping_changesA

Approve or reject a stored proposal. The actor comes from BULLHORN_MCP_ACTOR.

Args: proposal_id: The proposal_id returned by propose_mapping_changes. diff_hash: The diff_hash returned by propose_mapping_changes. decision: "approve" or "reject".

Returns: JSON with status (committed, rejected or refused), version (on commit) and correlation_id.

ParametersJSON Schema
NameRequiredDescriptionDefault
decisionYes
diff_hashYes
proposal_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations at all, the description carries the full burden and does meaningfully better than average: it discloses the auth source (BULLHORN_MCP_ACTOR), the permitted decision values, and the three possible outcome statuses including 'refused', which hints at a safety/consistency guard around diff_hash. It does not explain what triggers 'refused', whether the proposal is consumed or reusable after commit, or whether the operation is idempotent.

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

Conciseness4/5

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

Cleanly structured into a summary line, an Args block, and a Returns block, with the purpose front-loaded. The repeated 'returned by propose_mapping_changes' phrasing is slightly redundant, but nothing is padded.

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

Completeness4/5

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

For a three-param mutation tool with no annotations, it covers arguments, precondition, caller identity, and outcomes. An output schema exists so the Returns recap is optional rather than required; the remaining gap is the absence of failure/refusal conditions and post-commit state of the proposal.

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

Parameters5/5

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

Schema coverage is 0%, so the description must carry all parameter meaning and does: it documents all three required params, gives provenance for proposal_id and diff_hash, and supplies the effectively-enumerated 'approve'/'reject' domain for decision, which the schema omits entirely. This is close to full compensation for the coverage gap.

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

Purpose5/5

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

States a specific verb pair (approve/reject) applied to a specific resource (a stored proposal), and explicitly ties that proposal to the sibling tool propose_mapping_changes. An agent can distinguish this from propose_mapping_changes and other mapping tools without opening the schema.

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

Usage Guidelines4/5

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

The provenance of proposal_id and diff_hash ('returned by propose_mapping_changes') makes the ordering precondition clear: this tool is called after a proposal exists. There is no explicit statement of when NOT to call it (e.g. proposal already committed, hash stale), so it falls 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.

confirm_writeA

Approve or reject a previewed write. The approver comes from BULLHORN_MCP_ACTOR.

The write runs only if the preview_hash matches, the preview has not expired or been used, the actor is allowed, the scope and setup gate still hold, and nothing previewed has changed (otherwise: refused, e.g. stale_preview).

Args: operation_id: The operation_id returned by the preview. preview_hash: The preview_hash returned by the preview. decision: "approve" or "reject".

Returns: JSON with the normalized write result (status committed, partially_committed, failed, failed_orphan, rejected or refused).

ParametersJSON Schema
NameRequiredDescriptionDefault
decisionYes
operation_idYes
preview_hashYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so well: it discloses the authorization source (BULLHORN_MCP_ACTOR), idempotency semantics (preview must not be expired or already used), staleness protection (hash match and unchanged content), and the refusal path with an example error code. The enumerated result statuses (partially_committed, failed_orphan) also hint at non-atomic failure modes an agent must handle.

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

Conciseness4/5

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

Well front-loaded: purpose in the first sentence, then gating conditions, then args and returns. The Returns block partly restates what the output schema already provides, which is the only mildly expendable content.

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

Completeness5/5

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 spelled out, yet the description still summarizes the status vocabulary. Combined with prerequisites, actor provenance, and failure modes, nothing material is missing for correctly invoking a confirmation/commit tool.

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

Parameters5/5

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

Schema coverage is 0%, so the description must compensate, and it does: it explains that operation_id and preview_hash come from the preview response, and it supplies the accepted decision values ('approve'/'reject') that the schema itself leaves as an unconstrained string. All three parameters gain meaning beyond the bare typed properties.

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

Purpose5/5

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

Names a specific action pair (approve/reject) on a precisely scoped resource ('a previewed write'), which no sibling tool claims. An agent immediately understands this is the confirmation step of a preview-then-commit flow, not a direct write tool.

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

Usage Guidelines4/5

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

The description makes the prerequisite flow clear: the operation_id and preview_hash must have been produced by a prior preview, and it enumerates the exact gate conditions under which the write proceeds. It stops short of naming the preview tool explicitly or stating what to do when the preview is missing, so it falls just under fully explicit routing guidance.

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

connection_statusA

Check whether Bullhorn API credentials are configured and connectivity is available.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

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

No annotations are supplied, so the description carries the full burden, and it does disclose the two things being probed (credential configuration and connectivity), implying a safe read-only operation with no side effects. It says nothing about required permissions, failure semantics, or network behaviour, which for a zero-parameter, annotation-free tool is thin but not seriously deficient given an output schema exists.

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

Conciseness5/5

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

A single sentence with no filler, and the core action ('Check') is front-loaded. Nothing here is redundant or padding.

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

Completeness4/5

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

The tool is trivially simple — no parameters, no nesting, and an output schema that already explains the return values — so the description does not need to cover return shape or outcomes. The only real omission is routing guidance relative to sibling diagnostics, which is a usage rather than a completeness gap.

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

Parameters4/5

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

The tool takes zero parameters, so there is nothing for the description to disambiguate. Baseline 4 applies, and the schema is trivially complete.

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

Purpose4/5

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

The description gives a specific verb-and-object pair — checking whether Bullhorn API credentials are configured and connectivity is available — which is far more precise than the bare name 'connection_status'. It does not, however, differentiate itself from near-neighbour diagnostics such as setup_status or bullhorn_session, which an agent would reasonably confuse it with.

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

Usage Guidelines2/5

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

No when-to-use, when-not-to-use, or alternative routing is stated. The diagnostic framing implies a pre-flight check, but with setup_status and bullhorn_session in the sibling set the agent is given no basis to choose between them.

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

create_noteA

Create a Bullhorn note through the safe-write pipeline (preview by default).

With dry_run=True (the default) nothing is written to Bullhorn: the result holds operation_id and preview_hash. Execute exactly that preview with confirm_write(operation_id, preview_hash, "approve"). dry_run=False is accepted only when BULLHORN_NOTE_CREATE_MODE=direct. Writing requires the note.create scope (BULLHORN_ENABLED_WRITE_SCOPES) and BULLHORN_MCP_ACTOR.

Args: target_type: The person the note is about: "candidate" or "client_contact". target_id: The record id of the target. action_type: A tenant note action value (exact; never substituted). comments: The note text (1 to 10,000 characters; stored unchanged). associations: Additional records, each {"type": ..., "id": ...} (at most 10). idempotency_key: Optional caller key (kept 7 days) that prevents a duplicate write. dry_run: Preview only (default true).

Returns: JSON with operation, status, entity_type, record_id, associations, targets, activity, correlation_id, and operation_id/preview_hash for a preview.

ParametersJSON Schema
NameRequiredDescriptionDefault
dry_runNo
commentsYes
target_idYes
action_typeYes
target_typeYes
associationsNo
idempotency_keyNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so: it discloses that nothing is written while previewing, that a preview must be confirmed, the required note.create scope and BULLHORN_MCP_ACTOR, and the 7-day idempotency retention. These are exactly the safety and auth traits an agent needs before calling a mutation tool.

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

Conciseness4/5

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

Front-loaded with the pipeline behavior and default, then organized into Args and Returns sections. Slightly redundant because dry_run's default is stated in the opening paragraph and again in Args, but the surplus is small and every line carries information.

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

Completeness5/5

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

For a mutation tool requiring auth scopes and an environment gate, the description covers the write pipeline, preconditions, parameter constraints, and a return summary. An output schema exists, so the return paragraph is a bonus rather than a necessity, and nothing needed 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.

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate, and it does: target_type enumerates the allowed values, comments gives a 1–10,000 character bound and 'stored unchanged', associations caps at 10 with a shape, idempotency_key states its 7-day dedupe role, and dry_run restates the default. All 7 parameters gain meaning beyond their bare titles.

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

Purpose5/5

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

States a specific verb+resource ('Create a Bullhorn note') and qualifies it with the mechanism ('through the safe-write pipeline'), which immediately separates it from siblings like get_notes and confirm_write. An agent can identify the operation without opening the schema.

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

Usage Guidelines5/5

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

Explicitly explains the default behavior (dry_run=True previews, writes nothing), the follow-up path (execute exactly that preview with confirm_write(operation_id, preview_hash, "approve")), and the precondition for a direct write (dry_run=False only when BULLHORN_NOTE_CREATE_MODE=direct). This is a full when/when-not/alternative routing.

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

discover_schemaA

Discover the tenant's Bullhorn field metadata (metadata only; no record data, no samples).

Writes the local discovery snapshot and drift report; never changes mappings and never writes to Bullhorn.

Args: entities: Canonical or Bullhorn entity names to discover (default: every catalog entity).

Returns: JSON with per-entity summaries and the drift report.

ParametersJSON Schema
NameRequiredDescriptionDefault
entitiesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does so well: it discloses that the tool writes a local discovery snapshot and drift report while never modifying mappings or writing to Bullhorn, which is the key side-effect distinction an agent needs. It stops short of covering auth requirements, API-call volume, or failure behavior.

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

Conciseness4/5

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

Front-loaded purpose sentence followed by clearly separated side-effect, Args, and Returns sections; every line is short and scannable. The Returns section is largely redundant with the existing output schema and could be trimmed.

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

Completeness4/5

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

For a single-optional-param tool with an output schema already documenting the return shape, the description covers purpose, scope limits, side effects, and the parameter's default. Missing auth/prerequisite notes are minor given the tool's simplicity.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must compensate, and it does: 'entities: Canonical or Bullhorn entity names to discover (default: every catalog entity)' explains both the accepted naming schemes and the default-all behavior. It does not describe what form the names take (e.g. delimiter or casing), so it is not fully exhaustive.

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

Purpose5/5

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

States a specific verb and resource ('Discover the tenant's Bullhorn field metadata') and immediately bounds the scope with '(metadata only; no record data, no samples)', which cleanly separates it from data-querying siblings like query_entities, search_entities, and find_records. An agent can identify exactly what this returns without opening the schema.

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

Usage Guidelines3/5

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

The negative guidance ('no record data, no samples', 'never writes to Bullhorn') implies the intended use and rules out looking here for records, but there is no explicit 'use this when' or named alternative such as get_mapping_profile or connection_status. Usage is inferable rather than stated.

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

find_recordsA

Find canonical records of one entity with structured, AND-combined filters.

Only canonical names are accepted (never Bullhorn field names or query text). Every filter is applied exactly; a filter, operator or sort without a verified Bullhorn mechanism returns status "unsupported" and nothing is read.

Args: entity: candidate, job, submission, placement, client_corporation, client_contact, appointment or user. filters: 0 to 10 objects {"field": , "op": , "value": ...}. Operators by type: id/reference eq, in; string eq, in, is_null; boolean eq; integer/number eq, in, gt, gte, lt, lte; datetime gte, lt, is_null (ISO-8601 with offset, or a date = midnight in the reporting timezone). "in" takes 1 to 50 values. concept: Optional tenant concept (e.g. client_submission, interview_completed, offer_extended): only records whose current value matches the tenant's mapping. fields: 1 to 30 canonical field names to return (default: a standard set). sort: {"field", "direction"}; no sort is verified yet (returns "unsupported"). include_deleted: Include deleted records (default false; not verified, returns "unsupported"). limit: 1 to 100 (default 25). cursor: The next_cursor of a previous call with the same arguments.

Returns: JSON with status, entity, records, count, truncated, complete, next_cursor, consistency, reporting_timezone, provenance and warnings.

ParametersJSON Schema
NameRequiredDescriptionDefault
sortNo
limitNo
cursorNo
entityYes
fieldsNo
conceptNo
filtersNo
include_deletedNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does so well: it discloses that unsupported filters/operators/sorts return status 'unsupported' with nothing read, that include_deleted is unverified, default limit of 25, and cursor-based paging. It does not cover auth/permission requirements, but the failure-mode transparency is strong.

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

Conciseness4/5

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

Front-loaded with purpose, then cleanly sectioned into Args and Returns. Length is justified by 8 undocumented parameters, and each line carries information, though the Returns block restates what the existing output schema already defines.

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

Completeness4/5

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

For a complex 8-parameter, zero-schema-coverage tool the description is nearly complete, covering inputs and failure semantics. An output schema exists so the return-value enumeration is redundant rather than essential, leaving little genuinely missing.

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

Parameters5/5

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

Schema coverage is 0%, so the description must compensate and does: it enumerates entity values, documents the filters object shape and the valid operators per value type, 'in' bounds (1-50), fields range (1-30), concept semantics, sort shape, include_deleted default, limit range (1-100) and cursor reuse. This adds meaning far beyond the bare schema.

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

Purpose4/5

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

States a specific verb+resource ('Find canonical records of one entity') with an AND-combined filter scope. It implicitly distinguishes itself from query-based siblings by specifying 'Only canonical names are accepted (never Bullhorn field names or query text)', though it never names search_entities or query_entities directly.

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

Usage Guidelines3/5

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

Usage is implied through the constraint that only canonical field names (not query text) are accepted, which steers an agent away from the query-style siblings. However, it never explicitly says when to prefer find_records over search_entities or query_entities, leaving the routing decision to inference.

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

get_activityA

Read recruiting activity events, one independent block per concept.

Needs scope_type + scope_id, or both date_from and date_to (an unscoped range is at most 366 days). Business concepts (client_submission, interviews, offers) come only from the tenant's configured mappings; a missing definition returns "definition_missing", an unverified mechanism "unsupported" (never guessed).

Args: concepts: 1 to 8 concept IDs (e.g. job_created, submission_created, client_submission, interview_scheduled, interview_completed, placement_created, note_created). scope_type: candidate, job, client_corporation, client_contact, placement or submission. scope_id: The record id for scope_type (required with it). recruiter_id: A user id; filters on each concept's attribution field. date_from: Inclusive ISO-8601 date or datetime with offset. date_to: Exclusive ISO-8601 date or datetime with offset. limit: 1 to 200 events per concept (default 50). cursor: The next_cursor of a previous call with the same arguments.

Returns: JSON with status, concepts (per-concept blocks), next_cursor, reporting_timezone, provenance and warnings.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNo
date_toNo
conceptsYes
scope_idNo
date_fromNo
scope_typeNo
recruiter_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the full behavioral burden and does well: it documents pagination (cursor must be 'the next_cursor of a previous call with the same arguments'), limits, and status values returned for missing/unverified concepts. It stops short of stating permission/auth requirements or rate limits, so it is strong but not exhaustive.

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

Conciseness4/5

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

Front-loads the core operation and constraint in the first two sentences, then uses labeled Args/Returns sections for reference detail. The argument enumeration is somewhat long, but given 0% schema coverage the detail is earned rather than padding.

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

Completeness5/5

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

For an 8-parameter tool with no annotations, the definition covers scoping, date bounds, pagination, filtering, concept-resolution edge cases, and the return shape (status, concepts, next_cursor, reporting_timezone, provenance, warnings). Combined with the existing output schema, 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.

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate and it does: every one of the 8 parameters is explained, including allowed concept examples, the enumerated scope_type values, recruiter_id's attribution semantics, the inclusive date_from vs exclusive date_to distinction, the 1-200 limit default, and the same-arguments constraint on cursor. This adds meaning the bare schema cannot convey.

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

Purpose4/5

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

States a specific verb and resource ('Read recruiting activity events') plus a distinctive shape ('one independent block per concept'), so the agent knows it returns grouped event data rather than a flat list. It does not explicitly contrast itself with near siblings like get_notes or get_recruiting_metrics, so sibling 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.

Usage Guidelines4/5

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

Gives clear preconditions: 'Needs scope_type + scope_id, or both date_from and date_to (an unscoped range is at most 366 days).' It also explains the failure modes (definition_missing vs unsupported, 'never guessed'), which is effectively when-not guidance. It lacks an explicit 'use X instead' routing to a sibling, keeping it below a 5.

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

get_candidateA

Get details for a specific candidate by ID.

Args: candidate_id: The Candidate ID fields: Comma-separated fields to return (default: all common fields)

Returns: JSON object with candidate details

ParametersJSON Schema
NameRequiredDescriptionDefault
fieldsNo
candidate_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

No annotations are provided, so the description carries full responsibility. It states it returns a JSON object with candidate details, implying a read operation. However, it does not mention error handling, permissions, or idempotency specifics, though the basic read behavior is clear.

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

Conciseness5/5

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

The description is concise and well-structured with 'Args' and 'Returns' sections. Every sentence is informative, with no redundant content.

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

Completeness4/5

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

Given the presence of an output schema (not shown) and two well-described parameters, the description is mostly complete for a basic get operation. However, it could mention the typical workflow (e.g., use 'list_candidates' to obtain IDs) and provide some error handling notes.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate. It explains 'candidate_id' as 'The Candidate ID' and 'fields' as 'Comma-separated fields to return (default: all common fields)', adding meaningful semantics beyond the schema's titles and types.

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

Purpose5/5

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

The description clearly states 'Get details for a specific candidate by ID,' using a specific verb and resource. It distinguishes from siblings like 'list_candidates' and 'get_job' by targeting a single candidate via ID.

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

Usage Guidelines3/5

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

The description implies usage when you have a candidate ID but does not explicitly state when to use this tool versus alternatives like 'list_candidates' to find IDs. No exclusions or alternative recommendations are provided.

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

get_candidate_filesB

List file attachments for a Bullhorn Candidate.

ParametersJSON Schema
NameRequiredDescriptionDefault
candidate_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior3/5

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

No annotations are provided, so the description carries the burden, but 'List' at least signals a non-mutating read and an output schema covers the return shape. It discloses nothing about pagination, result limits, or permission requirements for accessing candidate attachments.

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

Conciseness5/5

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

A single front-loaded sentence with no filler; the resource and scope are stated immediately and nothing extraneous is included.

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

Completeness3/5

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

For a one-parameter read tool with an output schema, the definition is minimally adequate: returns need not be described, and the single parameter is self-explanatory. It still omits pagination, limits, and any indication of when listing attachments is the right call versus its siblings.

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

Parameters3/5

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

Schema coverage is 0% for the single candidate_id parameter, but the name and integer type are largely self-evident. The description only reinforces that the identifier refers to a Bullhorn candidate, adding marginal meaning beyond the schema.

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

Purpose4/5

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

States a specific verb (List) and resource (file attachments) scoped to a parent entity (Bullhorn Candidate), which separates it from sibling reads like get_candidate and from the write-side upload_candidate_resume. It is clear and unambiguous, though it does not explicitly name which sibling to prefer.

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

Usage Guidelines2/5

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

There is no when-to-use guidance, no prerequisite information, and no reference to alternative tools such as get_candidate (metadata) or upload_candidate_resume (mutation). The agent must infer the appropriate context entirely.

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

get_jobA

Get details for a specific job order by ID.

Args: job_id: The JobOrder ID fields: Comma-separated fields to return (default: all common fields)

Returns: JSON object with job details

ParametersJSON Schema
NameRequiredDescriptionDefault
fieldsNo
job_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior3/5

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

No annotations provided, so description carries the burden. It states the return type (JSON object) but does not mention error handling (e.g., job not found), authentication requirements, or side effects. For a simple read tool, it is minimally adequate.

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

Conciseness5/5

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

The description is very concise, using a docstring format with Args and Returns sections. It is front-loaded with the purpose and contains no redundant words.

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

Completeness4/5

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

Given the tool's simplicity (2 params, no pagination), the description covers input and output adequately. An output schema exists. It could mention behavior on missing job ID, but overall it is sufficiently complete.

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

Parameters5/5

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

Schema description coverage is 0%, but the description adds full semantics: job_id is the ID, and fields is a comma-separated string with default behavior explained. This compensates completely for the missing schema descriptions.

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

Purpose5/5

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

The description clearly states the tool gets details for a specific job by ID, using a clear verb and resource. It distinguishes itself from siblings like list_jobs and get_candidate.

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

Usage Guidelines3/5

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

Usage is implied: use when you have a job ID and want details. But there is no explicit guidance on when not to use it or alternatives, such as using list_jobs for browsing.

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

get_mapping_profileA

Read the tenant mapping profile, its history, a version diff, or a proposal.

Args: view: One of "active", "version", "history", "diff", "proposal". version: The version for view="version"; the first version for view="diff". other_version: The second version for view="diff" (default: the active version). entity: Only show mappings of this canonical entity (views "active"/"version"). search: A substring filter; for view="proposal" it is the proposal ID (omit it to list open proposals).

Returns: JSON for the requested view.

ParametersJSON Schema
NameRequiredDescriptionDefault
viewNoactive
entityNo
searchNo
versionNo
other_versionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral burden. It discloses the conditional defaults (other_version falls back to the active version; search is the proposal ID and omitting it lists open proposals), which is genuinely useful, but it never states explicitly that this is a read-only, side-effect-free operation, nor anything about auth or pagination, and 'JSON for the requested view' is a vague return statement.

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

Conciseness5/5

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

Well front-loaded: the purpose sentence precedes the Args/Returns blocks, and each arg line is a single tight clause. The only marginal line is the Returns summary, which is minimal and justified by disambiguating the multi-view output.

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

Completeness4/5

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

An output schema exists, so return values need not be spelled out, and the description covers every parameter and view mode. It is close to complete for a read tool; the missing piece is an explicit read-only/no-side-effect statement, which matters more here given the absence of annotations.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate, and it does. It documents all five parameters, supplies the five enum values for 'view' that the schema lacks, and clarifies the conditional meaning of 'version', 'other_version', 'entity', and 'search' per view.

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

Purpose4/5

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

The description states a specific verb and resource ('Read the tenant mapping profile') and enumerates the four things it can return (profile, history, diff, proposal). It is clear what the tool does, but it never names or contrasts itself with the obvious sibling manage_mapping_profile or the proposal siblings, so sibling 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.

Usage Guidelines3/5

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

The Args block does real work here: it tells the agent which view to pick and what each view requires, which substitutes for intra-tool usage guidance. However, there is no guidance on when to reach for this tool versus manage_mapping_profile, propose_mapping_changes, or commit_mapping_changes, so cross-tool routing is only implied by the name.

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

get_notesA

Read canonical notes (and their note_created events) for one record.

Exactly one primary scope is required: target_type + target_id, or one of candidate_id, job_id, client_corporation_id, client_contact_id, placement_id, submission_id. Only verified Bullhorn mechanisms are used; a scope or filter without one returns status "unsupported_filter" with the supported filters (it is never approximated).

Args: target_type: "candidate", "job", "client_contact", "client_corporation", "placement" or "submission". target_id: The record id for target_type. candidate_id: Primary scope: a candidate id. job_id: Primary scope: a job id. client_corporation_id: Primary scope: a client corporation id. client_contact_id: Primary scope: a client contact id. placement_id: Primary scope: a placement id. submission_id: Primary scope: a submission id. action_type: A tenant note action value (validated; never substituted). author: A Bullhorn user id or name. date_from: Inclusive ISO-8601 date or datetime with offset (a date means midnight in the reporting timezone). date_to: Exclusive ISO-8601 date or datetime with offset. include_deleted: Include deleted notes (default false). limit: Page size, 1 to 50 (default 20). start: Offset of the page (default 0).

Returns: JSON with status, notes, events, next_start, truncated and warnings.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
startNo
authorNo
job_idNo
date_toNo
date_fromNo
target_idNo
action_typeNo
target_typeNo
candidate_idNo
placement_idNo
submission_idNo
include_deletedNo
client_contact_idNo
client_corporation_idNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full behavioral burden and does well: it discloses the one-scope-required constraint, the 'unsupported_filter' failure mode (never approximated), pagination controls, and the deleted-notes default. It stops short of covering auth/permissions or what 'canonical' implies versus raw notes.

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

Conciseness4/5

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

Front-loads the core constraint before the Args/Returns sections, which is the right structure. It is long, and the repeated 'Primary scope:' phrasing across the id parameters adds some redundancy, but the length is largely justified by 15 undocumented parameters.

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

Completeness5/5

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

For a 15-parameter, zero-schema-coverage, zero-annotation tool, the description covers scoping, filter-validation behavior, pagination, defaults, and date semantics; the output schema handles return-shape detail (briefly summarized). Nothing an agent needs to invoke it correctly appears to be missing.

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

Parameters5/5

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

Schema coverage is 0%, so the description must compensate, and it documents all 15 parameters in an Args block: scope semantics, limit range 1-50, start offset, include_deleted default, inclusive date_from vs exclusive date_to (with 'date means midnight in the reporting timezone'), and validated action_type. This meaning is absent from the schema and is exactly what the description is for.

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

Purpose5/5

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

States a specific verb and resource: 'Read canonical notes (and their note_created events) for one record.' It implicitly distinguishes from the sibling create_note (a write) and clarifies that note_created events are bundled in. An agent can identify the operation without opening the schema.

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

Usage Guidelines4/5

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

Gives a clear gating rule: 'Exactly one primary scope is required' followed by the enumerated scope forms, and explains that unsupported scopes/filters yield status 'unsupported_filter' rather than being approximated. It does not, however, route against sibling read tools like get_activity or search_entities, so no explicit alternatives are named.

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

get_recent_placementsC

Get recent Bullhorn placements from the last X days.

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNo
limitNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior2/5

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

With no annotations, the description carries the full behavioral burden and discloses almost nothing: it doesn't confirm this is a read-only operation, note pagination or result capping via limit, mention auth/session requirements, or describe ordering. "Recent" is the only behavioral signal, and it is defined only implicitly by the days parameter.

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

Conciseness3/5

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

It is a single compact sentence with no filler, which is good front-loading. However, the brevity stems from under-specification rather than disciplined editing; a list tool with two undocumented parameters needs at least one more clause.

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

Completeness3/5

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 needn't be described. Still, for a tool with zero annotation coverage and 0% parameter documentation, the description is thin: defaults, result ordering, and pagination behavior are all missing despite being relevant to calling it correctly.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must explain the two parameters. "The last X days" loosely maps to days, but the default (30) is unexplained and the limit parameter (default 100) is never mentioned, leaving half the inputs undocumented in both places.

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

Purpose4/5

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

The description states a specific verb and resource ("Get recent Bullhorn placements") plus a scope constraint ("from the last X days"), so an agent knows exactly what it retrieves. It doesn't distinguish itself from siblings, though no other sibling appears to cover placements, so differentiation is largely moot.

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

Usage Guidelines2/5

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

There is no guidance on when to choose this over alternatives such as query_entities, search_entities, get_activity, or get_recruiting_metrics, nor any note that the X-day window defaults to 30. The agent must infer usage entirely from the name.

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

get_recruiting_metricsA

Recruiting metrics per calendar period: counts and same-period stage ratios.

Counts come from the tenant's configured activity concepts; a metric whose concept is not configured returns its status (e.g. "definition_missing") and no numbers. A count that could not be enumerated completely returns "incomplete" (never a partial number).

Args: metrics: 1 to 8 of jobs_created, client_submissions, interviews_scheduled, offers_extended, placements_created, submission_to_interview, interview_to_offer, offer_to_placement. date_from: Inclusive date (YYYY-MM-DD) in the reporting timezone, on a period boundary. date_to: Exclusive date (YYYY-MM-DD) on a period boundary; at most 12 months or 4 quarters. period: "month" (default) or "quarter".

Returns: JSON with status, tier, period, reporting_timezone, definition and per-metric cells.

ParametersJSON Schema
NameRequiredDescriptionDefault
periodNomonth
date_toYes
metricsYes
date_fromYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does disclose meaningful edge behavior: an unconfigured concept yields 'definition_missing' with no numbers, and an unenumerable count yields 'incomplete' rather than a partial figure. It omits auth/permission requirements and rate limits, which keeps it short of 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.

Conciseness4/5

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

The Args/Returns structure is front-loaded and each constraint earns its place. The Returns section partially duplicates the output schema, which is minor redundancy rather than bloat.

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

Completeness5/5

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

For a 4-parameter analytical tool with an output schema present, the definition covers input semantics, edge-case statuses, and period constraints thoroughly. Nothing an agent needs to invoke it correctly appears to be missing.

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

Parameters5/5

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

Schema coverage is 0%, so the description must compensate, and it does: it enumerates the 8 valid metric values and the 1-8 cardinality, defines date_from as inclusive and date_to as exclusive with YYYY-MM-DD format and period-boundary alignment, and specifies period as month (default) or quarter. This is information the bare schema does not carry.

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

Purpose5/5

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

The description states a specific resource and what it produces: 'Recruiting metrics per calendar period: counts and same-period stage ratios.' No sibling tool computes recruiting metrics, so the agent can identify this tool's role without ambiguity.

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

Usage Guidelines3/5

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

Usage is implied through the axis definitions (metrics list, period boundary constraints, 12-month/4-quarter cap) rather than stated as when-to-use guidance. There are no competing siblings to route against, but the description never says when this should be selected over, say, get_activity or get_recent_placements.

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

list_candidatesA

List and filter candidates from Bullhorn CRM.

Args: query: Lucene search query (e.g., "lastName:Smith" or "skillSet:Python") status: Filter by candidate status limit: Maximum number of results (1-500, default 20) fields: Comma-separated fields to return

Returns: JSON array of candidates

Examples: - list_candidates() - Get recent candidates - list_candidates(query="skillSet:Python") - Find Python developers - list_candidates(query="lastName:Smith AND status:Active") - list_candidates(status="Active", limit=50)

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryNo
fieldsNo
statusNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

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

No annotations are provided, so the description must fully disclose behavior. It states returns a JSON array and explains parameters, but lacks details on pagination, sorting, error handling, or response size limits beyond the implied limit param. The examples help but do not cover all behavioral traits.

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

Conciseness5/5

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

The description is well-structured with a summary, Args, Returns, and Examples sections. It is concise yet informative, using bullet points and code examples to aid comprehension without redundancy.

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

Completeness4/5

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

The description covers all parameters, return type, and usage patterns with examples. However, it omits details on error conditions, authentication requirements, or data freshness. Given moderate complexity and presence of an output schema, it is nearly complete.

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

Parameters5/5

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

Schema coverage is 0%, so the description must compensate. It defines each parameter with usage: query includes Lucene syntax examples, status is a filter, limit has range and default, fields describes comma-separated selection. This fully explains semantics beyond the schema.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'List and filter candidates from Bullhorn CRM.' It specifies the action (list/filter), the resource (candidates), and the source. This distinguishes it from sibling tools like get_candidate (single candidate) and list_jobs (different entity).

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

Usage Guidelines4/5

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

The description includes parameter explanations and four usage examples, giving clear context for typical use cases. However, it does not explicitly state when to use this tool vs. alternatives (e.g., 'use get_candidate for a single candidate'), leaving some ambiguity.

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

list_jobsA

List and filter job orders from Bullhorn CRM.

Args: query: Lucene search query (e.g., "title:Engineer AND isOpen:1") status: Filter by job status limit: Maximum number of results (1-500, default 20) fields: Comma-separated fields to return

Returns: JSON array of job orders

Examples: - list_jobs() - Get recent jobs - list_jobs(query="isOpen:1") - Get open jobs - list_jobs(query="title:Software AND employmentType:Direct Hire", limit=10) - list_jobs(status="Accepting Candidates")

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryNo
fieldsNo
statusNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

No annotations provided, so description fully explains behavior: returns JSON array, supports Lucene query, defaults to 20 results. It doesn't mention pagination or permissions, but non-destructive listing is implied.

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

Conciseness4/5

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

Description is structured with Args, Returns, and Examples. It is concise enough for a tool with 4 parameters, though slightly verbose. Front-loaded with purpose, making it easy to scan.

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

Completeness5/5

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

Given output schema exists and no annotations, description is complete: covers all parameters, provides examples, mentions defaults and return format. No gaps for this complexity level.

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

Parameters5/5

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

Schema has 0% description coverage, but description compensates fully: explains query (Lucene), status (filter), limit (max 1-500, default 20), fields (comma-separated). Examples demonstrate usage, adding significant value.

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

Purpose5/5

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

The description clearly states it lists and filters job orders from Bullhorn CRM. It distinguishes from sibling tools like get_job (single job) and list_candidates (different entity), making its purpose specific.

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

Usage Guidelines4/5

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

Provides examples showing different usage patterns (no args, query, status), giving clear context. However, it does not explicitly state when not to use this tool or mention alternatives like query_entities.

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

manage_mapping_profileA

Validate or export the active mapping profile.

Import and rollback are proposals (propose_mapping_changes with import_document / rollback_to), so nothing is ever activated silently.

Args: action: "validate" (fresh metadata discovery + validation of the active version, recorded locally) or "export" (write the active profile to a new file). path: For "export": a new .yaml/.yml file outside the setup store. format: For "export": "v2" (default) or "v1".

Returns: JSON describing the result.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNo
actionYes
formatNov2

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does disclose side effects: validate performs fresh metadata discovery and is "recorded locally," while export writes to a new file, and nothing is activated silently. It omits permission requirements, overwrite/error behavior for the target path, and any rate limits.

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

Conciseness4/5

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

Front-loaded with the core purpose, then Args and Returns sections that are tight and purposeful. The note about import/rollback being proposals earns its place as a safety clarification; nothing is filler.

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

Completeness4/5

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

An output schema exists, so the brief Returns note suffices, and the description documents all three otherwise-undocumented parameters plus their side effects. It is slightly incomplete on permissions and on differentiation from get_mapping_profile.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must compensate, and it largely does: it enumerates the two action values with semantics, scopes path to "export" as a new .yaml/.yml outside the setup store, and gives format's default and alternatives. It does not state optionality or confirm format is ignored for validate.

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

Purpose4/5

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

The first sentence gives a specific verb pair and resource: "Validate or export the active mapping profile." It also distinguishes itself from the import/rollback path by naming propose_mapping_changes, though it never clarifies how it differs from the sibling get_mapping_profile.

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

Usage Guidelines4/5

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

It explains when each action applies ("validate" for fresh metadata discovery, "export" to write a file) and explicitly routes import/rollback to propose_mapping_changes. It lacks an explicit when-not condition or a contrast with get_mapping_profile, so it stops short of the top band.

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

propose_mapping_changesA

Propose mapping changes (the dry-run): validate, diff, hash and store a proposal.

Nothing is activated; only a local proposal file is written. Commit it with commit_mapping_changes using the returned proposal_id and diff_hash.

Args: changes: Change operations, each an object with an "op": init_tenant, apply_verified_defaults, set_field_mapping, deactivate_field_mapping, remove_field_mapping, set_value_mapping, deactivate_value_mapping, remove_value_mapping, set_setting, rollback_to, import_document. base_version: The version the change is built on (default: the active version).

Returns: JSON with proposal_id, diff_hash, expires_at, diff, conflicts, dependencies, validation.

ParametersJSON Schema
NameRequiredDescriptionDefault
changesYes
base_versionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations, the description carries the full burden and does well: it discloses that nothing is activated, only a local proposal file is written, and that a commit step is required. It also enumerates the return fields including expires_at and conflicts, hinting at proposal lifecycle. It does not state permissions or rate limits, but the safety profile (non-destructive dry-run) is made clear.

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

Conciseness4/5

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

Front-loads the core purpose and the dry-run framing in the first sentence, then covers args and returns. The args and returns sections are dense but structured with labels. Slightly verbose but every section earns its place.

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

Completeness4/5

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

Output schema exists, so return values needn't be fully described, yet the description still summarizes them helpfully. Combined with the op enumeration, base_version default, and the commit handoff, an agent has enough to invoke and follow up. Permissions and error/conflict semantics are the remaining gap.

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

Parameters4/5

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

Schema coverage is 0%, so the description must compensate, and it partly does: it explains base_version defaults to the active version, and enumerates the full set of allowed 'op' values inside changes (init_tenant, set_field_mapping, rollback_to, etc.). The nested change object structure is still not fully specified (other fields per op remain undocumented), preventing a 5.

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

Purpose5/5

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

States a specific verb (propose) and resource (mapping changes), and explicitly frames it as 'the dry-run' with validation, diff, hashing, and storage. The terminal sentence naming commit_mapping_changes as the counterpart makes the distinction from the commit sibling unambiguous.

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

Usage Guidelines5/5

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

Explicitly states when to use this (for proposing) versus commit_mapping_changes (for activation), and gives the exact workflow: 'Commit it with commit_mapping_changes using the returned proposal_id and diff_hash.' Nothing about the propose-then-commit sequence 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.

query_entitiesA

Query Bullhorn entities using SQL-like WHERE syntax.

Args: entity: Entity type (JobOrder, Candidate, etc.) where: WHERE clause (e.g., "salary > 100000 AND status='Active'") limit: Maximum number of results (1-500, default 20) fields: Comma-separated fields to return order_by: Sort order (e.g., "-dateAdded" for newest first)

Returns: JSON array of matching entities

Examples: - query_entities(entity="JobOrder", where="salary > 100000") - query_entities(entity="Candidate", where="status='Active'", order_by="-dateAdded")

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
whereYes
entityYes
fieldsNo
order_byNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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

With no annotations, the description carries full burden. It explains return format ('JSON array of matching entities') and parameter behaviors (limit range, default). However, it does not disclose error handling, authentication requirements, or behavior for invalid entity types, leaving gaps.

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

Conciseness4/5

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

The description is well-structured with sections (Args, Returns, Examples) and is mostly concise. Each sentence adds value. Minor redundancy (e.g., 'JSON array' could be implied) but overall efficient.

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

Completeness4/5

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

Given the tool's complexity (5 params, output schema exists), the description covers parameter details, return type, and examples. It could mention valid entity types explicitly, but the output schema may cover that. Overall complete for a query tool.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must compensate. It clearly explains each parameter: entity type with examples, WHERE clause syntax, limit range, fields as comma-separated, and order_by format. Examples further illustrate usage. This adds significant meaning.

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

Purpose5/5

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

The description clearly states the tool's purpose: 'Query Bullhorn entities using SQL-like WHERE syntax.' It specifies the resource (Bullhorn entities) and the action (querying with WHERE syntax). Examples further clarify. It distinguishes from sibling tools like get_candidate or list_candidates by emphasizing the SQL-like query capability.

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

Usage Guidelines3/5

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

The description implies usage for complex filtering via WHERE syntax but does not explicitly contrast with siblings like search_entities or list_* tools. No when-not or alternative guidance is provided. Examples help, but explicit comparison is missing.

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

search_entitiesA

Search any Bullhorn entity type using Lucene query syntax.

Args: entity: Entity type (JobOrder, Candidate, Placement, ClientCorporation, ClientContact, etc.) query: Lucene search query limit: Maximum number of results (1-500, default 20) fields: Comma-separated fields to return

Returns: JSON array of matching entities

Examples: - search_entities(entity="Placement", query="status:Approved") - search_entities(entity="ClientCorporation", query="name:Acme*") - search_entities(entity="JobSubmission", query="jobOrder.id:12345")

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
entityYes
fieldsNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

Despite no annotations, the description is transparent: it explains the search functionality, returns a JSON array, and uses Lucene syntax. It does not explicitly state read-only behavior, but the examples imply no side effects. The description adequately discloses the core behavior.

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

Conciseness5/5

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

The description is concise and well-structured: a one-line summary, then Args, Returns, and Examples. Every sentence is purposeful, no redundancy. The format is front-loaded and easy to parse.

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

Completeness4/5

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

The description covers the essential aspects: entity types, query syntax, limit, fields, and return format. With an output schema present, the return description is sufficient. Minor omissions (e.g., pagination) are acceptable for a search tool.

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

Parameters5/5

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

With 0% schema coverage, the description fully compensates by detailing each parameter: entity types, Lucene query, limit range (1-500, default 20), and fields as comma-separated. Examples illustrate valid values, adding substantial meaning beyond the schema.

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

Purpose5/5

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

The description starts with 'Search any Bullhorn entity type using Lucene query syntax,' which clearly specifies the action (search) and the resource (any entity type). It distinguishes from sibling tools like get_candidate and list_candidates, which retrieve single entities or lists without search syntax.

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

Usage Guidelines3/5

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

The description implies usage when a Lucene query is needed, but it does not explicitly state when to use this tool versus alternatives like query_entities. No exclusions or when-not-to-use guidance is provided, leaving the agent to infer context from examples.

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

setup_statusA

Report the tenant setup state, missing requirements and per-capability readiness.

Args: check_connection: Also log in to Bullhorn to confirm connectivity and the REST URL fingerprint (default true).

Returns: JSON with state, missing_requirements, capabilities, active_version, open_proposals and last_validation.

ParametersJSON Schema
NameRequiredDescriptionDefault
check_connectionNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

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

With no annotations, the description carries full behavioral disclosure. It usefully reveals that check_connection also logs in to Bullhorn to confirm connectivity and the REST URL fingerprint, and it lists return fields, but it omits error behavior, permission requirements, and other operational traits.

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

Conciseness5/5

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

The description is front-loaded with the purpose and then structured into Args and Returns sections with no filler. Every sentence contributes useful information for calling the tool.

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

Completeness4/5

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

For a simple one-parameter status tool with an output schema, the description covers purpose, parameter behavior, and return fields adequately. It could still say more about when to choose it over connection_status, but the core calling information is complete.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must explain the only parameter. It does so by stating that check_connection triggers a Bullhorn login to confirm connectivity and the REST URL fingerprint, and it notes the default of true. This adds meaningful semantics beyond the bare boolean schema.

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

Purpose4/5

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

The description states a specific verb and resource: report tenant setup state, missing requirements, and per-capability readiness. This clearly distinguishes it from a simple connectivity tool like connection_status, though it does not explicitly name or contrast any sibling.

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

Usage Guidelines2/5

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

The description says what the tool reports but gives no guidance on when to use it versus alternatives such as connection_status or bullhorn_session. There are no when / when-not conditions or routing instructions.

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

upload_candidate_resumeA

Upload a local resume file to a Bullhorn Candidate.

Args: candidate_id: The Candidate ID file_path: Local filesystem path to the resume file file_type: Bullhorn file type classification (default: "SAMPLE") external_id: Bullhorn external ID for the file (default: "Portfolio") dry_run: If True, validate inputs and return a preview of what would be uploaded without performing the upload

Returns: JSON object with the upload result, or - when dry_run is True - a preview of what would have been uploaded.

ParametersJSON Schema
NameRequiredDescriptionDefault
dry_runNo
file_pathYes
file_typeNoSAMPLE
external_idNoPortfolio
candidate_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It usefully discloses that dry_run returns a preview without performing the upload, and gives the default classifications for file_type and external_id. It omits other important behavior: whether an upload replaces or appends existing resume files, auth/permission requirements, and error handling.

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

Conciseness4/5

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

The purpose is front-loaded in a single sentence, followed by a compact Args list and a short Returns note. It is slightly padded (the Returns section restates the preview behavior already covered under dry_run), but there is no significant waste.

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

Completeness3/5

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 detailed, and the parameter documentation is complete. Still, for a mutation tool with no annotations, an agent would benefit from knowing permission needs, supported file types, and whether the upload overwrites an existing resume — none of which appear.

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

Parameters4/5

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

Schema description coverage is 0%, so the description must compensate, and it does: all five parameters are explained, including the meaning of file_type and external_id as Bullhorn classifications and the defaults for those fields and dry_run. It does not clarify accepted file formats for file_path or candidate_id sourcing, so it falls short of fully compensating.

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

Purpose4/5

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

States a specific verb and resource ('Upload a local resume file to a Bullhorn Candidate'), which is unambiguous and clearly distinct from read-oriented siblings like get_candidate_files or get_candidate. It does not explicitly name an alternative tool, but the target and action are concrete enough to route on without opening the schema.

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

Usage Guidelines3/5

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

The dry_run parameter description implies a validate-then-commit workflow, which is useful usage guidance. However, it never states when to prefer this tool over others, what prerequisites exist (a session, an existing candidate), or any exclusions such as file format or size limits.

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.

  1. 23 tool updatesv0.1.0
    • First observedbullhorn_session
    • First observedcommit_mapping_changes
    • First observedconfirm_write
    • First observedconnection_status
    • First observedcreate_note
    • First observeddiscover_schema
    • First observedfind_records
    • First observedget_activity
    • First observedget_candidate
    • First observedget_candidate_files
    • First observedget_job
    • First observedget_mapping_profile
    • First observedget_notes
    • First observedget_recent_placements
    • First observedget_recruiting_metrics
    • First observedlist_candidates
    • First observedlist_jobs
    • First observedmanage_mapping_profile
    • First observedpropose_mapping_changes
    • First observedquery_entities
    • First observedsearch_entities
    • First observedsetup_status
    • First observedupload_candidate_resume

TDQS

B3.4/5.0

Scored across 23 tools

Disambiguation3/5

There is substantial overlap between the generic search tools (search_entities Lucene, query_entities SQL-like, find_records structured filters) and the specific ones (list_jobs, list_candidates, get_recent_placements), so an agent can easily pick the wrong path to the same data. get_notes versus get_activity (which includes note_created) and connection_status versus setup_status versus bullhorn_session also blur together. The very detailed descriptions do help differentiate them, keeping this from being worse than a 3.

Naming Consistency3/5

Most tools follow a verb_noun snake_case pattern (list_jobs, get_candidate, propose_mapping_changes, confirm_write), which is readable and predictable. However several tools break the pattern with noun or non-standard verb forms (connection_status, setup_status, bullhorn_session, manage_mapping_profile). The mix is understandable but not fully consistent.

Tool Count3/5

23 tools is on the heavy side and sits in the borderline range where redundancy costs appear. The breadth (CRM reads, mapping-profile governance, safe-write pipeline, activity and metrics) justifies many tools, but the generic search trio overlaps with the resource-specific list tools, suggesting some could be consolidated.

Completeness3/5

The server has strong read coverage (jobs, candidates, placements, notes, activity, metrics) and a well-governed write path, but it lacks create/update for the core CRM entities (no candidate/job/submission/placement creation). For a Bullhorn agent the only real writes are notes and resume upload, a notable lifecycle gap.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    F
    maintenance
    Enables AI assistants to query Bullhorn CRM data using natural language through direct REST API access with OAuth 2.0 authentication.
    6
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP-compatible AI assistants to securely access a user's job-search account, letting them search and save jobs, analyze job fit, and retrieve job queue and profile summaries with links back to the web app.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A hosted, OAuth-authenticated MCP endpoint exposing 176 tools that let AI assistants read and write jobs, candidates, applications, interviews, scorecards, prospects, talent pools, and imports within an organization's own applicant tracking data, scoped to the signed-in user's existing permissions.
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI clients to manage JobZyn jobs and candidates through MCP tools for creating, updating, unpublishing jobs, retrieving candidate applications, and linking external IDs.
    5
    46 npm
    MIT