Upwork MCP Server
Allows to search jobs, manage proposals, track contracts, and monitor earnings on the Upwork freelance marketplace.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Upwork MCP Serversearch for React developer jobs under $1000"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Upwork MCP Server
A Model Context Protocol (MCP) server for interacting with the Upwork freelance marketplace. Search jobs, manage proposals, track contracts, and monitor earnings - all through AI assistants like Claude.
Features
Job Search & Discovery
Search Jobs: Find freelance opportunities with filters for skills, budget, category, experience level, and more
Get Job Details: View complete job information including client history and requirements
Save Jobs: Bookmark jobs for later review
Get Recommendations: Personalized job suggestions based on your profile
Proposal Management
Submit Proposals: Apply to jobs with cover letters and custom bids
Track Proposals: Monitor proposal status (pending, accepted, declined)
Update Proposals: Modify bids and cover letters before client response
Withdraw Proposals: Cancel applications when needed
View Statistics: Analyze your proposal success rates
Contract Management
List Contracts: View all your active, paused, and completed contracts
Contract Details: See terms, milestones, and feedback
Work Diary: Track time logged on hourly contracts
Milestones: Manage fixed-price project milestones
Request Payment: Submit work and request payment
End Contracts: Close contracts with feedback
Profile & Earnings
View Profile: See your complete freelancer profile
Update Profile: Modify title, skills, rate, and availability
Earnings Reports: Detailed income breakdown by period and contract
Transaction History: View all financial transactions
Connects Balance: Monitor your proposal credits
Job Success Score: Track your JSS and factors
Messaging
List Conversations: View all message rooms with clients
Read Messages: Access full conversation history
Send Messages: Communicate with clients
Related MCP server: upwork-mcp
Installation
# Clone or download the server
cd upwork-mcp-server
# Install dependencies
npm install
# Build the server
npm run buildConfiguration
Getting Your Access Token
Go to Upwork API Center
Create a new API application or select an existing one
Request OAuth 2.0 credentials
Generate an access token with appropriate scopes
Environment Variables
# Required
UPWORK_ACCESS_TOKEN=your_oauth2_access_token
# Optional (for HTTP mode)
PORT=3000
TRANSPORT=http # or 'stdio' (default)Usage
With Claude Desktop
Add to your Claude Desktop configuration (~/.config/claude/claude_desktop_config.json on macOS/Linux or %APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"upwork": {
"command": "node",
"args": ["/path/to/upwork-mcp-server/dist/index.js"],
"env": {
"UPWORK_ACCESS_TOKEN": "your_token_here"
}
}
}
}Command Line
# Run with stdio (default)
UPWORK_ACCESS_TOKEN=xxx npm start
# Run as HTTP server
UPWORK_ACCESS_TOKEN=xxx npm start -- --http
# Development mode with auto-reload
UPWORK_ACCESS_TOKEN=xxx npm run devHTTP API
When running in HTTP mode, the server exposes:
POST /mcp- MCP protocol endpointGET /health- Health check
Available Tools
Jobs
Tool | Description |
| Search jobs with filters |
| Get detailed job information |
| List your saved jobs |
| Save/unsave a job |
| Get personalized recommendations |
Proposals
Tool | Description |
| List your proposals |
| Get proposal details |
| Submit a new proposal |
| Update an existing proposal |
| Withdraw a proposal |
| Get proposal statistics |
Contracts
Tool | Description |
| List your contracts |
| Get contract details |
| Get work diary entries |
| List contract milestones |
| Submit milestone work |
| Request payment |
| End a contract |
Profile & Earnings
Tool | Description |
| Get freelancer profile |
| Update your profile |
| Get earnings report |
| Get transaction history |
| Get Connects balance |
| Get your JSS |
Messages
Tool | Description |
| List message rooms/conversations |
| Send a message |
Examples
Search for React Jobs
Use upwork_search_jobs with:
- query: "react developer"
- skills: ["react", "javascript", "typescript"]
- job_type: "hourly"
- experience_level: "intermediate"Submit a Proposal
Use upwork_submit_proposal with:
- job_id: "~01abc123..."
- cover_letter: "Your personalized cover letter..."
- bid_amount: 50
- bid_type: "hourly"Check Earnings
Use upwork_get_earnings with:
- start_date: "2024-01-01"
- end_date: "2024-12-31"API Scopes
The server requires these Upwork API scopes:
job:read- Search and view jobsproposal:read,proposal:write- Manage proposalscontract:read,contract:write- Manage contractsprofile:read,profile:write- Access and update profileearning:read- View earningsmessage:read,message:write- Access messages
Development
# Install dependencies
npm install
# Run in development mode
npm run dev
# Build
npm run build
# Clean build artifacts
npm run cleanLicense
MIT
Resources
Available Tools
26 toolsupwork_end_contractEnd ContractADestructive
End an active contract.
Close a contract and optionally leave feedback for the client.
Args:
contract_id (string, required): The contract ID to end
reason (string, required): Reason - 'project_completed', 'project_cancelled', 'no_longer_needed', 'other'
feedback_rating (number, optional): Rating for client (1-5)
feedback_comment (string, optional): Feedback comment
would_recommend (boolean, optional): Would you recommend this client?
Returns: Confirmation of contract closure.
Important: This action cannot be undone. Make sure all work is complete and payments are settled.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | Reason for ending the contract | |
| contract_id | Yes | The unique identifier of the contract to end | |
| feedback_rating | No | Rating for the client (1-5 stars) | |
| would_recommend | No | Whether you would recommend this client to others | |
| feedback_comment | No | Feedback comment for the client |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true, and the description adds valuable context: 'This action cannot be undone' and the requirement to ensure work and payments are settled. This goes beyond the generic annotation and makes the irreversible nature concrete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded, but the entire 'Args' section duplicates the input schema almost verbatim. The Returns and Important lines are useful, yet the redundancy keeps it from being as tight as it could be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive 5-parameter tool with no output schema, this description covers required args, the reason enum, return expectation, and irreversibility warning. It could provide a more precise return shape, but the confirmation is sufficient 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.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents all parameters. The description repeats the parameter list and reason enum but adds no meaning beyond what the schema provides, such as rating bounds or comment max length already being defined.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'End an active contract,' a specific verb and resource, then clarifies 'Close a contract and optionally leave feedback.' This clearly distinguishes it from sibling read/list tools like upwork_get_contract and upwork_list_contracts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it through 'active contract' and the warning 'Make sure all work is complete and payments are settled,' but it never explicitly names alternatives or says when not to use this tool. Guidance is present but left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_get_connectsGet Connects BalanceARead-onlyIdempotent
Get your Connects balance.
View your current Connects balance and usage history.
Args:
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Current Connects balance and recent usage.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds that it returns 'recent usage' in addition to the balance, which is useful but not a rich behavioral disclosure beyond what annotations already provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded with the core purpose. 'Get your Connects balance' is slightly redundant with the title, but the additional usage-history detail, args, and returns sections are all concise and useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with zero required parameters and no output schema, the description is complete enough: it states what the tool returns (current balance and recent usage) and the only optional parameter. Annotations cover safety, and no further context is needed for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents response_format with its enum and default. The description only repeats the default value and adds no meaning beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get') and resource ('Connects balance'), and adds that it also shows usage history. This clearly distinguishes it from sibling tools like get_earnings or get_transactions because 'Connects' is a distinct Upwork resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes clear this is for viewing the current Connects balance and usage history, so an agent can infer when to call it. It does not explicitly name alternatives or exclusions, but the context is unambiguous given the tool name and sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_get_contractGet Contract DetailsARead-onlyIdempotent
Get detailed information about a specific contract.
Retrieve complete contract details including terms, milestones, and feedback.
Args:
contract_id (string, required): The contract ID
include_milestones (boolean): Include milestone details (default: true)
include_feedback (boolean): Include feedback details (default: true)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Complete contract details including payment terms, milestones, and client feedback.
| Name | Required | Description | Default |
|---|---|---|---|
| contract_id | Yes | The unique identifier of the contract to retrieve | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
| include_feedback | No | Whether to include feedback details in the response | |
| include_milestones | No | Whether to include milestone details in the response |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds useful behavioral context by specifying that milestones and feedback are included by default and that response_format controls output shape. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized with an opening sentence, a summary sentence, an Args block, and a Returns block. Minor redundancy exists between 'Get detailed information' and 'Retrieve complete contract details', but it is compact and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only retrieval tool with no output schema, the description adequately explains what is returned (payment terms, milestones, feedback) and how to control output via parameters. All call-relevant information is present, and annotations cover the safety profile.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters are already well documented in the schema. The description repeats the parameters and defaults but adds little beyond what the structured schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Get') and resource ('detailed information about a specific contract'), clearly distinguishing it from list-style siblings like upwork_list_contracts. The title and description are consistent and precise.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use when you have a specific contract_id and need full details, but it does not explicitly mention alternatives such as upwork_list_contracts for discovering contracts or how to obtain a valid contract ID. No when-not-to-use guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_get_earningsGet Earnings ReportARead-onlyIdempotent
Get your earnings report for a time period.
View earnings summary, breakdown by contract, and pending/escrow amounts.
Args:
start_date (string, optional): Start date YYYY-MM-DD (default: 30 days ago)
end_date (string, optional): End date YYYY-MM-DD (default: today)
contract_id (string, optional): Filter by specific contract
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Earnings summary with totals, averages, and per-contract breakdown.
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | No | End date for earnings period (YYYY-MM-DD). Defaults to today. | |
| start_date | No | Start date for earnings period (YYYY-MM-DD). Defaults to 30 days ago. | |
| contract_id | No | Filter earnings by specific contract | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool readOnly, idempotent, and non-destructive; the description adds context by stating the report includes pending/escrow amounts and that it returns totals/averages plus per-contract breakdown. It does not contradict the annotations and provides return-format expectations that are not captured structurally.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a purpose sentence up front, a summary of contents, Args, and Returns. It is slightly redundant with the schema because the Args list repeats schema descriptions, but it remains compact and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the Returns section compensates by describing what the caller will receive (totals, averages, per-contract breakdown). The tool is simple (zero required params, no nested objects) and the description covers purpose, parameters, defaults, and output shape, so only minor details like timezone or currency are missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with all four parameters documented in the schema including defaults, patterns, and enums. The description's Args section largely duplicates this information and adds no significant new meaning, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific operation and resource: 'Get your earnings report for a time period' and enumerates what is included (summary, breakdown by contract, pending/escrow). It is clearly distinct from siblings in substance, but does not explicitly reference a sibling or differentiate itself, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The first line provides a clear use case: retrieving earnings for a time period, with options for contract breakdown and pending amounts. However, it gives no explicit guidance about when to prefer this tool over related siblings like upwork_get_transactions, upwork_get_connects, or upwork_list_contracts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_get_jobGet Job DetailsARead-onlyIdempotent
Get detailed information about a specific Upwork job.
Retrieves complete job details including full description, client history, and requirements.
Args:
job_id (string, required): The unique job identifier
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Complete job details including description, budget, skills, client info, and application requirements.
Examples:
Get job details: job_id="~01abc123def456"
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | The unique identifier of the job to retrieve | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal readOnlyHint, idempotentHint, and non-destructive behavior, so the safety profile is covered. The description adds the scope of the returned data, e.g., client history and requirements, but does not disclose any additional behavioral context such as whether client history may be partial or whether authentication is required.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is reasonably organized with Args, Returns, and Examples sections, but it is repetitive: 'Get detailed information', 'Retrieves complete job details', and 'Returns: Complete job details' all say nearly the same thing. Some redundancy could be trimmed without losing value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple read-only tool with only two parameters, and the description covers the required argument, the optional response format, the default format, and expected return contents. Since there is no output schema, the explicit Returns section is valuable and sufficiently covers what an agent needs to know.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented in the schema. The description repeats the parameter names and includes an example job_id, but adds little semantic meaning beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource, 'Get detailed information about a specific Upwork job', and enumerates the kind of content returned, such as full description, client history, and requirements. This clearly distinguishes it from sibling tools like search_jobs, save_job, or get_contract.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'a specific Upwork job' and the required job_id parameter imply this tool is for fetching details when the caller already knows the job identifier. However, it does not explicitly state when to use this tool instead of alternatives like upwork_search_jobs or upwork_get_job_recommendations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_get_job_recommendationsGet Job RecommendationsARead-onlyIdempotent
Get personalized job recommendations based on your profile and history.
Returns jobs that Upwork's algorithm thinks are a good match for your skills and experience.
Args:
limit (number): Max recommendations (default: 20, max: 100)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: List of recommended jobs tailored to your profile.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of recommendations to return (default: 20) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already communicate that this is read-only, idempotent, and non-destructive. The description adds that results depend on profile/history and algorithmic matching, but it does not disclose additional behavioral traits such as possible variation over time, rate limits, or response-shape details beyond the basic 'list of recommended jobs.'
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear opening statement, elaboration, and compact Args/Returns sections. Some redundancy exists between the first two sentences, and the Args section restates schema information, but overall the description is appropriately sized and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with two optional parameters, full schema coverage, and safety annotations, the description is mostly complete. It explains the tool's purpose, output type, and parameter defaults, though it does not enumerate the fields included in each recommended job or explicitly distinguish its return shape from a search result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the description essentially repeats the schema's parameter details (defaults, max, enum values). It adds no meaning beyond what the input schema already provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Get personalized job recommendations based on your profile and history.' It also clarifies that results are algorithmically matched to the user's skills and experience, which differentiates it from sibling tools like upwork_search_jobs or upwork_get_job.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for personalized, algorithm-driven recommendations rather than active searching or fetching a specific job, but it never explicitly says when to prefer this tool over siblings like upwork_search_jobs. There are no stated exclusions or alternative routing cues.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_get_job_success_scoreGet Job Success ScoreBRead-onlyIdempotent
Get your Job Success Score (JSS) and related metrics.
View your JSS, factors affecting it, and tips for improvement.
Args:
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Current JSS, calculation factors, and historical trend.
| Name | Required | Description | Default |
|---|---|---|---|
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal a safe read-only, idempotent operation, so the description does not need to restate that. It adds some context about the returned content (current JSS, calculation factors, historical trend), but no further behavioral traits such as auth needs or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first two sentences are redundant—'Get your JSS' and 'View your JSS' cover the same ground—and the Args/Returns sections add length. The purpose is front-loaded, but the description would be tighter without the repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one optional parameter and no output schema, the description covers what the agent needs: the resource, optional format, and a summary of return contents. It is slightly vague about 'related metrics' and 'factors,' but not enough to prevent correct selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, response_format, is fully documented by the input schema including its enum values, default, and a clear description. The Args section merely repeats that information and adds no new semantic meaning, so the schema-coverage baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a clear verb-resource pair ('Get your Job Success Score') and specifies what is included: factors affecting it, tips for improvement, and historical trend. It does not explicitly differentiate from siblings, but the target resource is unique among the listed tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given for when to choose this tool over alternatives such as upwork_get_profile or upwork_get_contract. The description only states what the tool does, not the conditions or context in which it should be invoked.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_get_profileGet Freelancer ProfileARead-onlyIdempotent
Get your Upwork freelancer profile information.
Retrieve your profile details including title, skills, stats, and availability.
Args:
user_id (string, optional): User ID to fetch. Defaults to your profile.
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Complete profile with overview, skills, earnings stats, and availability.
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | No | User ID to fetch profile for. Defaults to the authenticated user. | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the read-only nature is covered. The description adds useful context beyond annotations by specifying that it returns a complete profile with overview, skills, earnings stats, and availability, and by noting the default-to-self behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a summary line, an Args section, and a Returns section. It is easy to scan and front-loads the core purpose. There is minor redundancy between the opening sentence and the Returns section, but overall it is appropriately sized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only getter with two optional parameters and no output schema, the description provides sufficient invocation details and return expectations. The only slight gap is ambiguity around whether user_id can fetch arbitrary users' profiles or only the authenticated user's, which could affect correct usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters and their defaults. The description largely restates this information, with only a slight clarification that user_id defaults to 'your profile' rather than just 'the authenticated user', matching the schema but not adding substantial new meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the operation as retrieving profile information, using the specific verb 'Get'/'Retrieve' with the resource 'freelancer profile'. It lists the key data areas (title, skills, stats, availability), which distinguishes it from sibling tools like upwork_get_contract or upwork_get_connects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool: whenever you need the freelancer profile details. It also clarifies that user_id is optional and defaults to the authenticated user. However, it gives no explicit guidance about when not to use it or which alternative tool to choose (e.g., update_profile for modifying).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_get_proposalGet Proposal DetailsARead-onlyIdempotent
Get detailed information about a specific proposal.
Retrieve the full proposal including cover letter, answers to screening questions, and current status.
Args:
proposal_id (string, required): The proposal ID
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Complete proposal details including cover letter, bid, and status.
| Name | Required | Description | Default |
|---|---|---|---|
| proposal_id | Yes | The unique identifier of the proposal to retrieve | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context about what the response includes (cover letter, bid, status, screening answers) and the response_format option. It does not disclose any extra caveats, but for a simple read operation the annotations carry much of the burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized with a one-line purpose, expanded details, Args, and Returns sections. It is appropriately sized for a two-parameter tool. There is minor redundancy between 'Get detailed information' and 'Retrieve the full proposal,' but no unnecessary fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only retrieval tool with two well-documented parameters and no output schema, the description provides enough context: the target resource, key return fields, and output format choice. It does not detail every possible response field or error behavior, but the lack of an output schema is partially mitigated by the Returns summary.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the argument descriptions in the schema fully document both proposal_id and response_format. The description largely repeats this information without adding significant new meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: 'Get detailed information about a specific proposal.' It also enumerates key contents (cover letter, screening answers, status), which clarifies what the tool returns. It does not explicitly distinguish itself from sibling tools like upwork_list_proposals or upwork_get_proposal_stats, so it misses the top score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for retrieving full details of one known proposal by ID, which is a clear use case. However, it offers no explicit guidance about when to choose this over alternatives such as upwork_get_proposal_stats or upwork_list_proposals, or what to do if only the proposal list is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_get_proposal_statsGet Proposal StatisticsARead-onlyIdempotent
Get statistics about your proposal activity.
View your proposal success rate, response times, and trends.
Args:
period_days (number): Days to include (default: 30, max: 365)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Statistics including total proposals, acceptance rate, and average response time.
| Name | Required | Description | Default |
|---|---|---|---|
| period_days | No | Number of days to include in statistics (default: 30, max: 365) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds no further behavioral context such as data freshness, live vs. cached statistics, or whether only active proposals are counted, but it 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is tightly written: a one-line summary, a clarifying metrics sentence, and concise Args/Returns blocks. Every sentence earns its place, and the structure is easy to scan and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only statistics tool with two documented optional parameters and no output schema, the description includes essential return elements (total proposals, acceptance rate, average response time) and parameter documentation. It could be slightly more complete by explaining what 'trends' means or whether stats cover only active proposals, but those are minor gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: both period_days and response_format already have descriptions, defaults, and constraints in the input schema. The Args section in the description merely paraphrases the schema and adds no new meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get statistics about your proposal activity,' then lists concrete metrics (success rate, response times, trends). This clearly distinguishes it from sibling tools like get_proposal or list_proposals, though it does not explicitly name those alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies its use case: when an agent needs aggregate proposal performance metrics, use this tool. It does not explicitly state when to use it instead of list_proposals, get_proposal, or submit_proposal, nor does it mention exclusions, so the guidance is largely left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_get_transactionsGet Transaction HistoryBRead-onlyIdempotent
Get your transaction history.
View all financial transactions including earnings, withdrawals, and fees.
Args:
start_date (string, optional): Start date YYYY-MM-DD
end_date (string, optional): End date YYYY-MM-DD
type (string, optional): Filter by type: 'earning', 'withdrawal', 'refund', 'bonus', 'fee'
limit (number): Max results (default: 20, max: 100)
offset (number): Pagination offset (default: 0)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: List of transactions with amounts, types, and dates.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Filter by transaction type | |
| limit | No | Maximum number of transactions to return (default: 20) | |
| offset | No | Number of results to skip for pagination | |
| end_date | No | End date for transactions (YYYY-MM-DD) | |
| start_date | No | Start date for transactions (YYYY-MM-DD) | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds value beyond this by specifying pagination behavior (limit default 20/max 100, offset default 0), the response_format default ('markdown'), and return contents ('List of transactions with amounts, types, and dates'), which is useful given no output schema exists. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first sentence and the structure (args, returns) is tidy. However, the Args block duplicates what the input schema already fully documents, adding length without new information; the Returns line, by contrast, earns its place since there is no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers core invocation details (filters, pagination, output format, return contents) and is supplemented by rich annotations, adequate for a read-only list tool. The notable gap is the missing relationship or contrast with upwork_get_earnings, which an agent needs to route correctly among 24 siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the input schema already documents all six parameters, their defaults, enums, and date patterns. The description's Args section merely restates the schema without adding new meaning (e.g., date inclusivity or how filters combine), earning the baseline score of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a clear action ('Get your transaction history') and enumerates the resource scope ('all financial transactions including earnings, withdrawals, and fees'), which sets it apart from most siblings. However, it does not differentiate itself from the closely named sibling upwork_get_earnings, leaving overlap ambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to choose this tool over alternatives. No exclusions or conditions are stated, and the sibling upwork_get_earnings appears to overlap semantically, so an agent has no basis to decide which one to invoke.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_get_work_diaryGet Work DiaryARead-onlyIdempotent
Get work diary entries for an hourly contract.
View time tracked, screenshots, and activity levels for hourly work.
Args:
contract_id (string, required): The contract ID
date (string, optional): Specific date in YYYY-MM-DD format
start_date (string, optional): Start of date range (YYYY-MM-DD)
end_date (string, optional): End of date range (YYYY-MM-DD)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: Work diary entries with time tracked, memos, and activity data.
Note: Only works for hourly contracts with time tracking enabled.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Specific date to retrieve (YYYY-MM-DD). Defaults to today. | |
| end_date | No | End date for range query (YYYY-MM-DD) | |
| start_date | No | Start date for range query (YYYY-MM-DD) | |
| contract_id | Yes | The unique identifier of the contract | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive behavior. The description adds useful behavioral context by listing what the entries contain (time tracked, memos, activity data) and the hourly-contract restriction. It does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The main purpose is front-loaded, followed by compact Args, Returns, and Note sections. The Args section partly duplicates the schema, but it is short and skimmable, so no sentence feels wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a five-parameter, no-output-schema tool, the description covers what is returned, the supported date formats, the output format option, and the key eligibility constraint. It is missing only an explicit rule for combining date with a range, which is a minor edge-case gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and the description mostly restates the schema's parameter docs (contract_id, date, start_date, end_date, response_format). It adds no meaning beyond the schema, so the baseline 3 applies. One minor ambiguity remains: behavior when both date and a start/end range are supplied is not clarified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get work diary entries for an hourly contract' and immediately clarifies the content ('time tracked, screenshots, and activity levels'). This clearly distinguishes it from sibling tools focused on contracts, proposals, jobs, or earnings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The note 'Only works for hourly contracts with time tracking enabled' provides an explicit boundary for when the tool applies. It does not name an alternative tool, but no sibling performs the same function, so this constraint is sufficient context for an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_list_contractsList ContractsARead-onlyIdempotent
List your contracts on Upwork.
View all your freelance contracts with clients.
Args:
status (string, optional): Filter by status: 'active', 'paused', 'ended', 'pending'
client_id (string, optional): Filter by specific client
limit (number): Max results (default: 20, max: 100)
offset (number): Pagination offset (default: 0)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: List of contracts with client info, earnings, and status.
Examples:
Active contracts only: status="active"
All contracts: (no filters)
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of contracts to return (default: 20) | |
| offset | No | Number of results to skip for pagination | |
| status | No | Filter by contract status: 'active', 'paused', 'ended', or 'pending' | |
| client_id | No | Filter by specific client ID | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds a useful return summary ('client info, earnings, and status') but does not disclose additional behavioral details such as pagination behavior or how 'all contracts' interacts with limit/offset. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with Args, Returns, and Examples, making it easy for an agent to scan. The opening two sentences are somewhat redundant ('List your contracts on Upwork' and 'View all your freelance contracts with clients'), but overall length is appropriate and front-loaded with purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description's Returns line provides necessary context about what the tool returns. All parameters are covered by the schema, and examples fill in common usage patterns. It could be more explicit about pagination or how to use returned contract IDs with get_contract, but an agent can invoke the tool correctly with the current information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents every parameter. The description's Args section largely duplicates the schema rather than adding new semantics. It reinforces defaults and enum choices but provides no meaning beyond what the schema already gives.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List') and resource ('your contracts on Upwork'), and the second sentence reinforces the purpose: 'View all your freelance contracts with clients.' It doesn't explicitly distinguish itself from sibling tools like upwork_get_contract, but the plural 'list' vs. singular 'get' is a clear enough separation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The examples ('Active contracts only: status="active"' and 'All contracts: (no filters)') provide concrete context for when to use the tool. It does not explicitly state when NOT to use it or name alternatives such as upwork_get_contract, but the filtering examples give the agent practical invocation guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_list_messagesList Message RoomsBRead-onlyIdempotent
List your message conversations on Upwork.
View your message rooms with clients and other freelancers.
Args:
room_id (string, optional): Get messages from a specific room
contract_id (string, optional): Filter by contract
unread_only (boolean): Only show rooms with unread messages (default: false)
limit (number): Max results (default: 20, max: 100)
offset (number): Pagination offset (default: 0)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: List of message rooms with participants and last message preview.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of messages/rooms to return (default: 20) | |
| offset | No | Number of results to skip for pagination | |
| room_id | No | Specific room ID to fetch messages from | |
| contract_id | No | Filter conversations by contract | |
| unread_only | No | Only show conversations with unread messages | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish that this is read-only, idempotent, and non-destructive. The description adds return-shape context (message rooms with participants and last message preview), but it also introduces ambiguity: room_id is described as 'Get messages from a specific room,' while the top-level return is described as a list of message rooms. This makes the exact behavior when room_id is provided unclear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is well-structured with an intro, Args section, and Returns section, and the core purpose is front-loaded. It is slightly redundant because the Args list repeats the schema, but it remains compact and easy for an agent to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With six optional parameters and no output schema, the description does provide a Returns line and documents all arguments. However, the relationship between room_id, message-level output, and room-level output is underspecified, and there is no mention of ordering or how response_format changes the output structure, which leaves meaningful gaps for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema describes all six parameters with defaults and enum values, so schema coverage is 100%. The description's Args list essentially mirrors the schema without adding constraints, relationships, or practical usage nuance, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a read-only list/view operation over Upwork message conversations and message rooms, naming the resource and even the return shape. It does not explicitly disambiguate from siblings like upwork_send_message, but the viewing intent is obvious from the wording.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this is the tool to use when you want to see your message rooms or conversations, but it never explicitly says when to use it versus alternatives such as upwork_send_message. There is no exclusion or 'when not to use' guidance, so usage is mostly inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_list_milestonesList MilestonesARead-onlyIdempotent
List milestones for a fixed-price contract.
View all milestones, their status, and amounts.
Args:
contract_id (string, required): The contract ID
status (string, optional): Filter by status: 'active', 'submitted', 'approved', 'paid', 'cancelled'
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: List of milestones with descriptions, amounts, and status.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | Filter by milestone status | |
| contract_id | Yes | The unique identifier of the contract | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, and non-destructive behavior; the description adds that this reads milestone statuses and amounts for a fixed-price contract and can return markdown or JSON. No behavioral surprises 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with the core purpose. The Args and Returns sections are somewhat redundant with the schema but are short and useful for quick scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only listing tool with strong annotations and full schema coverage, the description covers purpose, filter values, output format, and return content. It doesn't need extensive detail since there is no output schema and no destructive behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema fully documents contract_id, status, and response_format. The description repeats those details rather than adding new semantic meaning, which meets the baseline but doesn't elevate it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses explicit verb 'List' with specific resource 'milestones' scoped to 'a fixed-price contract', and clarifies the returned data (statuses and amounts). This distinguishes it from sibling tools like upwork_submit_milestone or upwork_get_contract.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description establishes when to use it: viewing milestones on a fixed-price contract. It doesn't explicitly exclude alternatives, but the scoping and read-only nature make the intended use clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_list_proposalsList ProposalsARead-onlyIdempotent
List your submitted proposals on Upwork.
View all your job applications and their current status.
Args:
status (string, optional): Filter by status: 'pending', 'accepted', 'declined', 'withdrawn', 'archived'
limit (number): Max results (default: 20, max: 100)
offset (number): Pagination offset (default: 0)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: List of proposals with job titles, bid amounts, and status.
Examples:
All pending proposals: status="pending"
Recent accepted proposals: status="accepted", limit=10
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of proposals to return (default: 20) | |
| offset | No | Number of results to skip for pagination | |
| status | No | Filter by proposal status: 'pending', 'accepted', 'declined', 'withdrawn', or 'archived' | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description reinforces this with 'List' and 'View', and additionally discloses the return content ('job titles, bid amounts, and status'). No hidden side effects or contradictions are present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with an opening summary, Args section, Returns section, and Examples. Every section is purposeful and no content is redundant or wasted. The most important information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list operation with all parameters covered by the schema and annotations disclosing the safety profile, the description is complete. It specifies the response fields, parameter behavior, and examples, so an agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all parameters. The description adds value by providing concrete examples (status='pending', status='accepted', limit=10) and summarizing defaults and limits in an agent-friendly way.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List your submitted proposals'), the resource ('proposals on Upwork'), and the purpose ('View all your job applications and their current status'). It is immediately distinguishable from sibling tools like upwork_get_proposal by its plural, list-oriented scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description makes clear when to use this tool: when the agent needs to view all submitted proposals or filter them by status. It does not explicitly mention alternatives such as upwork_get_proposal for a single proposal, but the context is strong enough that usage is not ambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_list_saved_jobsList Saved JobsARead-onlyIdempotent
List jobs you've saved/favorited on Upwork.
Retrieves your saved jobs list for easy access to opportunities you're interested in.
Args:
limit (number): Max results (default: 20, max: 100)
offset (number): Pagination offset (default: 0)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: List of your saved jobs with basic details.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of jobs to return (default: 20) | |
| offset | No | Number of results to skip for pagination | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context: it returns a paginated list, supports markdown/json output, and provides default limits. This is appropriate given the annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with the core purpose in the first sentence. The Args and Returns sections are clearly structured and easy to parse, though the Args list partially duplicates schema descriptions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with no required parameters and full schema coverage, the description is largely complete. The return value is described as a list with basic details; while the exact fields are not enumerated, this is a minor gap since no output schema exists and the tool is straightforward.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all three parameters. The description's Args section essentially repeats the schema information without adding meaningful new semantics, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and resource ('jobs you've saved/favorited on Upwork'), making the tool's purpose unmistakable. It clearly distinguishes itself from sibling tools like upwork_search_jobs by focusing on saved/favorited jobs rather than all jobs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies this tool is for retrieving previously saved jobs, which gives an agent clear context for when to choose it over search or single-job retrieval. It doesn't explicitly name alternatives or exclusions, but the saved-jobs scope is unambiguous and sufficient for this simple tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_request_paymentRequest PaymentA
Request payment for work completed.
For hourly contracts, request payment for tracked hours. For fixed-price, request milestone payment.
Args:
contract_id (string, required): The contract ID
milestone_id (string, optional): Milestone ID for fixed-price contracts
amount (number, optional): Amount for hourly contracts
message (string, optional): Message to client
Returns: Confirmation of payment request.
| Name | Required | Description | Default |
|---|---|---|---|
| amount | No | Amount to request for hourly contracts | |
| message | No | Optional message to the client | |
| contract_id | Yes | The unique identifier of the contract | |
| milestone_id | No | Specific milestone ID for fixed-price contracts |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description states it 'returns confirmation of payment request' and explains the two payment modes. Annotations are all false and offer little safety context; the description doesn't disclose idempotency, side effects such as notifying the client, or prerequisites. This leaves behavioral clarity incomplete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The main paragraph is front-loaded with purpose and use cases, and the Args list is tidy. The list repeats schema information but is compact and doesn't bloat the description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides the essential distinction between hourly and fixed-price payment requests and confirms a return value. Missing are caveats about repeated requests (idempotency is false), possible failure conditions, or the relationship to sibling tools like upwork_submit_milestone, leaving some uncertainty for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with descriptions for contract_id, milestone_id, amount, and message. The description's Args section largely restates these schema descriptions, adding no substantive new meaning beyond mapping them to contract types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Request payment for work completed.' It clearly differentiates between hourly and fixed-price contracts, making the tool's function distinct from siblings like upwork_submit_milestone or upwork_get_work_diary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly maps usage scenarios: hourly contracts use tracked hours, fixed-price contracts use milestone payment. It does not, however, name alternative tools or state when not to use them, so it falls just short of the highest bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_save_jobSave/Unsave JobAIdempotent
Save a job to your favorites or remove it from saved jobs.
Use this to bookmark jobs you want to apply to later.
Args:
job_id (string, required): The job ID to save/unsave
save (boolean): True to save, false to remove (default: true)
Returns: Confirmation of the save/unsave action.
| Name | Required | Description | Default |
|---|---|---|---|
| save | No | True to save the job, false to remove from saved jobs | |
| job_id | Yes | The unique identifier of the job to save/unsave |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey idempotentHint=true, destructiveHint=false, and readOnlyHint=false. The description adds the save/unsave toggle behavior and a confirmation return, which is mildly useful but not substantially beyond what the annotations and title already imply. 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, then uses compact Args/Returns sections. It is slightly redundant with the schema, but not bloated or confusing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter toggle tool with no output schema, the description is complete: it explains the action, required parameter, default behavior, and return value. An agent has enough context to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already documents both job_id and save, including the default. The Args block in the description mostly restates this information rather than adding new semantic meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair: 'Save a job to your favorites or remove it from saved jobs.' This clearly differentiates the tool from sibling read/search/proposal tools like upwork_get_job, upwork_search_jobs, and upwork_submit_proposal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides a clear use case: 'Use this to bookmark jobs you want to apply to later.' This tells the agent when the tool is appropriate, though it does not explicitly name alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_search_jobsSearch Upwork JobsARead-onlyIdempotent
Search for freelance jobs on Upwork with various filters.
This tool searches the Upwork job marketplace and returns matching job listings. Use it to find opportunities based on skills, budget, category, and more.
Args:
query (string, optional): Search keywords for job titles/descriptions
category (string, optional): Job category filter
skills (string[], optional): Filter by required skills
budget_min (number, optional): Minimum budget in USD
budget_max (number, optional): Maximum budget in USD
job_type ('hourly' | 'fixed', optional): Filter by job type
experience_level ('entry' | 'intermediate' | 'expert', optional): Filter by level
client_country (string, optional): Filter by client's country
posted_within_hours (number, optional): Jobs posted within N hours
payment_verified (boolean, optional): Only verified payment methods
limit (number): Max results (default: 20, max: 100)
offset (number): Pagination offset (default: 0)
response_format ('markdown' | 'json'): Output format (default: 'markdown')
Returns: List of matching jobs with details including title, budget, skills, client info, and posting date.
Examples:
Find React jobs: query="react developer", skills=["react", "javascript"]
High-budget fixed jobs: job_type="fixed", budget_min=1000
Recent expert jobs: experience_level="expert", posted_within_hours=24
Error Handling:
Returns "No jobs found" if search returns empty
Returns error message if authentication fails
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of jobs to return (default: 20, max: 100) | |
| query | No | Search keywords to match against job titles and descriptions | |
| offset | No | Number of results to skip for pagination | |
| skills | No | Filter by required skills (e.g., ['python', 'react', 'nodejs']) | |
| category | No | Job category filter. Common categories: web-development, mobile-development, software-development, data-science-analytics, design-creative, etc. | |
| job_type | No | Filter by job type: 'hourly' or 'fixed' | |
| budget_max | No | Maximum budget in USD | |
| budget_min | No | Minimum budget in USD | |
| client_country | No | Filter by client's country (e.g., 'United States', 'United Kingdom') | |
| response_format | No | Output format: 'markdown' for human-readable or 'json' for machine-readable | markdown |
| experience_level | No | Filter by experience level: 'entry', 'intermediate', or 'expert' | |
| payment_verified | No | Filter to show only jobs from clients with verified payment methods | |
| posted_within_hours | No | Filter jobs posted within the last N hours (max 720 = 30 days) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and non-destructive behavior. The description adds useful behavior beyond annotations by covering empty results ('No jobs found') and authentication failure handling. It does not mention rate limits or result ordering, but the annotations lower the burden and the added error context is valuable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a front-loaded summary, Args section, Returns, Examples, and Error Handling. However, the Args section largely duplicates the input schema's parameter descriptions, making the overall description longer than necessary. The examples and error handling earn their place, but the redundancy costs conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 13-parameter tool with no output schema, the description covers all parameters, return values, examples, and error cases. It does not fully clarify how empty results differ between markdown and json response formats, and it omits sorting behavior, but overall it is sufficiently complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value beyond the schema through realistic examples like query="react developer" with skills, high-budget fixed jobs, and recent expert jobs, which help an agent construct meaningful searches.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and resource: 'Search for freelance jobs on Upwork' and 'searches the Upwork job marketplace and returns matching job listings.' This distinguishes it from get/contract/profile tools, but it does not explicitly differentiate it from related job-listing tools like upwork_get_job_recommendations or upwork_list_saved_jobs.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says 'Use it to find opportunities based on skills, budget, category, and more,' which provides clear context for when to call it. It does not, however, state when not to use it or name alternative tools for specific scenarios.
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
Send a message in a conversation room.
Send a message to a client or in a job/contract conversation.
Args:
room_id (string, required): The conversation room ID
content (string, required): Message content (1-10000 chars)
attachments (string[], optional): File URLs to attach (max 5)
Returns: Confirmation of message sent.
Important: Keep messages professional and relevant to the work.
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | The message content to send | |
| room_id | Yes | The conversation room ID to send the message to | |
| attachments | No | URLs or file paths to attach to the message |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate this is a non-read-only, non-idempotent action, and the description aligns by saying 'send a message.' It adds minor behavioral context such as the professional tone requirement and return confirmation, but doesn't disclose side effects like duplicate messages if called repeatedly, which idempotentHint=false implies could occur.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a summary sentence, Args, Returns, and Important sections. The second sentence ('Send a message to a client...') is somewhat redundant with the first, but the rest is efficient and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (3 parameters, no nested objects, no output schema), the description adequately covers the essentials: what it does, parameters, return value, and a usage caution. It could mention that room_id can be obtained from list_messages, but that's a minor convenience, not a gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully describes all three parameters with descriptions and constraints (room_id, content, attachments). The description's Args section largely repeats this information, adding no meaning beyond the schema. Baseline of 3 is appropriate because schema coverage is 100%.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states exactly what the tool does: send a message in a conversation room, with explicit context of messaging a client or in a job/contract conversation. It clearly differentiates from the read-only sibling tools like list_messages, and no other sibling handles sending messages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context on when to use this tool: when there is a conversation room and the agent needs to send a message to a client or within a job/contract conversation. It doesn't explicitly name exclusions or alternatives, but the sibling set makes the purpose obvious enough that no exclusions are necessary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_submit_milestoneSubmit Milestone WorkA
Submit work for a milestone on a fixed-price contract.
Mark a milestone as complete and ready for client review.
Args:
contract_id (string, required): The contract ID
milestone_id (string, required): The milestone ID to submit
message (string, optional): Message to the client about the submission
Returns: Confirmation of submission.
Important: Only submit when work is complete. The client will review and approve or request changes.
| Name | Required | Description | Default |
|---|---|---|---|
| message | No | Optional message to the client about the submission | |
| contract_id | Yes | The unique identifier of the contract | |
| milestone_id | Yes | The unique identifier of the milestone to submit |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey the safety profile (write operation, not destructive, not idempotent), and the description is consistent with them. It adds workflow context beyond annotations by disclosing the state transition (milestone becomes complete) and the downstream client review/approval process.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded with purpose, followed by a terse Args/Returns block and a valuable usage warning. The Args section is somewhat redundant with the 100%-covered schema, but the overall structure wastes little space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple 3-string-param mutation with full schema coverage and annotations, the description covers purpose, usage condition, params, and return. Minor gaps: the return value is vaguely specified as 'Confirmation of submission' and there is no cross-reference to sibling listing tools for obtaining contract_id/milestone_id.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents all three parameters; baseline 3 applies. The description's Args block restates the same information without adding format details, ID-source hints, or relationships to sibling tools like upwork_list_milestones.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource: 'Submit work for a milestone on a fixed-price contract' and adds the resulting state change 'Mark a milestone as complete and ready for client review.' This clearly differentiates it from siblings like upwork_request_payment or upwork_end_contract without needing to inspect schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Important: Only submit when work is complete. The client will review and approve or request changes' note gives a clear condition for when to invoke the tool. However, it does not explicitly name alternatives or when-not-to-use conditions relative to adjacent workflow tools like upwork_list_milestones or upwork_request_payment.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_submit_proposalSubmit ProposalA
Submit a proposal (application) for a job on Upwork.
Apply to a job with your cover letter and bid. This will use Connects from your account.
Args:
job_id (string, required): The job ID to apply to
cover_letter (string, required): Your cover letter (50-5000 characters)
bid_amount (number, required): Your bid in USD
bid_type ('hourly' | 'fixed', required): Type of bid
estimated_duration (string, optional): Estimated time to complete
answers (array, optional): Answers to screening questions
attachments (array, optional): Files to attach
Returns: Confirmation with proposal ID and Connects used.
Examples:
Submit hourly proposal: job_id="~01abc", cover_letter="...", bid_amount=50, bid_type="hourly"
Submit fixed proposal: job_id="~01abc", cover_letter="...", bid_amount=500, bid_type="fixed"
Important:
Submitting proposals costs Connects
Review job requirements carefully before submitting
Customize your cover letter for each job
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | The unique identifier of the job to apply to | |
| answers | No | Answers to screening questions, if the job has any | |
| bid_type | Yes | Type of bid: 'hourly' for hourly rate or 'fixed' for fixed price | |
| bid_amount | Yes | Your bid amount in USD | |
| attachments | No | URLs or file paths to attach to the proposal | |
| cover_letter | Yes | Your cover letter explaining why you're a good fit for the job | |
| estimated_duration | No | Estimated time to complete the project (e.g., 'Less than 1 week', '1-2 months') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations are minimal and all false, so the description carries most of the behavioral burden. It adds important side-effect information: 'This will use Connects from your account' and 'Submitting proposals costs Connects.' It also documents the return value ('Confirmation with proposal ID and Connects used') despite no output schema. This goes beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with labeled Args, Returns, Examples, and Important sections, and the core purpose is front-loaded. It is slightly redundant (Connects costs are mentioned twice, and Args duplicates schema details), but the organization makes it easy for an agent to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description appropriately documents the return value. It covers required parameters, optional parameters, examples for hourly and fixed bids, the Connects-cost side effect, and usage cautions. For a 7-parameter mutation tool with 100% schema coverage, this is a complete and actionable definition.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents every parameter. The description's Args section mostly mirrors the schema (e.g., 'cover_letter (string, required): Your cover letter (50-5000 characters)' matches minLength/maxLength; 'bid in USD' matches the schema). It adds 'required' labels and examples, but little novel parameter meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Submit a proposal (application) for a job on Upwork' and says 'Apply to a job with your cover letter and bid.' This clearly identifies both the action and the resource being acted on. It also distinguishes itself from sibling tools like upwork_update_proposal and upwork_withdraw_proposal by using the verb 'submit' for new applications.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: this is used when applying to an Upwork job with a cover letter and bid. It also advises reviewing job requirements and customizing the cover letter, which implies pre-invocation care. However, it does not explicitly contrast this tool with alternatives like update_proposal or withdraw_proposal, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_update_profileUpdate ProfileAIdempotent
Update your Upwork freelancer profile.
Modify your professional title, overview, hourly rate, skills, or availability.
Args:
title (string, optional): Professional title (10-100 chars)
overview (string, optional): Professional bio (100-5000 chars)
hourly_rate (number, optional): Desired hourly rate in USD
skills (string[], optional): List of skills (1-15)
availability (string, optional): 'available', 'not_available', 'open_to_offers'
hours_per_week (number, optional): Available hours per week (0-80)
Returns: Confirmation of profile update.
Tips:
Keep your title specific and keyword-rich
Update your availability regularly
Add skills that match job requirements
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | Professional title (e.g., 'Senior Full Stack Developer') | |
| skills | No | List of skills to display on profile | |
| overview | No | Professional overview/bio | |
| hourly_rate | No | Desired hourly rate in USD | |
| availability | No | Current availability status | |
| hours_per_week | No | Available hours per week |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already signal a non-read-only, non-destructive, idempotent mutation; the description adds that it returns a confirmation and constrains allowed values. It does not explain whether omitted optional parameters are preserved or overwritten, which is a meaningful behavioral gap for a profile-update tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is clearly organized with intro, Args, Returns, and Tips, and it front-loads the purpose. It is a bit longer than strictly necessary because the Args section duplicates schema constraints, but the structure keeps it scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter mutation tool with no output schema, the description provides the essential inputs, return confirmation, and some usage tips. It misses the semantics of partial updates and prerequisites, so an agent may still be uncertain about the tool's full behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline applies; the description repeats the constraints (10-100 chars, 1-15 skills, 0-80 hours) but adds no conceptual meaning beyond the schema. It also doesn't explain cross-field relationships such as whether availability and hours_per_week must be consistent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with the concrete action 'Update your Upwork freelancer profile' and enumerates the exact fields (title, overview, hourly rate, skills, availability). This makes it immediately distinguishable from sibling tools like upwork_get_profile or upwork_update_proposal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies the trigger condition by saying 'Modify your professional title, overview, hourly rate, skills, or availability,' so an agent can infer when to call it. However, it never explicitly names alternatives (e.g., use upwork_get_profile to read first) or states exclusions/prerequisites such as needing an existing profile.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_update_proposalUpdate ProposalAIdempotent
Update an existing proposal.
Modify your cover letter or bid amount before the client responds.
Args:
proposal_id (string, required): The proposal ID to update
cover_letter (string, optional): Updated cover letter
bid_amount (number, optional): Updated bid amount
estimated_duration (string, optional): Updated duration
Returns: Confirmation of the update.
Note: You can only update proposals that are still pending.
| Name | Required | Description | Default |
|---|---|---|---|
| bid_amount | No | Updated bid amount in USD | |
| proposal_id | Yes | The unique identifier of the proposal to update | |
| cover_letter | No | Updated cover letter | |
| estimated_duration | No | Updated estimated duration |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate idempotent, non-destructive behavior. The description adds meaningful context beyond annotations by stating that only pending proposals can be updated and that the operation must happen before the client responds. It also notes the return is a confirmation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections and a useful note about pending proposals. The Args block is somewhat redundant with the schema, but it is compact and does not significantly bloat the description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a relatively simple update tool, the description covers the key behavioral constraint (pending only), the fields that can be updated, and the return type. It is sufficient for an agent to call the tool correctly, though a bit more detail on error cases would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema coverage is 100%, so all parameters are already documented in the schema. The description's Args section repeats this information without adding meaningful new semantics beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool updates an existing proposal and specifies the modifiable fields (cover letter, bid amount, estimated duration). This distinguishes it from sibling tools like submit_proposal, withdraw_proposal, and get_proposal.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: only for proposals still pending and before the client responds. It does not explicitly name alternatives, but the timing and pending-state constraint effectively guide selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
upwork_withdraw_proposalWithdraw ProposalADestructive
Withdraw a submitted proposal.
Remove your application from a job. Note that some Connects may not be refunded.
Args:
proposal_id (string, required): The proposal ID to withdraw
reason (string, optional): Reason for withdrawal
Returns: Confirmation of withdrawal and any Connects refunded.
Important: Withdrawn proposals cannot be undone. You would need to submit a new proposal.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | No | Optional reason for withdrawing the proposal | |
| proposal_id | Yes | The unique identifier of the proposal to withdraw |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the destructiveHint=true annotation, the description discloses important behavioral consequences: 'some Connects may not be refunded' and 'Withdrawn proposals cannot be undone.' This meaningfully informs the agent about irreversible side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well organized with Args, Returns, and an Important note. The first two sentences are somewhat redundant ('Withdraw a submitted proposal' and 'Remove your application from a job'), but the overall structure is clean and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one required parameter and no output schema, the description provides sufficient context: expected behavior, return shape, and irreversible consequences. It could mention error conditions or prerequisites, but nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are already well documented. The description largely restates the schema ('proposal ID to withdraw', 'Reason for withdrawal') without adding new semantic detail beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action ('Withdraw a submitted proposal') and the resource ('Remove your application from a job'). It distinguishes the tool from siblings like upwork_update_proposal and upwork_submit_proposal by naming the unique withdrawal intent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when to use the tool: when a submitted proposal needs to be withdrawn. It does not explicitly name alternatives or exclusions, but the intended use is obvious from the first line.
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.
26 tool updates
v1.0.0- First observed
upwork_end_contract - First observed
upwork_get_connects - First observed
upwork_get_contract - First observed
upwork_get_earnings - First observed
upwork_get_job - First observed
upwork_get_job_recommendations - First observed
upwork_get_job_success_score - First observed
upwork_get_profile - First observed
upwork_get_proposal - First observed
upwork_get_proposal_stats - First observed
upwork_get_transactions - First observed
upwork_get_work_diary - First observed
upwork_list_contracts - First observed
upwork_list_messages - First observed
upwork_list_milestones - First observed
upwork_list_proposals - First observed
upwork_list_saved_jobs - First observed
upwork_request_payment - First observed
upwork_save_job - First observed
upwork_search_jobs - First observed
upwork_send_message - First observed
upwork_submit_milestone - First observed
upwork_submit_proposal - First observed
upwork_update_profile - First observed
upwork_update_proposal - First observed
upwork_withdraw_proposal
TDQS
Scored across 26 tools
Every tool maps to a distinct resource+action: job discovery, proposal lifecycle, contract management, financial metrics, profile, and messaging are cleanly separated. Even close pairs like get_earnings and get_transactions are clearly differentiated as summary versus detailed ledger, so an agent should not misselect.
All tools share the upwork_ prefix and use a consistent verb_noun pattern such as search_jobs, submit_proposal, end_contract, and send_message. There are no mixed casing styles, vague action verbs, or unpredictable naming deviations.
At 26 tools, the server is at the upper edge of what is reasonable and feels heavy, but the tools span the full freelancer lifecycle from job search through proposals, contracts, payments, and messaging. Most tools earn their place, so the count is borderline rather than egregiously bloated.
The core freelancer workflow is well covered: search and save jobs, submit and manage proposals, handle contracts, track work, request payment, and review financial metrics. Minor gaps like accepting client offers or managing client reviews mean some edge workflows still have dead ends.
Maintenance
Related MCP Connectors
Manage job applications — jobs, companies, boards, notes, and profile — from your AI client.
Review Worqen contracts and chats, find decisions and send updates from your AI assistant.
Log hours and invoice clients from your AI chat. Time tracking and invoicing for freelancers.
Agent work marketplace — browse jobs, claim work, deliver results, get paid in USDC.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceConnects AI agents to Upwork's GraphQL API, enabling job discovery, proposal management, profile tracking, and analytics.8 npm1MIT
- FlicenseNot gradedqualityFmaintenanceMCP server for the Upwork GraphQL API enabling job search, contract management, proposal drafting, and other Upwork automation tasks via natural language.-
- AlicenseAqualityDmaintenanceEnables Claude to search jobs, manage proposals, messages, and contracts on Upwork via browser automation.18Apache 2.0
- AlicenseNot gradedqualityCmaintenanceA Model Context Protocol (MCP) server that connects AI coding assistants and agentic workflows to the Upwork freelance marketplace. Enables AI-powered job discovery, proposal generation, and contract management through a structured tool interface.MIT