Skip to main content
Glama

Upwork MCP Server

Server Details

Connect your AI agent to Upwork. Search talent, post jobs, manage contracts, and get answers from your account.

Ownership verified
Status
Unhealthy
OAuth
Requires browser extension
Last Tested
Transport
Streamable HTTP
URL

Available Tools

33 tools
upwork__confirm_attachment_uploadFinalize Uploaded FilesAInspect

Confirm uploaded files so they are retained in Upwork storage. Uses the same attachment backends as start_attachment_upload. Requires the upload context and the file_uid values returned from upload.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Each write requires separate confirmation even if the user said "approve all".

Actions:

  • confirm: context (string, required) selects the attachment backend: messages = room message attachments (requires room_id); proposals = job-application/proposal attachments; offer = offer attachments; milestones = milestone attachments; job = job posting attachments; invitation = attachments when a freelancer accepts a client invitation. If the user did not clearly say where the file belongs, ask which context they want before calling start_attachment_upload. Params: file_ids (array of strings, required — file_uid values to confirm); task_id (string, required — the task_id returned by start_attachment_upload for these files). Only file_uid values that get_upload_status reports as done for that task_id can be confirmed; anything else is refused. Upload sessions last 30 minutes, so confirm promptly. Files uploaded through the inline component are already stored and must NOT be confirmed. Use the same context as the upload session that produced the file_uid values.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A5/5.0
Behavior5/5

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

Annotations only say readOnlyHint=false, but the description goes much further: it declares WRITE OPERATION requiring explicit user confirmation, says each write needs separate confirmation, limits confirmations to file_uids that get_upload_status reports as done, and warns that upload sessions expire in 30 minutes. No contradiction with annotations 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?

The description is long but every sentence earns its place: purpose first, a prominent safety warning second, and then dense, structured parameter details. No fluff or repetition; the context list and constraints are organized as a single action block.

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 the operation's complexity, the description covers prerequisites, timing, exclusions, validity rules, and the confirmation protocol. Even without an output schema, the agent has everything needed to invoke 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?

The schema's params description is generic, leaving the actual required fields undocumented. The description fills this entirely by enumerating valid context values, declaring file_ids and task_id as required, explaining their provenance, and adding the validity constraint from get_upload_status. This is high-value parameter clarification 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 opens with a specific verb and resource: 'Confirm uploaded files so they are retained in Upwork storage.' It further clarifies its relationship to start_attachment_upload and get_upload_status, making it clearly distinguishable from sibling tools.

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?

Provides explicit decision rules: files uploaded through the inline component are already stored and must NOT be confirmed; confirmation is the step after start_attachment_upload returns file_uid values. It also instructs the agent to ask the user for the context if unclear, and states the 30-minute session urgency.

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

upwork__confirm_draftSubmit DraftA
Destructive
Inspect

Confirm and execute a previously prepared draft for job postings, proposals, invitation accepts, invitations, milestones, profile updates, and offer decline / request-changes. Requires draft_id from the prior draft action. Do NOT use to ACCEPT an offer — accepting is finalized on upwork.com via the finalize_url returned by respond_to_offer accept.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Each write requires separate confirmation even if the user said "approve all".

Actions:

  • confirm: Confirm and execute a draft using draft_id only. Params: type (string, required), draft_id (string, required — from the create draft response). Do not pass the returned params; they are loaded from server storage.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsYes
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the annotations' destructiveHint=true, the description discloses the mandatory user-confirmation behavior: 'WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION' and 'Each write requires separate confirmation even if user said approve all'. It also clarifies that server-stored params are executed, adding meaningful operational transparency. No contradiction with annotations.

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?

Every sentence carries useful information, from the core purpose to the explicit exclusion to the user-confirmation requirement. The description is long only because the tool has complex operational constraints; none of the content 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?

The description covers purpose, prerequisites, exclusions, confirmation behavior, and parameter semantics thoroughly. The only notable gap is that it does not describe the return value or result details after executing a draft, and there is no output schema to fill that 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 description adds important draft_id semantics ('from the create draft response', 'executes stored server params only — do not pass confirm payloads') beyond the schema. The type param is thoroughly covered by the schema enum and its description, so little extra description is needed. Overall the description compsensates well for the 67% schema coverage.

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 verb ('Confirm and execute'), a clear resource ('previously prepared draft'), and lists covered draft types. It explicitly distinguishes itself from offer acceptance by saying 'Do NOT use to ACCEPT an offer', which separates it from sibling workflows.

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?

It clearly says when to use the tool: after a prior draft action and with a required draft_id. It also gives explicit exclusions: offer acceptance must go through the finalize_url from respond_to_offer, and confirm_draft must not receive confirm payloads. This is strong routing guidance.

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

upwork__end_contractEnd ContractA
Destructive
Inspect

End a contract with a reason code, optionally attaching a freelancer review (six 1–5 scores + a comment). Runs through MCP (draft -> confirm_draft). Use list_contracts action=end_reasons to look up reason codes first.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval.

Actions:

  • end: Prepare a contract-end draft. Params: contract_id (string, required), reason_id (string, required). Optional freelancer review: quality_score, skills_score, communication_score, availability_score, deadlines_score, cooperation_score (integers 1–5) and comment (string). Provide all six scores together for a complete review.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.6/5.0
Behavior5/5

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

Beyond the annotations, the description discloses the two-phase draft/confirm_draft flow, states that it returns a draft for review, and explicitly warns 'REQUIRES EXPLICIT USER CONFIRMATION.' It also clarifies that this is a write operation, consistent with readOnlyHint=false and destructiveHint=true. This adds substantial behavioral context that annotations alone do not provide.

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: an opening summary, a workflow note, a warning, and a grouped action/parameter section. It is slightly redundant in mentioning the draft/confirm_draft flow twice, but every sentence carries useful information and the most important warnings are front-loaded.

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 destructive write operation with no output schema, the description fully covers what the agent needs: prerequisites (reason codes via list_contracts), the required flow (returns a draft, call confirm_draft), the required parameters, and the optional review grouping. It leaves no critical gap for safe invocation.

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 100%, so the baseline is 3. The description adds meaningful parameter semantics by summarizing the six optional scores and comment, and by stating 'Provide all six scores together for a complete review,' which is a constraint not present in the schema. It also reinforces the source of reason_id and contract_id.

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 opens with a specific verb and resource: 'End a contract with a reason code, optionally attaching a freelancer review.' This clearly distinguishes the tool from the sibling update_contract by describing a terminal action rather than a modification, even without naming the sibling explicitly.

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 gives clear usage context: use list_contracts action=end_reasons first to get reason codes, and call confirm_draft after explicit user approval to execute. It does not explicitly describe when to choose this over alternatives like update_contract, but the workflow is well-defined enough that an agent can identify correct usage.

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

upwork__find_freelancersFind FreelancersA
Read-only
Inspect

Search for freelancers and view profiles.

Actions:

  • search: Search freelancer profiles. Params: query (string — the ROLE or intent as a short phrase, e.g. "WordPress developer" or a job title; it is keyword AND-matched against profile text, so keep it short. Do NOT list skill keywords here — pass those as skills. Putting the same terms in both query and skills double-filters and over-narrows the results; prefer skills for concrete technologies and leave query for the role, or omit query when skills already capture the need), skills (array of string — each is matched as a structured skill filter/facet like the marketplace UI, not concatenated into the free-text query. Skills are AND-matched; if requiring all of them yields no matches the tool relaxes the broadest skill by ontology and retries, falling back to list order when the ontology cannot rank them, so list the most important first. The response then carries a note naming which skills were relaxed and which are still required — relay it so the user knows what was given up), rate_min (number), rate_max (number) (each must be greater than 0; rate_min cannot exceed rate_max; omit a bound to leave it open), country (string), state (string — filter by location state/region), regions (array of string — continents: Africa, Americas, Antarctica, Asia, Europe, Oceania), subregions (array of string — UN subregions, e.g. Northern America, Western Europe, South-Eastern Asia), talent_type (freelancer/agency — freelancer returns independent freelancers, agency returns agencies), job_success_min (number, 0-100 — minimum Job Success Score. The marketplace UI offers three standard choices: "Any job success" (omit this filter), "80% & up" (job_success_min=80), and "90% & up" (job_success_min=90) — offer these presets when the user asks to filter by job success; any other 0-100 value is also accepted, values outside 0-100 are rejected), top_rated (boolean — filter to Top Rated freelancers), top_rated_plus (boolean — filter to Top Rated Plus), rising_talent (boolean — filter to Rising Talent), contract_to_hire (boolean — open to contract-to-hire), offers_consultations (boolean — offers consultations), timezones (array of string — Upwork timezone labels, e.g. "UTC-05:00 Eastern Time (US & Canada)", "UTC+00:00 London" — NOT IANA names), languages (array of string — language codes, e.g. en, es), english_level (basic/conversational/fluent/native, or a rank number 1-4 — minimum English proficiency), earnings_min (number), earnings_max (number) (total earned amount range, USD; each must be > 0), no_earnings (boolean — freelancers with no earnings yet), hours_billed_min (number), hours_billed_max (number) (hours-billed range), total_jobs_min (number), total_jobs_max (number) (completed-jobs range), title (string — filter by freelancer title), limit (integer, 1–10, default 10), offset (number, default 0 — must be >= 0). All filters are optional. Each result has two distinct IDs: 'personId' (use it as freelancerId for invite_freelancer) and 'profile_key' (starts with ~, use it for get_profile). Do not interchange them. For hiring via manage_offers create_draft, first call get_profile with profile_key to obtain vendor_org_uid, then pass vendor_user_id=personId and vendor_org_uid. Each result includes job_success_score (the freelancer's Job Success Score, 0-100) when available — the same scale as the job_success_min filter. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • get_profile: Get a freelancer's public profile: skills, employment and education history, job aggregates (completed jobs, total earnings, feedback), portfolio projects when readable — check portfolio_available and relay the note when it is false — and the per-contract work history in work_history (AGEX-1733): each contract's title, dates, status, amount earned and the client's review. Check work_history_available and relay work_history_note when it is false; an absent section is NOT evidence the freelancer has no contracts. Params: profile_key (string — starts with ~ e.g. ~01abc123, from search results) or person_id (string — the numeric user.id returned by list_client_proposals); supply either one. Returns vendor_org_uid (the freelancer's org for hiring, pass it to manage_offers create_draft) and vendor_org_type (individual/agency) when available.

  • smart_search: Recommend freelancers for one of the client's own job postings, ranked by Upwork's own matching for that job — the same list the "Invite freelancers" page shows. Prefer this over find_freelancers action=search whenever the client has a job posting: the ranking uses the whole posting, not a keyword query. Params: job_id or job_posting_id (string, required — a numeric owned posting ID from get_job_posting action=list; the posting must belong to the selected organization), query (string, optional — free text that RE-RANKS the recommendations toward those terms. It is a relevance boost, not a filter: the list stays the same size and may still contain profiles that do not mention the terms, so do not promise the user it excludes anything. Use the real filters below when they need a hard constraint), skills (array of string, optional — folded into the same free-text boost; the posting's own skills already inform the ranking), available_now (boolean), hire_me_now (boolean), country (string), state (string), region (string — continent, e.g. Europe), subregion (string — UN subregion), languages (array of string — language codes, e.g. en, es), english_level (basic/conversational/fluent/native, or a rank 1-4), job_success_min (number, 0-100 — the UI presets are 80 and 90), top_rated (boolean), top_rated_plus (boolean), rising_talent (boolean), rate_min / rate_max (number — hourly rate range), earnings_min / earnings_max (number — total earned, USD), hours_billed_min / hours_billed_max (number), limit (integer, 1–10, default 10), offset (number, default 0), use_job_category (boolean, default false — set true to additionally scope results to the job's own category, as the Invite Freelancers page's preselected filter does. The job id already drives the ranking, so this only narrows the pool; it is not needed for relevance). WHEN PRESENTING RESULTS, show for each freelancer the fields that are present, because these are what the Upwork page itself shows and the user is comparing against it: name, title, country, hourly_rate, total_earnings (already bucketed for display, e.g. "$50K+" — present it as given, never as an exact figure), job_success_score (as a Job Success percentage), top_rated (the talent badge — Top Rated Plus, Top Rated or Rising Talent), available_now, and recommendation_reason. Do not silently drop the badge or the earnings when they are present. A row with boosted=true is a PAID AD PLACEMENT: say so using boosted_label, and never present it as a purely earned ranking — organic_position gives the rank it would have held unpaid. When preselected_filters is present, tell the user which filters came from their job post and that they can be dropped. Results are LEAN CARDS: no description, no skills list. Call get_profile with profile_key for full detail. person_id is the freelancerId for invite_freelancer; profile_key (starts with ~) is for get_profile. Do not interchange them. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • smart_search_keywords: Keyword search for freelancers built from a job posting's skills. SUPERSEDED by action=smart_search, which asks Upwork for the actual recommendations for the job; use this only when explicitly asked to compare the two rankings. It reads the posting's classification skills, folds them into one free-text query and runs the generic freelancer search, so it cannot surface recommendation reasons or boosted placements. Params: job_id or job_posting_id (string, required — owned posting ID from get_job_posting action=list).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds substantial behavioral context on top: skills are AND-matched with ontology-based relaxation and retry, smart_search may return paid placements with boosted=true that must not be presented as earned rankings, earnings are bucketed for display such as "$50K+", and an absent work_history section is explicitly not evidence of no contracts. All of this goes well beyond what annotations alone convey, and nothing contradicts them.

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 very long but well structured: action headings, per-parameter inline annotations, and front-loaded action summaries make it scannable for a complex four-action tool. There is some repetition — "Optional params are refinements" and the personId/profile_key interchange warning appear more than once — but the repeated warnings serve safety-critical routing and most content earns its place.

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?

With no output schema present, the description carries the full burden of explaining returns, and it does so thoroughly: search results expose personId and profile_key with distinct uses, get_profile returns vendor_org_uid, vendor_org_type, portfolio_available, work_history_available, and work_history_note, and smart_search results specify exactly which fields to present, including boosted_label, organic_position, and preselected_filters. Cross-tool dependencies like obtaining vendor_org_uid before manage_offers create_draft are also covered.

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?

Although schema coverage is 100%, the description adds meaning far beyond the terse schema descriptions. It clarifies that query should be a short role phrase rather than skill keywords, that skills are structured AND-matched facets (not concatenated text), that timezones are Upwork labels rather than IANA names, that smart_search query is a relevance boost not a hard filter, and that job_success_min maps to UI presets 80 and 90. This transforms an ambiguous parameter list into actionable instructions.

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 opens with a specific verb+resource statement — "Search for freelancers and view profiles" — and then breaks the tool into four clearly named actions (search, get_profile, smart_search, smart_search_keywords), each with its own purpose. It also differentiates internal actions from siblings like upwork__find_jobs and upwork__invite_freelancer by scoping exactly what this tool does.

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?

The description gives explicit routing guidance: "Prefer this over find_freelancers action=search whenever the client has a job posting", and marks smart_search_keywords as "SUPERSEDED... use this only when explicitly asked to compare the two rankings." It also explains when not to put terms in both query and skills, when to ask before applying optional filters, and how results should be used downstream (personId for invite_freelancer, profile_key for get_profile, vendor_org_uid for manage_offers).

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

upwork__find_jobsFind JobsA
Read-only
Inspect

Search and view marketplace job postings.

Actions:

  • search: Search for jobs matching filters. Params: query (string), job_type (fixed/hourly), experience_level (entry_level/intermediate/expert), budget_min (number), budget_max (number) (FIXED-PRICE project budget; each must be greater than 0; budget_min cannot exceed budget_max; omit a bound to leave it open. This does NOT filter hourly jobs — for an hourly rate use rate_min/rate_max), skills (array of string — filter to jobs carrying these Upwork skills, at most 5. Names are matched exactly against the Upwork skill list; a name that does not match is reported and NOT applied, never guessed at. Relay skills_note when present so the user knows which of their skills were actually used), category (string — scope to a top-level category, by name ("Web, Mobile & Software Dev") or ontology id. An unknown name is rejected with the valid list rather than ignored), subcategory (string — same, one level down), rate_min (number), rate_max (number) (HOURLY rate per hour, the filter to use when the user says "$50/hr" or "pays at least $30 an hour". Same bounds rules as budget. Pair it with job_type=hourly so fixed-price postings, which carry no rate, are not returned alongside), workload (full_time/part_time/as_needed), duration (less_than_1_month/1_to_3_months/3_to_6_months/more_than_6_months — expected project length; this is distinct from workload, which is hours per week. It constrains HOURLY jobs only: fixed-price jobs are returned regardless of their duration, so combine it with job_type=hourly when the user asks for work of a given length), verified_payment_only (boolean — only jobs from clients with a verified payment method), proposals_min (number), proposals_max (number) (filter by number of proposals already submitted; e.g. proposals_max=5 for jobs with fewer than 5 proposals), client_hires_min (number), client_hires_max (number) (filter by the client's past hire count; e.g. client_hires_min=0, client_hires_max=0 for clients with no hires, or client_hires_min=10 for 10+). Range bounds must be >= 0 and min cannot exceed max; omit a bound to leave it open. Each job carries a client block. total_spent is the client's lifetime spend and total_hires their hire count — read them together, since 45 hires at $500 and 45 at $50k are the same hire count and very different clients. rating there is the score FREELANCERS gave that client (client_rating_basis in the response says so) — treat a low rating as a warning about the client, not as the client being unsuccessful. sort (recency/relevance/client_total_charge/client_rating — how to order results; omit for the default recency order), previous_clients_only (boolean — only jobs from clients you have worked with before), timezone (string — filter by the client's timezone), location (string — filter by the client's location), limit (integer, 1–10, default 10), cursor (string — omit for the first page; to fetch the next page, repeat the SAME filters with cursor set to the endCursor from the previous response's pageInfo, and only when pageInfo.hasNextPage is true). A client's preferred qualifications are NOT in search results — use get on a specific job to see them. Each result includes proposal_count (proposals submitted so far). Hire/invite liveness (total_hired, invites_sent) is NOT in search — use get on a specific job before assuming it is still open. There is NO created_after/date filter — the signed-in marketplace search API exposes none (the public search has days_posted, but find_jobs uses the signed-in search for sort and extra filters). For the freshest jobs use sort=recency (already the default order); each result carries created_date/published_date for client-side narrowing to a time window. Each result also includes url, a ready-to-use Upwork job link. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • get: Get full details of a job posting including client company info, work history, connects, and the client's preferred qualifications (returned as preferred_qualifications: e.g. contractor_type, minimum job success score, English level, rising_talent, earnings). When present, surface the preferred qualifications to the user so they know what the client is looking for. The response includes connects_cost (the Connects required to apply), connects_balance, can_apply, and a ready-to-use url when available. client_record is the client's hiring record — hires, active contracts, total spend, feedback score and count, hours; surface it when the user is judging whether the client is worth applying to. When the response carries bid_stats_basis, the bid amounts under activityStat.applicationsBidStats have no unit attached. client_work_history holds the client's 5 latest open and 5 latest closed contracts, in separate open/closed lists (its selection field says so), so never derive totals or a count of open jobs from it — client_record has the totals. Params: id or job_id (string, required — the numeric id from find_jobs action=search, a ~02… ciphertext, or a full Upwork job URL, e.g. https://www.upwork.com/jobs/~0212345 — all accepted directly, no need to extract or reformat the id yourself). If this returns access denied for a marketplace job ID, use get_job_posting action=get_marketplace with the same id.

  • smart_search: Auto-fetch your profile skills and search matching jobs. Each result includes a ready-to-use url. The search terms come from the profile — to write your own query use action=search instead — but every filter below narrows the results the same way it does there, so prefer this action whenever the user wants work matching their profile. Params: job_type (fixed/hourly), experience_level (entry_level/intermediate/expert), budget_min (number), budget_max (number) (FIXED-PRICE project budget; does NOT filter hourly jobs), skills (array of string — filter to jobs carrying these Upwork skills, at most 5. Names are matched exactly against the Upwork skill list; a name that does not match is reported and NOT applied, never guessed at. Relay skills_note when present so the user knows which of their skills were actually used), category (string — scope to a top-level category, by name ("Web, Mobile & Software Dev") or ontology id. An unknown name is rejected with the valid list rather than ignored), subcategory (string — same, one level down), rate_min (number), rate_max (number) (HOURLY rate per hour — use this, not budget, when the user says "$50/hr"; pair with job_type=hourly). For both pairs each bound must be greater than 0, min cannot exceed max, and omitting a bound leaves it open. workload (full_time/part_time/as_needed), duration (less_than_1_month/1_to_3_months/3_to_6_months/more_than_6_months — expected project length; distinct from workload, which is hours per week. It constrains HOURLY jobs only, so combine it with job_type=hourly when the user asks for work of a given length), verified_payment_only (boolean), proposals_min (number), proposals_max (number) (RANGE over how many proposals a job already has — there is no exactly-N filter; e.g. proposals_max=5 for jobs with fewer than 5), client_hires_min (number), client_hires_max (number) (RANGE over the client's past hire count; e.g. client_hires_min=0 with client_hires_max=0 for clients who have never hired, or client_hires_min=10 for 10+). Range bounds must be >= 0 and min cannot exceed max; omit a bound to leave it open. sort (recency/relevance/client_total_charge/client_rating), previous_clients_only (boolean — only clients you have worked with), timezone (string), location (string), limit (integer, 1–10, default 10), cursor (string, optional — omit for the first page; to fetch the next page repeat the SAME filters with cursor set to the endCursor from the previous response's pageInfo, only when pageInfo.hasNextPage is true). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already mark this read-only and non-destructive, but the description adds substantial behavioral context beyond them: there is no created_after/date filter, hire/invite liveness is not in search results, client rating is freelancer-given and should be read as a warning, bid_stats_basis implies unit-less bid amounts, and client_work_history must not be used to derive totals. These caveats directly prevent an agent from misinterpreting responses or inventing unsupported filters.

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 definition is long but well-structured with action headers and dense, purposeful content. Some boilerplate is repeated between search and smart_search—such as the optional-params reminder and several identical filter explanations—which adds length without new information. Still, the front-loaded summary and clear action breakdown make it navigable for an agent.

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?

With no output schema, the description carries the burden of explaining response semantics, and it does so thoroughly: it documents proposal_count, pageInfo.endCursor, client_record, connects_cost, preferred_qualifications, client_work_history structure, and the meaning of total_spent and rating. It also covers edge cases like access-denied fallback and missing date filters. For a multi-action tool of this complexity, nothing essential 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?

The description greatly exceeds the schema's parameter documentation by explaining semantics and pitfalls: budget_min/max apply only to fixed-price jobs while rate_min/max handle hourly rates; duration only constrains hourly jobs; skills are matched exactly and unknown names are reported not guessed; range bounds rules are specified; and cursor pagination requires repeating the same filters. This is exactly the kind of added meaning that helps an agent invoke parameters correctly.

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 opens with a specific verb and resource: 'Search and view marketplace job postings.' It then enumerates three distinct actions (search, get, smart_search), each with a clear function, and explicitly distinguishes this tool from get_job_posting via the fallback instruction. An agent can immediately tell what this tool does and which sub-operation matches a given request.

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?

The description gives explicit when-to-use guidance and names alternatives: use smart_search when the user wants profile-matched work, use search for a custom query, use get for full details and preferred qualifications, and fall back to get_job_posting action=get_marketplace on access denied. It also instructs when to ask before applying optional filters, e.g. for selective requests like 'best' or 'near me'. This is strong routing guidance.

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

upwork__get_accountGet AccountA
Read-only
Inspect

View account info and organization details.

Actions:

  • get_user_details: Get user details. Params: id (string, optional — defaults to current user).

  • get_organization: Get current organization. No params.

  • get_company: Get the company details of the organization you are acting as. To read a different account of yours, call again with that org_uid. For a marketplace job's client, use find_jobs action=get with the job ID instead. No params.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.1/5.0
Behavior4/5

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

Annotations establish read-only and non-destructive safety; the description adds org_uid-dependent behavior, default-to-current-user semantics for get_user_details, and the marketplace-client redirect. No contradictions with annotations, and no auth or rate-limit details, but for a read-only tool the added context is solid.

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 opens with a one-line summary and then uses a compact action-by-action list. Every bullet adds operational detail without filler or restating the tool name.

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?

Covers all three actions, their parameters, and the key alternative routing for client accounts. The main minor gap is not describing the return value shape, but with no output schema and readOnlyHint true this is acceptable; the required org_uid is documented in the schema.

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 schema already documents action, params, and org_uid, so the baseline is 3. The description adds value by specifying the optional id default, labeling get_organization and get_company as having no params, and explaining how org_uid selects the account for get_company.

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?

Describes a clear read-only purpose ('View account info and organization details') and enumerates the three concrete operations. It stops short of explicitly distinguishing itself from siblings like list_accounts and update_account, so it gets 4 rather than 5.

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 a direct routing rule for get_company: call again with another org_uid for a different account, and use find_jobs action=get for a marketplace job's client. It does not explicitly state when to prefer this tool over list_accounts, but the organization-scoped actions and org_uid requirement imply the intended use context.

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

upwork__get_client_dashboardGet Client DashboardA
Read-only
Inspect

Get a consolidated overview of what's new: proposals received (grouped by job), pending offers, messages, and contract updates — all in one call.

Actions:

  • check: Check all activity sources in parallel. No params required.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4/5.0
Behavior4/5

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

The description adds useful behavioral detail beyond annotations: it checks all activity sources in parallel and requires no action-specific parameters. The readOnlyHint and destructiveHint annotations already establish safety, and the description does not contradict them.

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 front-loaded: the first sentence captures the full purpose, and the action bullet is short and useful. Every sentence earns its place 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?

Given the simple check-only action, read-only annotations, and complete input schema, the description provides enough context for an agent to invoke the tool correctly. It lists what the dashboard contains, though it could be slightly more explicit about the output structure or time window.

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 description coverage is 100%, so the baseline is 3. The description adds the useful clarification that the 'check' action requires no params, but it does not expand on org_uid or other parameter semantics beyond what the schema already provides.

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: getting a consolidated overview of proposals, pending offers, messages, and contract updates in one call. This distinguishes it from more granular sibling tools like list_client_proposals, get_messages, list_offers, and list_contracts.

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 'all in one call' phrasing implies this tool is for when a broad, consolidated snapshot is needed rather than individual detail calls. However, it does not explicitly name alternatives or state when not to use it, leaving the agent to infer routing.

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

upwork__get_client_financialsGet Client FinancialsA
Read-only
Inspect

View client financial reports: timesheets, work diaries, work-diary snapshots, and transaction history. timesheets organization_id defaults to org_uid. transactions may require elevated org permissions.

Actions:

  • summary: Get the client Weekly financial summary for one ISO week (mirrors Reports → Weekly summary): total charged and hours, the hourly/fixed breakdown, and the Top-5 contracts and Top-5 activities by charge. All charged amounts in this summary are USD, reported by the response-level currency field. Params: from_date (string, yyyy-mm-dd, optional — selects the week containing this date; defaults to the current week). The summary is a single Monday–Sunday week. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • timesheets: Get timesheets (hours logged on your contracts). Params: organization_id (string — defaults to org_uid), from_date (string, yyyy-mm-dd), to_date (string, yyyy-mm-dd, max 53 weeks from from_date) — at least one date required; when only from_date is set, to_date defaults to today, contract_ids (array of string), limit (number). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • work_diary: Get work diaries (time cells: activity level, screenshots, keyboard/mouse activity). With NO contract_id it returns all work diaries across the company for a single day — the marketplace 'All work diaries' view. Pass contract_id to drill into one contract's diary. Params: contract_id (string, optional — a contract id from list_contracts; omit for the company-wide view), date (string, optional — yyyy-mm-dd, defaults to today UTC), activity (string, optional filter), sort_by (string, optional), paging (string, optional — company view only).

  • snapshots: Drill into one work-diary snapshot (a contract at a point in time): mouse/keyboard event counts, memo, task, status, and hasScreenshot — activity metadata, NOT the screenshot image. Use work_diary for the diary view; use this only for per-timestamp detail. Params: input (object, required) with contractId (string) and timestamp (integer — Unix epoch seconds, e.g. a snapshotDateTime rawValue from work_diary).

  • work_days: Get work days. Params: input (object, required).

  • transactions: Get transaction history. Covers the selected account's accounting entity only — a company whose ledger spans several entities sees each separately, so this can return less than the web Transaction History page shows for the same dates. Params: ace_ids (array of accounting entity ID strings, optional — auto-resolved from org context if omitted), from_date (string, yyyy-mm-dd), to_date (string, yyyy-mm-dd) — when both dates are omitted, defaults to the last 30 days; when only from_date is set, to_date defaults to today (max 53 weeks from from_date). limit (number, default 25, max 200 — returns the most recent N transactions; total_count reports how many exist). May require elevated org permissions on some accounts. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true, and the description goes beyond them by disclosing operational traits: transactions may return less than the web page due to accounting-entity scoping, work_diary with no contract_id returns a company-wide view, snapshots return metadata not images, and various defaults/limits. This helps an agent predict actual behavior beyond the annotation flags.

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

Conciseness3/5

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

The action-by-action bullet structure is logical and front-loaded, but the same 'Optional params are refinements' paragraph is repeated nearly verbatim under four actions. This is verbose and could be consolidated. The work_days action is also minimal, so structure is uneven.

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 six-action tool with no output schema and nested params, this description is complete: it defines every action, relevant defaults, caveats, and deprecations. The only notable gap is work_days, which has almost no parameter or result description beyond 'Get work days', and there is no return-format guidance for any action.

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?

Even though schema coverage is 100%, the description adds substantial meaning: date defaulting rules, max 53-week spans, limit behavior, contract_id provenance from list_contracts, paging restrictions, and the snapshot timestamp format. It effectively documents parameters that the schema branches do not cover for work_diary, snapshots, and work_days.

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 opens with a clear verb+resource statement ('View client financial reports') and then enumerates six distinct actions, each with a specific verb and scope (summary, timesheets, work_diary, snapshots, work_days, transactions). This distinguishes the tool from siblings and makes the multi-action structure immediately understandable.

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?

Provides explicit per-action usage guidance, including when to choose work_diary vs snapshots ('Use work_diary for the diary view; use this only for per-timestamp detail'), and warns that transactions may require elevated org permissions. It also gives default behavior and date constraints, so an agent knows what to invoke and when.

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

upwork__get_draftGet DraftA
Read-only
Inspect

Retrieve a pending server-stored draft without consuming it.

Actions:

  • get: Get a pending draft for review. Params: type (required — the draft type), id (required — the draft_id returned by the creating action).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds valuable behavioral context beyond that: the draft is pending, server-stored, and retrieving it does not consume it. This clarifies the state impact of the call without contradicting the annotations.

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 compact and front-loaded: the first sentence states the core behavior, and the Actions section provides the required parameter mapping without extraneous detail. Every sentence contributes to correct invocation.

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 moderate-complexity tool with nested params and no output schema, the description covers the essential retrieval behavior, the non-consuming nature, and the required draft identifiers. It does not explain the relationship to confirm/update actions, but the schema and annotations cover the remaining operational details adequately.

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 description coverage is 100%, and the schema already documents id as 'Draft ID returned as draft_id by the creating action' and type as 'Draft type returned by the action that created the draft.' The description repeats this information rather than adding significant new semantic value, so the baseline of 3 applies.

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 uses a specific verb ('Retrieve') with a precise resource ('pending server-stored draft') and adds a key scope qualifier ('without consuming it'). This clearly differentiates the tool from siblings like upwork__confirm_draft and upwork__update_draft, which consume or modify drafts.

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 phrase 'Get a pending draft for review' establishes clear context: use this tool when you need to inspect a draft before finalizing it. It does not explicitly name alternatives or when-not-to-use conditions, but the review purpose and non-consuming behavior imply the appropriate usage boundary.

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

upwork__get_job_postingGet Job PostingA
Read-only
Inspect

View your owned job postings and search the marketplace. Use action=list to obtain posting IDs for list_client_proposals and list_client_invitations. Prior postings are useful templates when creating new jobs.

Actions:

  • get: Get an owned job posting by ID (from get_job_posting action=list). Params: job_id or job_posting_id. For marketplace jobs use find_jobs action=get or get_job_posting action=get_marketplace.

  • search_marketplace: Search marketplace job postings. Each result includes a ready-to-use url. Params: query (string), filters (object). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • get_marketplace: Get a marketplace job posting by ID. The response includes a ready-to-use url. Params: id (the numeric id, a ~02… ciphertext, or a full Upwork job URL — all accepted directly).

  • list: List the selected organization's owned job postings (not marketplace), paginated. Params: title (string, optional — partial-match filter applied upstream), limit (integer, 1–10, default 10), page (integer, default 1). Returns total_count, has_more, and next_page, plus postings[] with id, title, status, access, type, created_time, updated_time, premium, and the applicant funnel (applicants, shortlisted, messaged, offered, hired, pending_invitations, new_applicants). Use the ids for list_client_proposals / list_client_invitations; to page, call again with page=next_page. Each entry is a SUMMARY, not the full posting: description, budget, skills, screening questions and invites-sent are not included — call action=get with the id when you need them. Applicant counts ARE included, so answering "how many applied/were hired" needs no follow-up call. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.9/5.0
Behavior5/5

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

Beyond the readOnlyHint annotation, the description discloses important behaviors: list results are summaries lacking description/budget/skills, applicant counts are included, pagination uses next_page, search results include ready-to-use URLs, and get_marketplace accepts numeric IDs, ciphertexts, or full URLs. It also warns not to silently invent optional filter values. This is rich, non-obvious behavioral context that an agent needs to call the tool correctly.

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 action-labeled bullets and front-loaded purpose. Some guidance about optional refinements is repeated nearly verbatim under separate actions, adding length, but the repetition reinforces behavior at the point of use. Overall it is dense with useful information and easy to navigate.

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?

The tool exposes four distinct actions with nested parameters and no output schema, so the description must compensate. It details list return fields (total_count, has_more, next_page, postings[], applicant counts), search result URLs, get_marketplace URL output, and the relationship between list summaries and get full detail. For a multi-action tool this level of context is complete enough for an agent to invoke 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?

Although the input schema describes parameters, the description adds essential semantics: job_id is preferred and job_posting_id is an alias; marketplace id can be a numeric ID, ciphertext, or full URL; list limit is 1–10 with default 10; page uses next_page; title is a partial-match filter. It also clarifies that optional params are refinements and that the agent should surface rather than invent values. This goes well beyond 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 opens with a specific verb and resource: 'View your owned job postings and search the marketplace.' It then explicitly differentiates the four actions (get, list, search_marketplace, get_marketplace) and clarifies where to use each, including a direct pointer to find_jobs for marketplace alternatives. This makes the tool's purpose unmistakable and distinct from siblings.

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?

The description gives explicit when-to-use guidance: use action=list to obtain IDs for list_client_proposals and list_client_invitations; use action=get for full owned-posting details; use get_marketplace for marketplace jobs by ID; use find_jobs for marketplace searches. It also tells the agent when to ask before applying optional filters and how to handle broad user requests, which is actionable routing guidance.

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

upwork__get_messagesGet MessagesA
Read-only
Inspect

List rooms, find rooms by context, and read messages.

Actions:

  • list_rooms: List your rooms, most-recently-active first. The count of rooms is not available, so never state a total. Page with cursor while hasMore is true. Params: unread_only (boolean, optional — only rooms with unread messages), room_type (ALL/GROUP/ONE_ON_ONE/INTERVIEW, default ALL), limit (integer, 1–100, default 10), cursor (string, optional — next_cursor from a prior list for the next page; alias: after). unread_only and room_type both carry a note in the response describing what the filtered list does and does not cover. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • search_rooms: Find your own past conversations by free text — a participant's name (a first name is enough), a room name, or a topic. This is the way to locate an old thread with someone when you do not have its room_id: do NOT use find_freelancers for that, which searches the public marketplace rather than your own conversations. Results are room cards in the same shape list_rooms returns; pass a room's id to list_messages to read it. Params: query (string, required — the name or text to search for), limit (integer, 1–10, default 10), offset (number, optional — next_offset from a prior search for the next page; must be a multiple of limit). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • find_room: Find a room by context. Params: context_type (contract/offer/proposal/one_on_one, required), context_id (string, required), organization_id (string, required for one_on_one). For context_type=proposal: Freelancers (TALENT): cannot initiate a proposal room or send the first message on a proposal — the client must contact you first. To reply, use an existing room from list_freelancer_proposals action=get_room or get_messages action=find_room (context_type=proposal). If no room exists yet, tell the user the client needs to message first.

  • list_messages: List messages in a room, NEWEST FIRST — the default page is the tail of the conversation, not the whole thread. Before summarising a thread or answering whether something was ever discussed, page back with cursor while hasMore is true; the message count is not available, so never state one. Params: room_id (string, required), limit (integer, 1–100, default 20), cursor (string, optional — next_cursor from a prior call for the next page of older messages; alias: after). message_count is present only once the whole thread has been read (hasMore false); while paging, the number of messages in the room is unknown. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • get_message: Get a single message. Params: room_id (string, required), story_id (string, required).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.4/5.0
Behavior5/5

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

The description goes far beyond the readOnlyHint by disclosing that room and message counts are unavailable, that messages are newest-first, that hasMore drives pagination, and that message_count only appears after fully reading a thread. These are non-obvious behavioral facts that materially affect agent behavior, and nothing contradicts the annotations.

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

Conciseness3/5

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

The action-based organization is clear and the opening is front-loaded, but the optional-params guidance paragraph is repeated nearly verbatim for list_rooms, search_rooms, and list_messages. Token economy is weaker than the overall quality suggests.

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?

With no output schema, the description compensates well by explaining response semantics: room cards, newest-first ordering, hasMore, message_count availability, and when not to state totals. It still leaves the exact message/room card field shapes unspecified, which would otherwise be needed for an agent to confidently consume results.

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 already high, so the baseline is 3; the description does add useful aliases, pagination constraints, and per-action required params. However, it contradicts the schema on defaults: list_rooms and list_messages are described as default 10/20 while the schema says default 100, and the 'after' alias for list_messages is not present in the schema. These inconsistencies make the added parameter guidance unreliable.

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 opens with a specific verb–resource summary ('List rooms, find rooms by context, and read messages') and then enumerates five distinct actions with clear semantics. It also differentiates from siblings like send_message and find_freelancers, making the tool's scope unmistakable.

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?

It gives explicit when-to-use guidance, e.g., 'This is the way to locate an old thread... do NOT use find_freelancers', and instructs paging when summarizing a thread or checking whether something was discussed. It also provides nuanced guidance for optional refinements and proposal-room constraints.

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

upwork__get_rate_insightsGet Rate InsightsA
Read-only
Inspect

Get the going hourly rate range for similar jobs to guide a job's hourly budget — the same From/To range Upwork shows in the Budget step. Read-only. Use it while helping a client set an hourly budget so the suggested rate reflects the market.

Actions:

  • get: Get the suggested hourly rate range for a job. Params: experience_level (string, required — 'entry', 'intermediate', or 'expert'); and one of occupation_id (string — from the job classification) or project_text (string — the job title/description, used to infer the occupation). Returns rate_low / rate_high (USD/hr) and based_on_jobs (sample size).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true; the description reinforces this with 'Read-only' and adds meaningful context: it returns the same From/To range Upwork shows, explains parameter effect, and names return fields. No contradictions with annotations.

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 compact and front-loaded with purpose, then gives action-specific parameter and return details. The single-action bullet is slightly redundant with the tool name but every sentence contributes value.

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?

With no output schema, it correctly documents return fields (rate_low/rate_high, based_on_jobs). It explains the data source ('same range Upwork shows in Budget step') and required parameters. Minor omissions like error/edge-case behavior are not critical for a read-only lookup tool.

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 100% and schema descriptions are detailed, so the description doesn't need to compensate. It adds useful mutual-exclusion guidance (one of occupation_id or project_text) and confirms experience_level accepted values, though most parameter meaning is already in 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?

Description names a specific operation ('Get the going hourly rate range') and a concrete resource ('similar jobs' / Budget step). It distinguishes itself from sibling tools by tying directly to hourly budget guidance and market rate, so an agent can tell it apart without schema inspection.

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 explicitly says to use this when helping a client set an hourly budget so the suggested rate reflects the market. It doesn't enumerate when-not-to-use or sibling alternatives, but the intended context is clear and the tool appears unique among siblings.

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

upwork__get_tool_helpA
Read-only
Inspect

Get the full reference for a tool: its complete description and input schema, including every action and all required and optional parameters. Call this before using a tool whose listed description is brief and you need the full field list.

Params:

  • tool_name (string, required) — the tool to describe (a name from search_tools or the tool list).

ParametersJSON Schema
NameRequiredDescriptionDefault
tool_nameYesName of the tool to get full help for

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, so the read-only safety profile is covered. The description adds useful behavioral context about what the call returns—'complete description and input schema'—and the scope of that output, which goes beyond the annotations.

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?

Every sentence earns its place: the first defines the purpose, the second gives the usage trigger, and the param line clarifies the argument. It is front-loaded with the action and resource, and there is no filler or repetition that could be cut without losing 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?

With a single parameter, a read-only annotation, and no output schema, the description sufficiently explains what the tool returns and when to invoke it. Nothing an agent needs to decide to call this tool 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?

While the input schema already describes tool_name, the description adds critical sourcing guidance: 'the tool to describe (a name from search_tools or the tool list).' This tells the agent exactly where to obtain valid values, which is more helpful than the schema's generic 'Name of the tool to get full help 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?

The description opens with a specific verb and resource: 'Get the full reference for a tool: its complete description and input schema, including every action and all required and optional parameters.' This clearly distinguishes it from all sibling tools, none of which serve a meta-help function.

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 gives an explicit call condition: 'Call this before using a tool whose listed description is brief and you need the full field list.' It does not name alternative tools, but no alternative exists; a clearer 'when not to use' clause is the only minor omission.

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

upwork__get_upload_statusGet Upload StatusA
Read-only
Inspect

Returns file_uid values for files a user uploaded through the web UI. Action name is get (not get_status). Upload sessions expire 30 minutes after start_attachment_upload; poll within that window.

Actions:

  • get: Get uploaded file metadata. Params: task_id (string, required). Returns file_uid values and file metadata. Does not return file content.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.4/5.0
Behavior5/5

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

Beyond the readOnlyHint annotation, the description discloses important behavior: upload sessions expire 30 minutes after start_attachment_upload, the response includes file_uid values and metadata, and file content is not returned. These details are actionable and not present in the annotations or schema.

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 compact and front-loaded with the core purpose and key caveats. Minor redundancy exists between the opening sentence and the Actions block, but the structure is clear and every section contributes useful guidance.

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?

With no output schema, the description adequately explains what the caller will receive: file_uid values and metadata, not file content. It also covers the critical time constraint and the task_id source, making the tool callable without needing to infer hidden behavior.

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 description coverage is 100%, so the schema already documents task_id and org_uid. The description adds context about the task_id coming from start_attachment_upload and reinforces the expiry window, but it does not significantly expand on the parameter meanings beyond what the schema provides.

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 returns file_uid values for files uploaded through the web UI, using a specific verb and resource. It also disambiguates the action name ('get', not 'get_status') and explicitly notes what the tool does not return (file content), setting it apart from related upload tools.

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 gives concrete usage context: poll within the 30-minute window after start_attachment_upload, and use action name 'get'. It does not explicitly name alternative tools or when not to use this tool, but the timing and operational instructions are clear enough to guide correct invocation.

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

upwork__invite_freelancerInvite FreelancerAInspect

Invite a freelancer to a job posting. Use list_jobs to see your jobs and how many invites remain on each, then send returns a draft — call confirm_draft with type='invitation' to send.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval. Call get_tool_help(tool_name="invite_freelancer") for the actions, parameters, and how to use this tool.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters — call get_tool_help(tool_name="invite_freelancer") for the full field list.
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.3/5.0
Behavior5/5

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

Beyond the annotations, the description clearly discloses that this is a write operation requiring explicit user confirmation and that the tool returns a draft rather than immediately sending. This is critical behavioral information for safe invocation and is not supplied by the annotations alone.

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 front-loaded and generally concise, with the core workflow in the first two sentences. There is minor redundancy in repeating that confirm_draft must be called after a draft is returned.

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 write operation with multiple actions and nested parameters, the description covers the actual workflow, the confirmation requirement, and points to get_tool_help for the full field list. It could be more self-contained by enumerating the params fields directly, but it is complete enough to guide correct usage.

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?

The schema already provides descriptions for action, params, and org_uid, so baseline is met. The description adds useful action-level context for list_jobs and send, but delegates the actual action-specific parameter fields to get_tool_help instead of documenting them.

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 action — 'Invite a freelancer to a job posting' — and clearly identifies the resource and outcome. It also distinguishes the tool from the confirmation step by explaining that send only returns a draft that must later be confirmed.

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 gives explicit workflow guidance: use list_jobs first to check remaining invites, then send, then confirm_draft with type='invitation'. It lacks explicit when-not-to-use exclusions, but the sequencing and reference to get_tool_help provide clear usage context.

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

upwork__list_accountsA
Read-only
Inspect

List your available Upwork accounts (Freelancer, Client, Agency). Call this first.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful scoping context ('your available' accounts) and the sequential behavior 'Call this first', but it does not describe response format, pagination, or auth nuances. It is adequate but not rich.

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 efficient sentence plus a short directive. Every word earns its place: the action, the scope, the account-type enumeration, and the placement instruction. There is no filler or redundant restating of the tool name.

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 parameterless, read-only listing tool, the description is complete enough for correct invocation. It states what the tool returns (accounts), the types it covers, and the recommended call order. No output schema exists, but the description's meaning directly implies a list result, so nothing essential is missing.

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 has zero parameters, so the schema vacuously covers 100% of parameter semantics. With no parameters to document, the description need not add parameter details; the baseline of 4 applies and nothing in the description undermines it.

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 verb ('List'), a clear resource ('your available Upwork accounts'), and enumerates the account types (Freelancer, Client, Agency). It is easily distinguished from related tools like get_account by the plural 'accounts' and the 'available' qualifier, and 'Call this first' positions it as the intended entry point.

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 instruction 'Call this first' gives explicit, actionable timing context, telling the agent to invoke this tool before others. However, it does not name alternatives or state when not to use it, so it lacks full exclusion guidance.

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

upwork__list_client_invitationsList Client InvitationsA
Read-only
Inspect

List or get client job invitations for one owned job posting. Requires job_reference from get_job_posting action=list (postings[].id). Invitations are per-job only — there is no list_all.

Actions:

  • list: List active invitations for a job, or get one invitation when invitation_id is set. Params: job_posting_id, job_id, or job_reference (string, required — owned posting ID from get_job_posting action=list), invitation_id (string, optional — when set, returns that invitation only; organizationId_eq comes from org_uid), limit (integer, 1–10, default 10) — list only), cursor (string, optional — pageInfo.endCursor from a prior list for the next page; alias: after; list only). Org comes from org_uid on execute_tool. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A5/5.0
Behavior5/5

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

Annotations already mark read-only and non-destructive; the description adds pagination details (cursor/pageInfo.endCursor), limit bounds (1–10), invitation_id override behavior, and the source of org (org_uid on execute_tool). It also discloses the expected post-return behavior of mentioning refinements.

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?

Structured with a leading summary then an Actions section; each sentence adds either a constraint, prerequisite, or operational rule. It is longer than average but not bloated given the alias and pagination complexity.

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?

Covers input aliases, required prior step, pagination, limit, optional param policy, and org resolution. Given there is no output schema, it even hints at the paged return shape via pageInfo.endCursor, so a model has enough to invoke and continue a multi-page list.

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?

Although schema covers all params, the description clarifies aliases (job_id, job_reference for job_posting_id), marks owned-posting-id as required, explains cursor alias 'after', and ties invitation selection to invitation_id. This prevents mis-use that bare schema would allow.

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 opening sentence names the verb ('List or get'), the object ('client job invitations'), and the scope ('for one owned job posting'), which is enough to separate it from sibling tools like list_client_proposals or list_contracts. The follow-up 'there is no list_all' removes ambiguity about aggregate behavior.

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?

It states the prerequisite ('Requires job_reference from get_job_posting action=list (postings[].id)') and explicitly warns the operation is per-job only. It also gives actionable policy on optional params: do not invent values, ask before applying selective filters, and mention refinements after results.

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

upwork__list_client_proposalsList Client ProposalsA
Read-only
Inspect

View proposals on your job postings. Use action=list_all to discover proposals across all postings without a job_posting_id. Use action=list when you already have job_posting_id from get_job_posting action=list. Prior proposals can provide context for drafting offers.

Actions:

  • list: List proposals for a job. Params: job_posting_id or job_id (string, required — from get_job_posting action=list), status (string), shortlisted (bool — only proposals the client shortlisted), limit (integer, 1–50, default 50), cursor (string, optional — pageInfo.endCursor from a prior list for the next page; alias: after). The response includes totalCount and pageInfo; when the user wants to review all applicants, page through with cursor until hasNextPage is false. Use list_all to discover proposals without a posting id. Declined proposals carry get_unavailable=true — that list card is the complete view; do not call get on their id. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • get: Get full proposal details. Does not work for declined proposals (see list/list_all's get_unavailable flag) — use the list card for those instead. Params: id or proposal_id (string, required).

  • list_all: List proposals across all your job postings. Params: status (string, optional), limit_per_job (integer, 1–10, default 10). Each job's proposals are capped at limit_per_job; a job whose pageInfo.hasNextPage is true has more applicants — page them with action=list using that job_posting_id and pageInfo.endCursor. jobs_truncated=true means the org has more postings than were scanned; narrow with action=list per posting. Declined proposals carry get_unavailable=true — that list card is the complete view; do not call get on their id. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • metadata: Get valid proposal metadata (durations, engagement values). No params needed.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds substantial behavioral context beyond that: declined proposals carry get_unavailable=true and get will not work for them, pagination semantics via pageInfo.hasNextPage and endCursor, jobs_truncated=true meaning the org has more postings than were scanned, and the policy that 'Optional params are refinements: do not silently invent values.' The description also explains the handoff between list_all and list for paging individuals jobs. No contradiction with annotations exists.

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 long, but it is tightly organized per action (list, get, list_all, metadata) with each sentence carrying operational value — no filler. Some content is duplicated verbatim across the list and list_all sections (the declined-proposal and refinement guidance), which is slightly redundant, but this repetition is defensible for an agent that may read only one section. The purpose statement is front-loaded before the action details.

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 four-action tool with a complex conditional schema, no output schema, and significant cross-action interplay, the description covers everything needed: action selection, parameter sources, pagination loops, the declined-proposal edge case, truncation behavior, and refinement etiquette. An agent has enough information to select the correct action, supply correct parameters, and page through all results without additional guesswork.

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 100%, so the baseline is 3, but the description adds meaningful semantic value beyond the schema: it explains that job_posting_id comes from get_job_posting action=list, that cursor comes from pageInfo.endCursor of a prior list, the alias relationships (cursor/after, job_id/job_posting_id, id/proposal_id), and the meaning of limit_per_job as a per-job cap. These provenance and cross-tool relationships are not inferable from the schema alone.

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 opens with 'View proposals on your job postings,' a specific verb+resource statement. It then clearly delineates four distinct actions (list, get, list_all, metadata) with their own purposes, which distinguishes the tool from siblings like upwork__manage_client_proposals (management vs. viewing) and upwork__list_offers (proposals vs. offers). An agent can immediately tell what this tool does and what each sub-action does.

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?

The description gives explicit routing rules: 'Use action=list_all to discover proposals across all postings without a job_posting_id' and 'Use action=list when you already have job_posting_id from get_job_posting action=list.' It also states when NOT to use a feature ('do not call get on their id' for declined proposals) and provides behavioral norms for optional filters, including an explicit 'Ask before applying optional filters' list (best, top, cheapest, near me, urgent, or only). This is exemplary usage guidance.

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

upwork__list_contractsList ContractsA
Read-only
Inspect

View and search your contracts and time reports. ID provenance: use action=search to discover rows; for CLIENT search results use node.contract.id (not node.id) as contract_id. Offer ids for list_offers/get come from list_offers or manage_offers list, not from list_contracts search. See docs/id-chaining.md.

Actions:

  • search: Discover contracts/offers — call this FIRST. For freelancers: vendor_id (string, defaults to your user ID). For clients: searches clientOffers automatically. Common: contract_statuses (array: ACTIVE, CLOSED, PAUSED), start_date_before (string), end_date_after (string), limit (integer, 1–10, default 10), offset (number, default 0). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • list: Fetch known contracts by ID only — do NOT use for discovery. Params: ids (string[], required, 1–100). Obtain ids from search (node.contract.id) or get. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • get: Get full contract details by contract ID. Authoritative milestone read for active/fixed-price contracts: offer.milestones includes dueDateTime, state (plus state_label), depositAmount, fundedAmount, paid, submissionCount, and submission records at data.contractDetails.offer.milestones[].submissions[]. For manage_milestones action=reject, choose the submission with the latest submissionDateTime and pass its id — no offer-ID chaining needed. Params: contract_id (string, required).

  • get_original_proposal: Get the original proposal for a contract. Params: id (string, required).

  • timesheets: Get timesheets (time report) for contracts. Params: organization_id (string — defaults to org_uid), from_date (string, yyyy-mm-dd), to_date (string, yyyy-mm-dd, max 53 weeks from from_date) — at least one date required; when only from_date is set, to_date defaults to today, contract_ids (array of string), limit (integer, 1–10, default 10). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • end_reasons: Get valid reason codes for ending a contract. Params: reason_type (required enum: CONTRACT_END_HOURLY | CONTRACT_END_FIXED).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already mark the tool read-only and non-destructive, and the description adds substantial behavioral context beyond that: ID provenance (node.contract.id vs node.id), defaults for vendor_id/organization_id/to_date, pagination cursor/offset semantics, the 'ask before applying optional filters' policy, and the note that get is the authoritative milestone read. No contradiction with annotations.

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 long but logically grouped by action, with the main purpose and ID provenance front-loaded. It loses one point for repeating the same optional-refinements paragraph verbatim under multiple actions, which could have been consolidated without losing clarity.

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?

Despite having no output schema, this complex six-action tool is thoroughly specified: input defaults, pagination, response shape hints (node.contract.id, milestones[].submissions[], pageInfo.endCursor), cross-tool ID chaining, and helpful exclusions are all present. There is no significant gap for an agent deciding how and when to call the 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 100%, so parameters are already documented; the description goes further by explaining how parameters relate across actions, e.g., ids come from search node.contract.id, contract_id for get comes from search or get, and it adds behavioral constraints like 'at least one date required' and 'max 53 weeks from from_date'.

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 opens with a specific verb+resource ('View and search your contracts and time reports') and enumerates six distinct actions with clear responsibilities: search, list, get, get_original_proposal, timesheets, and end_reasons. This clearly differentiates the tool from sibling tools like list_offers and list_client_proposals by focusing on contracts and associated reports.

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?

Provides explicit when-to-use rules: call search FIRST for discovery, use list only for known IDs ('do NOT use for discovery'), use get for full details, and use end_reasons for reason codes. It also routes to related workflows, e.g., manage_milestones action=reject, and warns against inventing optional filters, giving the agent unambiguous selection criteria.

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

upwork__list_offersList OffersA
Read-only
Inspect

View and list offers. Use list_mine to see all offers for your org. Use get to fetch full details of a specific offer. The 'id' from these results is the offer_id needed for manage_proposals action=accept_invitation.

Actions:

  • get: Get full offer details by offer ID. Milestones match list_contracts get / manage_offers get (dueDateTime, state + state_label, depositAmount, fundedAmount, paid, submissionCount). For active contracts prefer list_contracts action=get. Params: offer_id or id (string, required — from list/list_mine here; NOT clientOffers node.id from list_contracts search).

  • get_attachments: List the file attachments on an offer (documents the client attached to the offer), each with its file name and a downloadable link. Params: offer_id or id (string, required — the offer ID). Returns fileName and link per attachment; present each as a markdown link (the link is presigned and expires in about 15 minutes).

  • list: List offers for your account — offers you sent (client) or received (freelancer). No filter needed; the tool uses your org_uid automatically. Results are newest first. Params: limit (integer, 1–10, default 10), page (integer, default 1), Optional: states (array of strings to filter by offer state — use role-appropriate values; returned offer state matches these keys). Client: sent, awaiting_acceptance, contract_started, awaiting_approval, expired, denied, draft, withdrawn, canceled. Freelancer/agency: awaiting_your_acceptance, contract_started, awaiting_client_approval, expired, denied, draft, withdrawn, canceled. Do NOT pass searchAttribute, id, or a filter object. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

  • list_mine: List your offers (same as list). Results are newest first. Params: limit (integer, 1–10, default 10), page (integer, default 1), Optional: states (array of strings to filter by offer state — use role-appropriate values; returned offer state matches these keys). Client: sent, awaiting_acceptance, contract_started, awaiting_approval, expired, denied, draft, withdrawn, canceled. Freelancer/agency: awaiting_your_acceptance, contract_started, awaiting_client_approval, expired, denied, draft, withdrawn, canceled. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.9/5.0
Behavior5/5

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

The annotations already declare readOnlyHint=true and destructiveHint=false, and the description supplements this with meaningful behavioral details: results are newest first, the org_uid is used automatically, state values are role-appropriate, attachment links are presigned and expire in about 15 minutes, and optional params should not be silently invented. No contradiction exists between description and annotations.

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 action-based bullets and front-loaded guidance. However, the list and list_mine sections duplicate the same parameter details and refinement policy nearly verbatim, which adds length and some redundancy. Still, the structure makes the multi-action tool easier to navigate.

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 multi-action read-only tool with no output schema, the description is complete: it covers action selection, parameters, source of identifiers, output behavior, attachment link expiry, role-specific state lists, and guidance on optional refinements. No critical information an agent needs to call the tool 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?

Although the input schema already covers 100% of parameters, the description adds substantial semantic value: it explains where offer_id comes from and what it is NOT (clientOffers node.id), lists role-specific state values for clients vs freelancers/agencies, clarifies the relationship between id and offer_id, and warns against passing unsupported parameters like searchAttribute. This goes well beyond the schema alone.

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 ('View and list offers') and enumerates distinct actions (get, get_attachments, list, list_mine) with specific verbs and resources. It also differentiates internal actions and references the sibling context, e.g., 'For active contracts prefer list_contracts action=get', making it easy for an agent to select the right operation.

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?

The description gives explicit when-to-use guidance: 'Use list_mine to see all offers for your org', 'Use get to fetch full details of a specific offer', and 'For active contracts prefer list_contracts action=get'. It also instructs the agent not to pass forbidden params and how to handle optional refinements, including asking before applying selective filters. This is strong, actionable routing guidance.

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

upwork__manage_client_proposalsManage Client ProposalsAInspect

Manage proposals on your job postings while reviewing applicants: shortlist/un-shortlist and decline. To HIRE an applicant, use manage_offers create_draft instead (accepting a proposal is an offer).

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Each write requires separate confirmation even if the user said "approve all".

Actions:

  • shortlist: Shortlist (or un-shortlist) a proposal on your job posting. Shortlisting flags a promising applicant for later review; it does NOT hire them (to hire, use manage_offers create_draft). Params: proposal_id (string, required), job_posting_id (string, required — numeric posting id), shortlisted (bool, optional — default true; pass false to un-shortlist).

  • decline: Decline a proposal on your job posting. Returns a draft — present it and call confirm_draft with type='proposal_decline' and the returned draft_id to actually decline (the freelancer is notified). Params: proposal_id (string, required), job_posting_id (string, required), reason (string — human-readable reason, auto-matched to valid reasons), message (string, optional message to applicant). Optional params are user choices: do not silently invent values. Briefly surface relevant optional inputs before the action when they could affect the outcome. If the user does not choose them, proceed with only required params plus context the user already provided.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A5/5.0
Behavior5/5

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

The description goes well beyond annotations by disclosing that this is a confirmation-gated write operation requiring explicit user approval for each action. It also explains the decline workflow's draft/confirm_draft step and clarifies that shortlisting does not hire, all of which are non-obvious behavioral details.

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 dense but every section adds value: scope, confirmation requirement, action-specific details, and routing to sibling tools. The critical write-confirmation warning is prominent, and the action details are organized in scannable bullets.

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 the nested params object and lack of an output schema, the description provides complete guidance for using the tool correctly. It covers both actions, required and optional parameters, the confirmation obligation, the decline draft follow-up, and the distinction from hiring.

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?

Although the input schema is generic with a params object, the description thoroughly documents every action-specific parameter: proposal_id, job_posting_id, shortlisted, reason, and message. It explains defaults and optionality, such as shortlisted defaulting to true and the reason being auto-matched.

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 manages proposals on job postings with two specific actions: shortlist/un-shortlist and decline. It explicitly distinguishes itself from a hiring action by directing the agent to use manage_offers create_draft for proposals that should become offers.

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?

The description gives explicit when-to-use context: managing proposals while reviewing applicants. It also provides a clear alternative: if the intent is to hire or accept a proposal, use manage_offers create_draft instead. This removes ambiguity about sibling tool selection.

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

upwork__manage_milestonesManage MilestonesA
Destructive
Inspect

WRITE milestone management. create, edit, delete, and reject run through MCP (draft -> confirm_draft). fund (activate) and approve move money — funding escrow and releasing payment — so they are completed by you on Upwork and return a link, NOT a draft. No list/get actions — inspect milestone state via list_contracts action=get (offer.milestones includes state, amounts, paid, submissionCount).

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval. Call get_tool_help(tool_name="manage_milestones") for the actions, parameters, and how to use this tool.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters — call get_tool_help(tool_name="manage_milestones") for the full field list.
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.6/5.0
Behavior4/5

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

Annotations mark the tool destructive and non-readonly; the description adds important contextual behavior: draft-based actions require confirm_draft, explicit user confirmation is needed, and money-moving actions return a link. There is slight ambiguity in 'Returns a draft for review' because it could be read as applying to all six actions even though the prior sentence clearly carves out the link-returning ones.

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 compact, front-loaded with the verb and resource, and every sentence adds operational value. The caps warnings and the pointer to get_tool_help are structurally effective without unnecessary 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?

The description covers the essential write flow, the special money-moving exception, how to check milestone state when reads are needed, and where to obtain action-specific parameters. The only soft spot is the slightly ambiguous draft-return statement, but overall it provides enough context for an agent to proceed correctly.

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 covers the three top-level parameters, and the description adds meaning to the action enum by explaining that create/edit/delete/reject produce drafts for confirm_draft while activate/approve return links and move money. The params object itself remains opaque, but the description explicitly routes the agent to get_tool_help for the full field list.

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 explicitly states 'WRITE milestone management' and enumerates the precise operations: create, edit, delete, reject, activate, approve. It distinguishes the money-moving actions from the draft-based ones and explicitly says there are no list/get actions, making the tool's purpose unmistakable.

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?

The description gives explicit when-to-use and when-not-to-use guidance: use it for milestone writes, but inspect milestone state via list_contracts action=get. It also explains that activate and approve return a link for completion on Upwork rather than a draft, and points to get_tool_help for detailed usage.

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

upwork__manage_offersManage OffersAInspect

Create draft offers and manage offers to freelancers.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Creates a draft that must be finalized on upwork.com by the user. Call get_tool_help(tool_name="manage_offers") for the actions, parameters, and how to use this tool.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters — call get_tool_help(tool_name="manage_offers") for the full field list.
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A3.8/5.0
Behavior4/5

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

Annotations only indicate readOnly=false, openWorld=true, idempotent=false, destructive=false. The description adds meaningful behavioral context beyond these: it explicitly warns that this is a write operation requiring user confirmation and that draft creation must be finalized by the user on upwork.com. This is valuable for agent decision-making and does not contradict the annotations.

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 purpose sentence, a critical warning, and a pointer to detailed help. The write operation warning is front-loaded, which is appropriate for a non-read-only tool. Every sentence earns its place with no 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?

This is a multi-action tool with nested params and no output schema. The description gives the essential warning and directs the agent to get_tool_help for exhaustive action and parameter details. It does not enumerate action semantics or return values, but the explicit pointer to help and the schema enum mitigate that gap for a complex tool.

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 description coverage is 100%, so the baseline is 3. The description adds little beyond the schema for parameters; it only points to get_tool_help for the full field list. It does not explain action-specific parameter semantics, but the schema already documents each parameter at a basic level.

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 clear verb+resource: 'Create draft offers and manage offers to freelancers.' This identifies the tool's domain and primary action. However, 'manage offers' is broad and does not explicitly distinguish this tool from siblings such as list_offers or get_draft, though the action enum provides some scope.

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 provides important usage context: it is a WRITE OPERATION requiring explicit user confirmation, and created drafts must be finalized on upwork.com. It also tells the agent to call get_tool_help for actions and parameters. However, it does not state when to prefer this tool over alternatives like list_offers or get_draft, nor when those siblings are more appropriate.

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

upwork__manage_talent_listsManage Talent ListsA
Destructive
Inspect

Save freelancers to your talent lists ("Your Lists"), create lists, and browse the freelancers in a list. Get freelancer_id (personId) from find_freelancers.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Each write requires separate confirmation even if the user said "approve all".

Actions:

  • list_lists: List your talent lists ("Your Lists"). No params. Returns each list's list_id (only for custom lists), list_type, title, and talent_count.

  • create_list: Create a new talent list. Params: title (string, required), description (string, optional).

  • delete_list: Delete a talent list. Params: list_id (string, required — a custom list's id).

  • save: Save (favorite) a freelancer. Params: freelancer_id (string, required — personId from find_freelancers), list_id (string, optional — a custom list's id from list_lists). OMIT list_id to add to your default "Favorites" list, which the tool creates automatically if it doesn't exist yet.

  • unsave: Remove a freelancer from a list. Params: freelancer_id (string, required), list_id (string, optional — the custom list to remove from; omit to remove from your default "Favorites" list).

  • list_talents: List the freelancers in a list. Params: list_id (string, optional — a custom list's id; omit to list all saved freelancers across your lists), limit (integer, 1–20, default 20), offset (number, default 0). Note: newly saved freelancers may take a moment to appear here — use lists_for_talent for an immediate check.

  • lists_for_talent: Show which of your lists a freelancer is in. Params: freelancer_id (string, required — personId).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.5/5.0
Behavior5/5

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

The description adds substantial behavior beyond annotations: starts with a prominent WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION directive with per-operation approval semantics, notes that the default Favorites list is auto-created, discloses eventual consistency for newly saved freelancers, and states what list_lists returns. No contradiction with destructiveHint=true or readOnlyHint=false.

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 long but earned by a seven-action surface; the purpose statement and write-warning are front-loaded, and each action occupies a single dense line. Minor redundancy exists (the tool title is restated as 'Your Lists'), but nothing is empty 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?

For a multi-action tool with no output schema, coverage is strong: all params documented, cross-tool references included (find_freelancers, list_accounts), edge cases covered (auto-created Favorites, delayed visibility). The only gap is that return shapes are specified only for list_lists, not for the mutation actions.

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?

Though top-level schema coverage is reported at 100%, the params object is only conditionally documented for list_talents; the other six actions rely on the description for parameter meaning. The description compensates by specifying required vs optional, defaults, ranges, omit-to-use-Favorites semantics, and ID provenance (list_id from list_lists, freelancer_id as personId), exceeding the baseline.

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 opens with a specific verb+resource statement — 'Save freelancers to your talent lists, create lists, and browse the freelancers in a list' — and then enumerates seven concrete actions with distinct semantics. It differentiates from siblings like find_freelancers, invite_freelancer, and manage_offers by focusng on the talent-list domain.

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 gives clear action-level context and practical routing: freelancer_id is sourced from find_freelancers, and list_talents includes a note to use lists_for_talent for an immediate check. It lacks an explicit 'when not to use' alternative at the tool level, but the per-action guidance is concrete enough to steer correct selection.

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

upwork__post_jobManage Job PostingA
Destructive
Inspect

Create or update a job posting. For create, returns a draft for review before posting. Use confirm_draft to publish after approval. Provide skills as human-readable names (e.g., 'React', 'WordPress') — they are resolved automatically.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval. Call get_tool_help(tool_name="post_job") for the actions, parameters, and how to use this tool.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters — call get_tool_help(tool_name="post_job") for the full field list.
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.1/5.0
Behavior5/5

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

This description goes well beyond the annotations. It discloses that the tool is a WRITE OPERATION requiring explicit user confirmation, that it does not post directly but returns a draft for review first, and that skills are 'resolved automatically' from human-readable names. These are critical execution traits an agent cannot infer from readOnlyHint=false or destructiveHint=true alone, making the two-step draft/confirm behavior and the confirmation gate genuinely valuable context.

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 the first sentence and the high-stakes confirmation warning is prominently placed. However, the draft/confirm workflow is stated twice in near-identical terms ('For create, returns a draft for review before posting. Use confirm_draft to publish after approval' and 'Returns a draft for review — call confirm_draft to execute after explicit user approval'), which is redundant and could be consolidated into a single sentence.

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 multi-action, destructive tool with an opaque nested params object and no output schema, the description covers the essential ground: the create workflow, the confirmation requirement, and the skill format. It explicitly points to get_tool_help for the missing action/parameter detail. The main gaps are that close/close_reasons actions are never mentioned and the expected return shape beyond 'a draft' is unspecified, though the help pointer mitigates these.

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 100%, so the baseline is 3. The description adds one useful semantic detail — skills should be given as human-readable names and are auto-resolved — which the schema's generic 'Action-specific parameters' line lacks. However, the params object itself remains opaque, with its full field list externalized to a get_tool_help call; the description acknowledges this delegation but does not compensate for the gap.

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 opens with a specific verb+resource, 'Create or update a job posting,' which is concrete and identifiable. It distinguishes itself from the sibling publish step by naming confirm_draft ('Use confirm_draft to publish after approval'). However, the tool's action enum also includes close and close_reasons, which the description never surfaces, leaving the stated purpose slightly narrower than the tool's actual scope.

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 establishes a clear workflow: this tool creates or updates a posting and returns a draft, and confirm_draft is the designated follow-up for publishing. This effectively routes the agent between post_job and confirm_draft without ambiguity. It also directs the agent to get_tool_help for full details. It stops short of naming alternatives for reads (get_job_posting) or drafts (get_draft/update_draft), so inversion guidance is partial.

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

upwork__send_messageSend MessageA
Destructive
Inspect

Create rooms and send messages. Freelancers (TALENT): cannot initiate a proposal room or send the first message on a proposal — the client must contact you first. To reply, use an existing room from list_freelancer_proposals action=get_room or get_messages action=find_room (context_type=proposal). If no room exists yet, tell the user the client needs to message first.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Each write requires separate confirmation even if the user said "approve all".

Actions:

  • create_room: Create a group room. Params: input (object, required — RoomCreateInputV2).

  • send: Send a message to a room. Params: room_id (string, required), message (string, required unless file_attachments is set; max 10240 characters — if the user's text is longer, ask them to shorten it rather than sending it truncated). file_attachments (array, optional — each item needs file_id and file_name from start_attachment_upload; include image_id when present).

  • send_to_user: Send a message to a user (auto-creates 1-on-1 room if needed). Starting a conversation with a freelancer you are not yet connected to uses one of a limited number of new connections per day; the response includes remaining_connections. Optionally attach a job via job_posting_id to share it — the recipient gets a link plus a job id their assistant can open with find_jobs get. Params: user_id (string, required), org_id (string, required — recipient's org ID), job_posting_id (string, optional), message (string, required unless file_attachments is set; max 10240 characters — if the user's text is longer, ask them to shorten it rather than sending it truncated). file_attachments (array, optional — each item needs file_id and file_name from start_attachment_upload; include image_id when present).

  • message_proposal: Send a message to a proposal applicant (auto-creates room if needed). Params: job_posting_id (string, required), proposal_id (string, required), message (string, required unless file_attachments is set; max 10240 characters — if the user's text is longer, ask them to shorten it rather than sending it truncated). file_attachments (array, optional — each item needs file_id and file_name from start_attachment_upload; include image_id when present).

  • edit: Edit a sent message. Params: room_id (string, required), story_id (string, required), message (string, required unless file_attachments is set; max 10240 characters — if the user's text is longer, ask them to shorten it rather than sending it truncated).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.9/5.0
Behavior5/5

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

Beyond annotations (readOnly=false, destructive=true), it discloses that every write requires explicit confirmation, auto-creates rooms, consumes limited new connections, depends on attachment upload, and supports message editing. No contradiction with annotations.

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 structured with front-loaded constraints and clear action bullets, but the message-limit and file-attachment caveat is repeated verbatim four times, adding unnecessary length.

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 multi-action write tool with no output schema, it covers prerequisites (RoomCreateInputV2, attachment upload, org_uid), role restrictions, per-action params, side effects, and an important response detail (remaining_connections). Nothing essential to selecting or invoking the tool 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?

The input schema only has generic action/params/org_uid fields; the description specifies all action-specific parameters, requiredness, the message length limit, attachment file_id/file_name/image_id requirements, and job_posting_id behavior. This greatly exceeds the schema's coverage.

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 first sentence states the operation verb and resource ('Create rooms and send messages') and the body enumerates five distinct actions, so an agent can identify what the tool does and how to pick an action. It also contrasts proposal-room initiation with replying in existing rooms, which further separates it from related message and proposal tools.

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?

Provides explicit when and when-not guidance: freelancers cannot initiate proposal rooms or send the first proposal message; if no room exists, tell the user the client must message first; reply via list_freelancer_proposals/get_messages. It names the alternative tools and also mandates separate confirmation per write.

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

upwork__set_tool_modeSet Tool ModeAInspect

View or change how MCP tools are presented. full_list shows all tools directly; search_execute uses search_tools/execute_tool indirection.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Each write requires separate confirmation even if the user said "approve all".

Actions:

  • get: Get the current tool mode preference. No params required.

  • set: Set the tool mode preference. Params: mode (string, required — 'full_list' or 'search_execute'). Takes effect on your next tool call or tools/list request.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.6/5.0
Behavior5/5

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

The description clearly discloses that set is a write operation, requires explicit user confirmation for each write, and takes effect on the next tool call or tools/list request. These behavioral details go well beyond the annotations, which only indicate non-read-only, non-idempotent, non-destructive hints.

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 a clear purpose, prominent write-operation warning, and bulleted action list. There is slight redundancy between the 'WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION' header and the following sentence restating the same requirement, but the overall structure is 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?

The description provides everything needed to call the tool correctly: the two actions, the mode values, the required confirmation behavior, and the timing of effect. It does not describe the expected return shape, but there is no output schema and the invocation details are sufficiently complete for an agent.

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?

Although the input schema has 100% description coverage for its top-level properties, the nested params object is generic and does not enumerate the mode parameter. The description fills this critical gap by specifying mode as a required string with allowed values 'full_list' or 'search_execute', and also clarifies that get requires no params.

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 'views or changes how MCP tools are presented' and explains the two presentation modes, full_list and search_execute. This precisely distinguishes it from related tools like set_tool_permission, which concerns permissions rather than presentation mode.

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 gives explicit context on when to use get vs set, and explains the practical difference between the two mode values. It does not explicitly compare against alternative tools, but the purpose is specific enough that an agent can infer when to invoke it.

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

upwork__set_tool_permissionSet Tool PermissionAInspect

View or change per-tool write confirmation settings. Write tools default to 'always_ask'. Set 'always_allow' to let an agent run a specific tool without asking for confirmation first — useful for automated flows. This applies in search_execute mode only, and it never bypasses the draft-confirm gate: a destructive write still requires a separate confirm_draft with the draft_id.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Each write requires separate confirmation even if the user said "approve all".

Actions:

  • get: Get permission for a tool or all tools. Params: tool_name (string, optional — omit to list all).

  • set: Set permission for a tool. Params: tool_name (string, required), permission (string, required — 'always_ask' or 'always_allow').

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the annotations, the description discloses that this is a write operation requiring explicit user confirmation, that each write needs separate confirmation even after 'approve all,' and that it does not bypass the separate confirm_draft flow for destructive writes. This is substantive, safety-critical behavioral context that the annotations alone do not provide.

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, then gives usage context, a clear safety warning, and a compact action list. Every sentence contributes either to selecting the tool, invoking an action, or avoiding unsafe behavior; there is no filler or redundancy that weakens the guidance.

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 purpose, usage boundaries, safety requirements, and action-specific parameters, which is strong. It does not describe return values or the response shape for get/set, and there is no output schema, but the core calling decisions and safety constraints are complete enough for an agent to act correctly.

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 top-level schema only describes action, params, and org_uid generically, but the description adds the missing nested parameter details: tool_name optional for get and required for set, plus the permission enum 'always_ask'/'always_allow'. It does not repeat every schema field, but it substantially clarifies the action-specific parameters 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 opens with a specific verb-resource pair: 'View or change per-tool write confirmation settings.' It immediately distinguishes the tool from siblings by naming the exact domain (write confirmation settings) and breaks it into get/set actions, so an agent can tell what it does and how it differs from other Upwork tools.

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?

It gives explicit when-to-use guidance: set 'always_allow' for automated flows, and explains the default 'always_ask' state. It also provides when-not/limitations: 'This applies in search_execute mode only' and 'it never bypasses the draft-confirm gate,' making the boundary of use clear.

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

upwork__start_attachment_uploadStart Attachment UploadAInspect

Requests a secure file upload from the user. Creates a short-lived upload session and returns task_id plus fallback_url. In MCP App-capable hosts, an inline upload UI may appear; otherwise share fallback_url with the user. The inline upload UI supports up to 7 MB per file. The fallback_url page supports up to 100 MB per file and 300 MB total; use it for larger files. Never ask for base64 text or local file paths. Before calling upload, you MUST know the upload context. Ask the user to choose messages, proposals, offer, milestones, job, or invitation when it is not obvious from the conversation. Never guess a context.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Each write requires separate confirmation even if the user said "approve all".

Actions:

  • upload: Create a secure, short-lived file upload session for the user. context (string, required) selects the attachment backend: messages = room message attachments (requires room_id); proposals = job-application/proposal attachments; offer = offer attachments; milestones = milestone attachments; job = job posting attachments; invitation = attachments when a freelancer accepts a client invitation. If the user did not clearly say where the file belongs, ask which context they want before calling start_attachment_upload. Params: reason (string, optional — why you need the file); room_id (string, required when context is messages). Returns task_id, fallback_url and expires_at. After the user submits files in the inline UI, poll get_upload_status with task_id until status is ok. The session expires 30 minutes after it is created: keep the task_id, and if the user has not finished by then start a new upload rather than trying to confirm against the expired one.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.9/5.0
Behavior5/5

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

Annotations are all neutral/negative (readOnlyHint=false, idempotentHint=false, etc.), so the description carries the full burden and delivers richly: write-operation confirmation policy, short-lived session, size limits, conditional context requirement, polling requirement, return values, and expiry behavior. Nothing contradicts the annotations.

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 long but every section earns its place given the tool's conditional schema and write-operation stakes; the core purpose is front-loaded and the WRITE OPERATION warning is prominent. The only flaw is minor redundancy: the 'ask the user for context rather than guessing' instruction appears both in the opening paragraph and again in the Actions section.

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?

Despite having no output schema, the description explains all return values; it fully covers the complex conditional schema (context enum + room_id requirement), the write-confirmation policy, size limits, session expiry, and the post-upload polling lifecycle. Everything needed to correctly select and invoke this tool is present.

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?

Although schema coverage is 100% (baseline 3), the description adds substantial meaning beyond the schema: it explains each context enum value (messages = room attachments requiring room_id, proposals = job-application attachments, etc.), specifies that room_id is required only for messages and sourced from get_messages list_rooms, clarifies reason is optional, and documents the return fields task_id, fallback_url, and expires_at.

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 verb and resource: 'Requests a secure file upload from the user. Creates a short-lived upload session and returns task_id plus fallback_url.' It clearly differentiates from siblings like confirm_attachment_upload, get_upload_status, and store_uploaded_files by centering on session creation rather than confirmation, status, or storage.

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?

Extensive when-to-use guidance: it distinguishes the inline UI (7 MB) from the fallback_url (100 MB/file, 300 MB total) and says to use the fallback for larger files; it dictates when to ask the user for context rather than guessing; it names the follow-up flow via get_upload_status; and it gives the 30-minute expiry restart rule. It even includes an anti-pattern warning: never ask for base64 text or local file paths.

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

upwork__store_uploaded_filesAInspect

App-only tool that persists files uploaded through the inline MCP App UI. The model does not call this tool.

ParametersJSON Schema
NameRequiredDescriptionDefault
filesYes
org_uidYesUpwork org_uid for the active account
task_idYesUpload session task_id from start_attachment_upload

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already carry the safety profile (readOnlyHint=false, idempotentHint=false, destructiveHint=false), and the description is consistent with them: 'persists' describes a non-read-only, side-effecting write. It adds beyond-annotation context by disclosing the app-only invocation scope and that the model is not an actor, which is the principal behavioral fact an agent needs. It does not elaborate on re-call side effects, but idempotentHint=false already signals that.

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?

Two sentences with zero waste, front-loading the most decision-relevant fact ('App-only') and delivering the prohibition ('The model does not call this tool') immediately. Every word 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?

For a tool the agent must never invoke, the description carries both facts that matter — what it is and that the model must not call it — while the schema covers task_id sourcing from start_attachment_upload. It does not map the upload lifecycle (start → store → confirm) to its siblings, but that is largely unnecessary given the explicit no-call directive. A small deduction for not naming the lifecycle siblings, which would help an agent reason about the upload flow.

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 67%: task_id and org_uid are documented, while files lacks a property-level description. The description adds only indirect parameter context by tying the files to the inline UI session, and does not compensate for the undocumented files payload. This is a middle score — the schema does most of the parameter work, and the description neither repeats it nor fills the 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 ('persists') with a precise resource ('files uploaded through the inline MCP App UI') and a scope restriction ('App-only'). This clearly differentiates it from siblings like confirm_attachment_upload or get_upload_status, which manage upload state rather than storing file payloads.

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?

Provides explicit when-not guidance: 'The model does not call this tool.' It also identifies the invocation context — files uploaded through the inline MCP App UI — which tells the agent this is an app-internal persistence step it must never select. This is the strongest possible routing guidance for a tool the model is prohibited from calling.

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

upwork__update_accountUpdate AccountAInspect

Update your own company account: company name, description, and business location. Call get_account action=get_company first and pass only the fields you want to change. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval. Call get_tool_help(tool_name="update_account") for the actions, parameters, and how to use this tool.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters — call get_tool_help(tool_name="update_account") for the full field list.
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.4/5.0
Behavior5/5

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

It prominently discloses that this is a WRITE OPERATION requiring explicit user confirmation, and that it returns a draft for review rather than executing directly, with confirm_draft as the execution step. These behavioral traits go beyond the annotations, which only mark readOnlyHint=false, destructiveHint=false, and idempotentHint=false.

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

Conciseness3/5

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

The warning 'WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION' appears verbatim twice, adding unnecessary redundancy. The core information is front-loaded and readable, but the duplication prevents a higher score.

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 full workflow: precondition (get_account), parameter guidance (only changed fields), the draft return, and the subsequent confirm_draft step. Although the exact params object structure is deferred to get_tool_help, that pointer is explicit and acceptable given the availability of the help tool.

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 100%, so the baseline is 3. The description adds meaning by naming the updatable fields ('company name, description, and business location') and instructing to pass only the fields to change, which complements the opaque params object in the schema. It also points to get_tool_help for the full field list, further aiding parameter understanding.

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 'Update your own company account: company name, description, and business location,' using a specific verb, resource, and scope of changes. This clearly distinguishes it from sibling tools like update_contract and update_draft, which target other resources.

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 gives clear operational context: call get_account action=get_company first, pass only the fields to change, and follow up with confirm_draft after approval. It does not explicitly list exclusions or alternative tools for other updates, but the 'own company account' scope makes the intended usage unambiguous.

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

upwork__update_contractUpdate ContractAInspect

Update contract conditions. pause and restart run through MCP (draft -> confirm_draft). Changing the weekly hours limit is completed by you on Upwork and returns a link, not a direct change.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval.

Actions:

  • pause: Prepare a contract pause draft. Params: contract_id (string, required), message (string).

  • restart: Prepare a draft to restart a paused contract. Params: contract_id (string, required), message (string).

  • update_hourly_limit: Get the Upwork link to change a contract's weekly hours limit. Changing the limit notifies the freelancer and must be done by you on Upwork — this returns a finalize_url, it does NOT change the limit. Params: contract_id (string, required).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A5/5.0
Behavior5/5

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

The description goes well beyond the annotations by disclosing that this is a write operation requiring explicit user confirmation, that it returns a draft rather than executing immediately, and that update_hourly_limit returns a finalize_url without changing the limit. It also notes the freelancer notification.

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 and front-loaded: a one-line summary, a critical write-operation warning, and a bulleted action list with per-action parameters. Every sentence contributes decision-relevant information without unnecessary 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?

Given there is no output schema, the description adequately covers return behavior (draft or finalize_url), the external Upwork step, required parameters per action, and the confirm_draft execution path. An agent has enough context to invoke the tool 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?

The input schema provides generic params object descriptions, but the description adds essential action-specific parameter semantics: pause and restart need contract_id and message, while update_hourly_limit needs only contract_id. This directly helps the agent construct correct invocations.

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 with a specific verb and resource ('Update contract conditions') and then enumerates three concrete actions: pause, restart, and update_hourly_limit. This makes it easy to distinguish from related tools like confirm_draft or update_draft.

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?

It explicitly explains when to use the tool: pause and restart produce drafts requiring confirm_draft, while update_hourly_limit is not a direct change and requires the user to complete it on Upwork. This gives actionable routing and execution guidance.

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

upwork__update_draftUpdate DraftAInspect

Change the content of a pending server-stored draft without executing it. Send only the fields being changed; they are merged over the stored params. Returns a fresh preview AND A NEW draft_id that requires new user approval before confirm_draft — the previous draft_id is invalidated, so an edit can never be confirmed under the approval the user gave for the previous content.

WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Each write requires separate confirmation even if the user said "approve all".

Actions:

  • update: Change fields on a pending draft. Params: type (required), id (required — the draft_id), content (required object — only the fields being changed, merged over the stored params), mode (optional — 'merge' default, or 'replace' to swap the whole payload), remove_fields (optional array of field paths to delete). The response preview must be shown to the user and explicitly re-approved before confirmation, and confirm_draft must use the NEW draft_id returned here — the id passed in is invalidated by the edit (previous_draft_id in the response names it).

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesThe operation to perform
paramsNoAction-specific parameters (see allOf branches per action when present)
org_uidYesYour Upwork org_uid from list_accounts

TDQS

A4.6/5.0
Behavior5/5

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

Goes well beyond the annotations by disclosing write semantics, mandatory user confirmation, per-write confirmation even after 'approve all', draft_id invalidation, merge-vs-replace behavior, and the fact that nulls in content are ignored. This gives the agent critical operational knowledge that annotations alone do not provide.

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 front-loaded with the essential purpose and the write-confirmation warning, then structured as an executable action list. There is some redundancy around re-approval and new draft_id, but the length is justified by the tool's nuanced invalidation and confirmation flow.

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?

The description covers the full lifecycle relevant to this tool: what changes, how merging works, how to remove fields, what the response contains, why the old draft_id is invalid, and how to proceed with confirm_draft. Even without an output schema, the agent has enough to call the tool correctly and handle the result.

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 100%, so the baseline is 3, but the description adds meaningful semantics: id is the draft_id and is invalidated by the edit, content is a partial merge, mode can replace the whole payload, and remove_fields is the only way to delete fields. This is a useful supplement to the schema's already-detailed parameter 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?

States a specific action: 'Change the content of a pending server-stored draft without executing it.' This clearly identifies the verb, resource, and scope, and distinguishes it from sibling tools like confirm_draft and get_draft by emphasizing the edit step and explicitly ruling out execution.

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 clear context for when to use the tool: editing a pending draft before confirmation. It also explains the relationship to confirm_draft and warns that edits invalidate prior approval, which guides sequencing. It does not explicitly enumerate alternatives such as get_draft, but the main workflow implication is strong enough.

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. Dates show when Glama detected each change.

  1. 33 tool updates
    • First observedupwork__confirm_attachment_upload
    • First observedupwork__confirm_draft
    • First observedupwork__end_contract
    • First observedupwork__find_freelancers
    • First observedupwork__find_jobs
    • First observedupwork__get_account
    • First observedupwork__get_client_dashboard
    • First observedupwork__get_client_financials
    • First observedupwork__get_draft
    • First observedupwork__get_job_posting
    • First observedupwork__get_messages
    • First observedupwork__get_rate_insights
    • First observedupwork__get_tool_help
    • First observedupwork__get_upload_status
    • First observedupwork__invite_freelancer
    • First observedupwork__list_accounts
    • First observedupwork__list_client_invitations
    • First observedupwork__list_client_proposals
    • First observedupwork__list_contracts
    • First observedupwork__list_offers
    • First observedupwork__manage_client_proposals
    • First observedupwork__manage_milestones
    • First observedupwork__manage_offers
    • First observedupwork__manage_talent_lists
    • First observedupwork__post_job
    • First observedupwork__send_message
    • First observedupwork__set_tool_mode
    • First observedupwork__set_tool_permission
    • First observedupwork__start_attachment_upload
    • First observedupwork__store_uploaded_files
    • First observedupwork__update_account
    • First observedupwork__update_contract
    • First observedupwork__update_draft

Frequently Asked Questions

Discussions

No comments yet. Be the first to start the discussion!

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables detection and analysis of pre-public product launches through web search, content extraction, AI-powered scoring, and automated alerting. Provides comprehensive tools for surfacing stealth startup signals before they trend publicly.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Browse IndustryLens's published competitive-intelligence reports and head-to-head competitor comparisons from any AI agent — real, source-backed data.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI chat clients to perform market research and competitive intelligence by gathering company overviews, competitor lists, product portfolios, pricing snapshots, and recent news via live Tavily search.
    MIT
Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A3.9/5.0
Disambiguation3/5

Most tool names are distinct, but several surfaces overlap: find_jobs and get_job_posting both provide marketplace job search/get, and list_offers' list and list_mine are duplicates. The verbose descriptions help, but an agent could still select the wrong tool, especially when actions are nested inside tools.

Naming Consistency4/5

All tools share the upwork__ prefix and a snake_case verb_noun pattern, which is easy to scan. There are minor inconsistencies in verb choice (get_account vs list_accounts, get_messages vs send_message) and a few vague names, but no chaotic mixing of conventions.

Tool Count2/5

33 tools is over the 25+ threshold and includes redundancies like duplicate marketplace job search surfaces and list/list_mine in list_offers, plus several meta/config tools. The broad Upwork domain explains some of the count, but the surface is heavier and more duplicated than it needs to be.

Completeness3/5

Client-side workflows are well covered: job posting, proposals, offers, contracts, milestones, messaging, and financials. However, core freelancer flows are incomplete—there is no tool for submitting a proposal or accepting an offer—and descriptions reference missing tools such as list_freelancer_proposals and respond_to_offer, creating notable dead ends.

Resources