Skip to main content
Glama

Upwork MCP Server

List Contracts

upwork__list_contracts
Read-only

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).

Input Schema

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

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. First observed

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.

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