- Brand
- Upwork
- Category
- HR & Recruiting
- Primary Subcategory
- Talent Marketplaces & Freelance Hiring
Integration details
Description
Upwork connects clients hiring for work with the freelancers doing it. Clients can post jobs, review proposals, send offers, message freelancers, and manage contracts, milestones, and payments. Freelancers can search and save jobs, submit proposals, respond to invitations and offers, track earnings and time reports, and manage their public profile. Both sides get a consolidated dashboard of what's new.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Talent Marketplaces & Freelance Hiring
- Secondary Subcategories
- None listed
- Brand
- Upwork
- Access
- Account required
- First tracked
- 2026-08-06
- Tool count
- 47
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for Upwork
Get updates when Upwork’s Discoverability Score or category rank changes.
Competing in ChatGPT Talent Marketplaces & Freelance Hiring
View Category47 tools agents can invoke
Manage freelancer profile visibility boosters: availability badge (PIB) and profile boost ad. All write operations spend Connects and WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval. Actions: - get_status: Read current state of visibility boosters: availability badge (on/off, weekly Connects budget, cost) and profile boost ad (status, bid, targeting). No params required. - toggle_availability_badge: Enable or disable the Availability Badge (Available Now). Spending up to max_weekly_connects Connects per week when enabled. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Params: enabled (bool, required), max_weekly_connects (int, required when enabling — maximum Connects to spend per week, e.g. 8). - get_suggested_boost_bid: Get the suggested Connects bid per click for a profile boost. Params: l1_category_id (string, required — L1 category ID), l3_category_id (string, required — L3 specialty ID). - create_profile_boost: Create a profile boost ad to appear at the top of search results. Charged only when a client clicks. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Params: bid_connects (int, required — Connects per click), l1_category_id (string, required), l3_category_id (string, required), daily_budget (int, optional — max Connects/day), total_budget (int, optional — lifetime Connects cap), end_date (string, optional — yyyy-mm-dd). - manage_profile_boost: Stop, pause, restart, or update an existing profile boost ad. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Params: action (string, required — one of: stop, pause, restart, update), ad_id (string, required), bid_connects (int, optional — for update), daily_budget (int, optional — for update), total_budget (int, optional — for update), end_date (string, optional — yyyy-mm-dd, for update).
upwork__boost_profile
End a contract with a reason code, optionally attaching a freelancer review (six 1–5 scores + a comment). Runs through MCP (draft -> confirm_preview). Use list_contracts action=end_reasons to look up reason codes first. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a preview — call confirm_preview only after explicit user approval. Actions: - end: Prepare a contract-end draft. Params: contract_id (string, required), reason_id (string, required). Optional freelancer review: quality_score, skills_score, communication_score, availability_score, deadlines_score, cooperation_score (integers 1–5) and comment (string). Provide all six scores together for a complete review.
upwork__end_contract
Confirm uploaded files so they are retained in Upwork storage. Uses the same attachment backends as start_attachment_upload. Requires the upload context and the file_uid values returned from upload. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Actions: - confirm: Params: file_ids (array of strings, required — file_uid values to confirm); task_id (string, required — the task_id returned by start_attachment_upload for these files); context (string, optional — taken from the upload session; if given it must name the same backend the session was started with, or the call is refused). Only file_uid values that get_upload_status reports as done for that task_id can be confirmed; anything else is refused. Upload sessions last 30 minutes, so confirm promptly. Files uploaded through the inline component are already stored and must NOT be confirmed.
upwork__confirm_attachment_upload
Freelancers on the marketplace: search them by keywords and filters, get the freelancers recommended for one of your job postings (smart_search), or view one profile. A result whose rate carries "*Boosted" is a paid ad placement the freelancer bought, not a ranking of merit — say so when presenting it. Actions: search, get_profile, smart_search. Call get_tool_help(tool_name="find_freelancers") for how to use this tool.
upwork__find_freelancers
Search and view marketplace job postings. Actions: - search: Search for jobs matching filters. Params: query (string), job_type (fixed/hourly), experience_level (entry_level/intermediate/expert), budget_min (number), budget_max (number) (each must be greater than 0; budget_min cannot exceed budget_max; omit a bound to leave it open), workload (full_time/part_time/as_needed), verified_payment_only (boolean — only jobs from clients with a verified payment method), proposals_min (number), proposals_max (number) (filter by number of proposals already submitted; e.g. proposals_max=5 for jobs with fewer than 5 proposals), client_hires_min (number), client_hires_max (number) (filter by the client's past hire count; e.g. client_hires_min=0, client_hires_max=0 for clients with no hires, or client_hires_min=10 for 10+). Range bounds must be >= 0 and min cannot exceed max; omit a bound to leave it open. sort (recency/relevance/client_total_charge/client_rating — how to order results; omit for the default recency order), previous_clients_only (boolean — only jobs from clients you have worked with before), timezone (string — filter by the client's timezone), location (string — filter by the client's location), limit (integer, 1–10, default 10), cursor (string — omit for the first page; to fetch the next page, repeat the SAME filters with cursor set to the endCursor from the previous response's pageInfo, and only when pageInfo.hasNextPage is true). A client's preferred qualifications are NOT in search results — use get on a specific job to see them. Each result includes proposal_count (proposals submitted so far). Hire/invite liveness (total_hired, invites_sent) is NOT in search — use get on a specific job before assuming it is still open. There is NO created_after/date filter — the signed-in marketplace search API exposes none (the public search has days_posted, but find_jobs uses the signed-in search for sort and extra filters). For the freshest jobs use sort=recency (already the default order); each result carries created_date/published_date for client-side narrowing to a time window. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - get: Get full details of a job posting including client company info, work history, connects, and the client's preferred qualifications (returned as preferred_qualifications: e.g. contractor_type, minimum job success score, English level, rising_talent, earnings). When present, surface the preferred qualifications to the user so they know what the client is looking for. The response includes connects_cost (the Connects required to apply), connects_balance, and can_apply when available. Params: id or job_id (string, required — the numeric id from find_jobs action=search, a ~02… ciphertext, or a full Upwork job URL, e.g. https://www.upwork.com/jobs/~0212345 — all accepted directly, no need to extract or reformat the id yourself). If this returns access denied for a marketplace job ID, use get_job_posting action=get_marketplace with the same id. - smart_search: Auto-fetch your profile skills and search matching jobs. Params: cursor (string, optional — omit for the first page; to fetch the next page repeat with cursor set to the endCursor from the previous response's pageInfo, only when pageInfo.hasNextPage is true).
upwork__find_jobs
Browse your saved (favorite) job postings. Each saved job includes a ready-to-use url. Use find_jobs action=get for full job details. Use save_job action=save or action=unsave to update bookmarks. Actions: - list: List saved jobs for the current freelancer. Params: limit (integer, 1–10, default 10), offset (number, default 0), job_ids (array of string, optional — filter by job IDs), followed (boolean, optional — defaults to true, i.e. jobs the user currently has saved. Unsaving keeps the record with followed=false, so followed=false lists jobs that were saved and then removed — not current bookmarks). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - count: Get the number of saved jobs. No params.
upwork__find_saved_jobs
View account info, organization details, teams and the member roster. Actions: - get_user_details: Get user details. Params: id (string, optional — defaults to current user). - get_organization: Get current organization, including its teams (child organizations) when it has any. Teams are informational: they are NOT selectable accounts, so a team id must never be passed as org_uid — list_accounts returns the only usable org_uid values. No params. - list_teams: List the teams you belong to under the selected organization, optionally filtered by what you may do in each. Params: action (string, optional — one of approve_milestone, end_contract, hire, invite_freelancer, post_job, send_offer); with it each team carries allowed true/false. Team ids are team_uid FILTER values for other tools — never an org_uid. whole_organization describes acting company-wide, which is done by omitting team_uid, not by passing the org uid. - list_members: List the people on the selected client account: abbreviated name, Owner or Member, Active/Inactive, join date, company-wide roles and the teams they sit in with their roles there; an owner is listed once. Params: limit (integer, optional), offset (integer, optional — next_offset from the previous page). - get_company: Get the company details of the organization you are acting as. To read a different account of yours, call again with that org_uid. For a marketplace job's client, use find_jobs action=get with the job ID instead. No params.
upwork__get_account
View your agency: teams, members, portfolio projects, and organization details. To change the portfolio, use update_agency. Use get_messages list_rooms to view rooms. Actions: - list_agencies: List agencies you belong to. No params required. - list_teams: List teams (child organizations) in the current org. Params: limit (integer, 1–10, default 10). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - list_members: List staff members in the current org. Params: limit (integer, 1–10, default 10), cursor (string, optional — pageInfo.endCursor from a prior list for the next page; alias: after). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - list_projects: List this agency's portfolio projects — the showcase clients read when deciding whether to engage the agency. Returns title, description, project URL, completion date, rank and skill ids. Params: limit (integer, 1-20), offset (integer, optional — for the next page; total_count and has_more are in the response). Project attachments are not exposed yet. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - get_profile: View your agency's public profile: summary, website, size, minimum project size, year founded, office locations and skills. Reads the agency for the selected account, so no params are required. Rates and services are not included yet. Street addresses are never returned — locations give city, state, country and postal code.
upwork__get_agency
Get a consolidated overview of what's new: invitations, offers, messages, matching jobs, contracts, plus agency teams and members — all in one call. Access is scoped by your agency role. Actions: - check: Check all activity sources in parallel. No params required.
upwork__get_agency_dashboard
Get a consolidated overview of what's new: proposals received (grouped by job), pending offers, messages, and contract updates — all in one call. Actions: - check: Check all activity sources in parallel. No params required. proposals.jobs lists the client's open postings, newest first; each carries its status, created_time and applicant funnel (applicants, new_applicants, shortlisted, messaged, offered, hired, pending_invitations). The newest 5 proposal rows (with proposals_total) are read for at most 5 postings; the rest carry proposals_omitted. new_ai_interviews: unopened rows with AI interview results ready.
upwork__get_client_dashboard
View client financial reports: timesheets, work diaries, work-diary snapshots, and transaction history. timesheets organization_id defaults to org_uid. transactions may require elevated org permissions. Actions: - summary: Get the client Weekly financial summary for one ISO week (mirrors Reports → Weekly summary): total charged and hours, the hourly/fixed breakdown, and the Top-5 contracts and Top-5 activities by charge. All charged amounts in this summary are USD, reported by the response-level currency field. Params: from_date (string, yyyy-mm-dd, optional — selects the week containing this date; defaults to the current week). The summary is a single Monday–Sunday week. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - timesheets: Get timesheets (hours logged on your contracts). Params: organization_id (string — defaults to org_uid), from_date (string, yyyy-mm-dd), to_date (string, yyyy-mm-dd, max 53 weeks from from_date) — at least one date required; when only from_date is set, to_date defaults to today, contract_ids (array of string), limit (number). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - work_diary: Get work diaries (time cells: activity level, screenshots, keyboard/mouse activity). With NO contract_id it returns all work diaries across the company for a single day — the marketplace 'All work diaries' view. Pass contract_id to drill into one contract's diary. Params: contract_id (string, optional — a contract id from list_contracts; omit for the company-wide view), date (string, optional — yyyy-mm-dd, defaults to today UTC), activity (string, optional filter), sort_by (string, optional), paging (string, optional — company view only). - snapshots: Drill into one work-diary snapshot (a contract at a point in time): mouse/keyboard event counts, memo, task, status, and hasScreenshot — activity metadata, NOT the screenshot image. Use work_diary for the diary view; use this only for per-timestamp detail. Params: input (object, required) with contractId (string) and timestamp (integer — Unix epoch seconds, e.g. a snapshotDateTime rawValue from work_diary). - work_days: Get work days. Params: input (object, required). - transactions: Get transaction history. Params: ace_ids (array of accounting entity ID strings, optional — auto-resolved from org context if omitted), from_date (string, yyyy-mm-dd), to_date (string, yyyy-mm-dd) — when both dates are omitted, defaults to the last 30 days; when only from_date is set, to_date defaults to today (max 53 weeks from from_date). limit (number, default 25, max 200 — returns the most recent N transactions; total_count reports how many exist). May require elevated org permissions on some accounts. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.
upwork__get_client_financials
Get a consolidated overview of what's new: invitations, offers, messages, matching jobs, contract updates, connects balance, ID verification, and promotions — all in one call. Actions: - check: Check all activity sources in parallel. No params required.
upwork__get_freelancer_dashboard
View your own financial data as a freelancer or agency: earnings and transaction history, connects balance, and time report. Use this to verify a payment or earnings release. Actions: - summary: Get your earnings summary for a period (the Weekly financial summary): per-client totals (earned, billed, fee, tax) and per-job billings, plus overall totals. This is the answer to "how much did I earn" — use transactions only for the full line-item ledger. Params: from_date (string, yyyy-mm-dd), to_date (string, yyyy-mm-dd) — when both omitted, defaults to the last 30 days. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - transactions: Get transaction/earnings history. Params: ace_ids (array of accounting entity ID strings, optional — auto-resolved from org context if omitted), from_date (string, yyyy-mm-dd), to_date (string, yyyy-mm-dd) — at least one date required. accounting_entity_id (string, optional — single ACE ID shortcut, auto-resolved if omitted). limit (number, default 25, max 200 — returns the most recent N transactions; total_count reports how many exist). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - connects_balance: Get connects balance and recent usage history. Shows current balance breakdown (free, paid, rollover) and recent connects transactions with job titles. Params: limit (integer, 1–10, default 10). - timesheets: Get your timesheets (hours logged on your contracts). Params: organization_id (string — defaults to org_uid), from_date (string, yyyy-mm-dd), to_date (string, yyyy-mm-dd, max 53 weeks from from_date) — at least one date required; when only from_date is set, to_date defaults to today, contract_ids (array of string), limit (integer, 1–10, default 10). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.
upwork__get_freelancer_financials
View the job postings your organization owns. Use action=list to obtain posting IDs for list_client_proposals and list_client_invitations. Prior postings are useful templates when creating new jobs. For MARKETPLACE jobs — other clients' postings — use find_jobs, which serves clients as well as freelancers: action=search to search, action=get to read one by id. Actions: - get: Get an owned job posting by ID (from get_job_posting action=list). Params: job_id or job_posting_id. For marketplace jobs use find_jobs action=get. - list: List the selected organization's owned job postings (not marketplace), paginated. Covers the whole organization, including its teams. Params: title (string, optional — partial-match filter applied upstream), team_uid (string, optional — narrow to one team; get the ids from get_account action=get_organization childOrganizations, and never pass a team id as org_uid), limit (integer, 1–10, default 10), page (integer, default 1). Returns total_count, has_more, and next_page, plus postings[] with id, title, status, access, type, created_time, updated_time, premium, and the applicant funnel (applicants, shortlisted, messaged, offered, hired, pending_invitations, new_applicants). Use the ids for list_client_proposals / list_client_invitations; to page, call again with page=next_page. Each entry is a SUMMARY, not the full posting: description, budget, skills, screening questions and invites-sent are not included — call action=get with the id when you need them. Applicant counts ARE included, so answering "how many applied/were hired" needs no follow-up call. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.
upwork__get_job_posting
List rooms, find rooms by context, and read messages. Actions: - list_rooms: List your rooms, newest-created first and sorted by latest activity within the page — NOT a global most-recent-first inbox, and the count of rooms is not available, so never state a total. Page with cursor while hasMore is true. Params: room_type (ALL/GROUP/ONE_ON_ONE/INTERVIEW, default ALL), unread_only (boolean, optional), active_since (RFC3339 timestamp, optional — filters weakly upstream, do not rely on it to find recent conversations). unread_only=true and active_since cannot be combined. sort_order (ASC/DESC, default DESC), limit (integer, 1–100, default 10), cursor (string, optional — next_cursor from a prior list for the next page; alias: after). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - find_room: Find a room by context. Params: context_type (contract/offer/proposal/one_on_one, required), context_id (string, required), organization_id (string, required for one_on_one). For context_type=proposal: Freelancers (TALENT): cannot initiate a proposal room or send the first message on a proposal — the client must contact you first. To reply, use an existing room from list_freelancer_proposals action=get_room or get_messages action=find_room (context_type=proposal). If no room exists yet, tell the user the client needs to message first. - list_messages: List messages in a room, NEWEST FIRST — the default page is the tail of the conversation, not the whole thread. Before summarising a thread or answering whether something was ever discussed, page back with cursor while hasMore is true; the message count is not available, so never state one. Params: room_id (string, required), limit (integer, 1–100, default 20), cursor (string, optional — next_cursor from a prior call for the next page of older messages; alias: after). message_count is present only once the whole thread has been read (hasMore false); while paging, the number of messages in the room is unknown. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - get_message: Get a single message. Params: room_id (string, required), story_id (string, required).
upwork__get_messages
View freelancer profile, transaction history, and connects balance. Actions: - get: Get a freelancer profile. Params: profile_key (string, optional — starts with ~ e.g. ~01abc123, from search results). If omitted, returns the current user's own profile. Job aggregates count completed contracts: totalFixedJobs and totalHourlyJobs are the component counts, and totalJobs is their reconciled sum. - list_highlights: List your certificates and portfolio projects that can be attached to a proposal as highlights. Returns certificates (id, name) and portfolio_projects (id, title). When drafting a proposal, offer to attach the most relevant ones and pass the chosen ids to manage_proposals create as certificate_ids / portfolio_project_ids. No params. - transactions: Get transaction/earnings history. Covers the selected account's accounting entity only, so a person with more than one account sees each separately. Params: ace_ids (array of accounting entity ID strings, optional — auto-resolved from org context if omitted), from_date (string, yyyy-mm-dd), to_date (string, yyyy-mm-dd, max 53 weeks from from_date — split longer questions into one call per year) — at least one date required. accounting_entity_id (string, optional — single ACE ID shortcut, auto-resolved if omitted). limit (number, default 25, max 200 — returns the most recent N transactions; total_count reports how many exist). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - connects_balance: Get connects balance and recent usage history. Shows current balance breakdown (free, paid, rollover) and recent connects transactions with job titles. balance is the general Connects wallet; product_credits (when present) are ad credits spendable only on the named product and are NOT included in it — report them separately, never summed. Page with next_cursor until hasMore is false. Params: limit (integer, 1–10, default 10), cursor (string, optional — next_cursor from the prior call).
upwork__get_profile
Get the going hourly rate range for similar jobs to guide a job's hourly budget — the same From/To range Upwork shows in the Budget step. Read-only. Use it while helping a client set an hourly budget so the suggested rate reflects the market. Actions: - get: Get the suggested hourly rate range for a job. Params: experience_level (string, required — 'entry', 'intermediate', or 'expert'); and one of occupation_id (string — from the job classification) or project_text (string — the job title/description, used to infer the occupation). Returns rate_low / rate_high (USD/hr) and based_on_jobs (sample size).
upwork__get_rate_insights
Returns file_uid values for files a user uploaded through the web UI. Action name is get (not get_status). Upload sessions expire 30 minutes after start_attachment_upload; poll within that window. Actions: - get: Get uploaded file metadata. Params: task_id (string, required). Returns file_uid values and file metadata. Does not return file content.
upwork__get_upload_status
Invite a freelancer to a job posting. Use list_jobs to see your jobs and how many invites remain on each, then send returns a draft — call confirm_draft with type='invitation' to send. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval. Call get_tool_help(tool_name="invite_freelancer") for the actions, parameters, and how to use this tool.
upwork__invite_freelancer
List or get client job invitations for one owned job posting. Requires job_reference from get_job_posting action=list (postings[].id). Invitations are per-job only — there is no list_all. Actions: - list: List active invitations for a job, or get one invitation when invitation_id is set. Params: job_posting_id, job_id, or job_reference (string, required — owned posting ID from get_job_posting action=list), invitation_id (string, optional — when set, returns that invitation only; organizationId_eq comes from org_uid), limit (integer, 1–10, default 10) — list only), cursor (string, optional — pageInfo.endCursor from a prior list for the next page; alias: after; list only). Org comes from org_uid on execute_tool. - history: Declined, withdrawn, archived, rejected or invalid invitations for a job. Params: as list, plus status.
upwork__list_client_invitations
View proposals on your job postings. Use action=list_all to discover proposals across all postings without a job_posting_id. Use action=list when you already have job_posting_id from get_job_posting action=list. Prior proposals can provide context for drafting offers. Actions: - list: List proposals for a job, ordered as the client's own Upwork dashboard orders them. Params: job_posting_id or job_id (string, required — from get_job_posting action=list), status (string), shortlisted (bool — only proposals the client shortlisted), sort (string), search, country, top_rated, english_level, applier_type (all optional), limit (integer, 1–50, default 50), cursor (string, optional — pageInfo.endCursor from a prior list for the next page; alias: after). A proposal carrying boosted=true is one the freelancer spent their own Connects to promote to this client; its bid also carries "*Boosted". Boosted proposals lead the first page. Always tell the client which applicants paid to promote themselves — it is a paid placement, not a ranking of merit. Absence of the flag means the proposal is not boosted, which says nothing about the freelancer — a job has a limited number of paid boost slots. verified_credentials, when present, are credentials a partner institution confirmed. The response includes totalCount and pageInfo; when the user wants to review all applicants, page through with cursor until hasNextPage is false. Use list_all to discover proposals without a posting id. Declined proposals carry get_unavailable=true — that list card is the complete view; do not call get on their id. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - get: Get full proposal details. Does not work for declined proposals (see list/list_all's get_unavailable flag) — use the list card for those instead. Params: id or proposal_id (string, required). - list_all: List proposals across all your job postings. Params: status (string, optional), sort (string, optional), limit_per_job (integer, 1–10, default 10). This cross-posting scan does not flag boosted proposals — use action=list on a single posting to see which applicants promoted themselves to the client. Each job's proposals are capped at limit_per_job; a job whose pageInfo.hasNextPage is true has more applicants — page them with action=list using that job_posting_id and pageInfo.endCursor. jobs_truncated=true means the org has more postings than were scanned; narrow with action=list per posting. Declined proposals carry get_unavailable=true — that list card is the complete view; do not call get on their id. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - metadata: Get valid proposal metadata (durations, engagement values). No params needed.
upwork__list_client_proposals
View and search your contracts and time reports. ID provenance: use action=search to discover rows; for CLIENT search results use node.contract.id (not node.id) as contract_id. Offer ids for list_offers/get come from list_offers or manage_offers list, not from list_contracts search. See docs/id-chaining.md. Actions: - search: Discover contracts/offers — call this FIRST. For freelancers: vendor_id (string, defaults to your user ID). For clients: searches clientOffers automatically, across the whole organization including its teams; narrow with team_uid (string, optional — from get_account action=get_organization childOrganizations, never as org_uid). Common: contract_statuses (array: ACTIVE, CLOSED, PAUSED), start_date_before (string), end_date_after (string), limit (integer, 1–10, default 10), offset (number, default 0). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - list: Fetch known contracts by ID only — do NOT use for discovery. Params: ids (string[], required, 1–100). Obtain ids from search (node.contract.id) or get. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - get: Get full contract details by contract ID. Authoritative milestone read for active/fixed-price contracts: offer.milestones includes dueDateTime, state (plus state_label), depositAmount, fundedAmount, paid, submissionCount, and submission records at data.contractDetails.offer.milestones[].submissions[]. For manage_milestones action=reject, choose the submission with the latest submissionDateTime and pass its id — no offer-ID chaining needed. Params: contract_id (string, required). - get_original_proposal: Get the original proposal for a contract. Params: id (string, required). - timesheets: Get timesheets (time report) for contracts. Params: organization_id (string — defaults to org_uid), from_date (string, yyyy-mm-dd), to_date (string, yyyy-mm-dd, max 53 weeks from from_date) — at least one date required; when only from_date is set, to_date defaults to today, contract_ids (array of string), limit (integer, 1–10, default 10). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - end_reasons: Get valid reason codes for ending a contract. Params: reason_type (required enum: CONTRACT_END_HOURLY | CONTRACT_END_FIXED).
upwork__list_contracts
View your freelancer proposals and received invitations. Prior proposals are useful examples when drafting new proposals. Note: the status 'Accepted' means the proposal was submitted and validated (NOT that the client accepted you) — each result includes a status_label with the plain-English meaning. Start with recent submitted (Accepted) proposals; when looking for the strongest templates, also check Offered/Hired examples. Actions: - list: List your proposals with status (plus status_label), bid terms, created/modified dates, job id/title, and cover letter text. Each proposal carries boosted (true/false) and, when boosted, terms.connectsBid — the Connects bid Upwork actually STORED. This is the figure to report and the way to verify a boost after submitting: it is read back from Upwork, not the number that was sent. If it differs from what the user asked for, tell them the stored value and that the bid cannot be changed through this tool. Params: status (string, default Accepted — which means 'submitted'; values: Accepted=submitted, Offered=offer received, Hired, Activated=invitation accepted, Pending=processing, Declined, Withdrawn, Archived), sort_field (CREATEDDATETIME/MODIFIEDDATETIME, default CREATEDDATETIME), sort_order (ASC/DESC, default DESC), limit (integer, 1–10, default 10), cursor (string, optional — pageInfo.endCursor from a prior list for the next page; alias: after). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - invitations: List invitations you received from clients. The 'id' field in each result is the invitation_uid needed for manage_proposals action=accept_invitation. Each result includes jobPosting (id + title); for full job details call find_jobs action=get with jobPosting.id. Params: status (string, default pending), job_posting_id (string, optional — only invitations for that job), sort_field (CREATED, default CREATED), sort_order (ASC/DESC, default ASC), limit (integer, 1–10, default 10), cursor (string, optional — pageInfo.endCursor from a prior list for the next page; alias: after). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - get: Get full details of a proposal. Each proposal carries boosted (true/false) and, when boosted, terms.connectsBid — the Connects bid Upwork actually STORED. This is the figure to report and the way to verify a boost after submitting: it is read back from Upwork, not the number that was sent. If it differs from what the user asked for, tell them the stored value and that the bid cannot be changed through this tool. Params: id or proposal_id (string, required — from list). The response may include insights: how many proposals the job has, how many the client opened, shortlisted or messaged, and what the competing applicants look like on average (earnings, completed jobs, years on Upwork, Job Success Score) plus their most common skills. Present them as the client's activity and the field so far, not as a verdict on the proposal. When insights_available is false, relay insights_note as written: never say the job has no other applicants, and never estimate the numbers yourself. - get_room: Get the messaging room for a proposal. Params: proposal_id (string, required). Freelancers (TALENT): cannot initiate a proposal room or send the first message on a proposal — the client must contact you first. To reply, use an existing room from list_freelancer_proposals action=get_room or get_messages action=find_room (context_type=proposal). If no room exists yet, tell the user the client needs to message first.
upwork__list_freelancer_proposals
View milestone state for a fixed-price contract. Returns each milestone's state (NotFunded, Active, Submitted, Paid, …), deposit/funded/paid amounts (both rawValue and displayValue are in dollars), submission count, and — for submitted milestones — the submission deliverables with downloadable links (uploaded_by_role marks FREELANCER vs CLIENT files). Use after list_contracts to check status before submit_milestones, or after the client funds/releases payment on the web. Actions: - list: List milestones for a contract. Params: contract_id (string, required — from list_contracts search/get).
upwork__list_milestones
View and list offers. Use list_mine to see all offers for your org. Use get to fetch full details of a specific offer. The 'id' from these results is the offer_id needed for manage_proposals action=accept_invitation. Actions: - get: Get full offer details by offer ID. Milestones match list_contracts get / manage_offers get (dueDateTime, state + state_label, depositAmount, fundedAmount, paid, submissionCount). For active contracts prefer list_contracts action=get. Params: offer_id or id (string, required — from list/list_mine here; NOT clientOffers node.id from list_contracts search). - get_attachments: List the file attachments on an offer (documents the client attached to the offer), each with its file name and a downloadable link. Params: offer_id or id (string, required — the offer ID). Returns fileName and link per attachment; present each as a markdown link (the link is presigned and expires in about 15 minutes). - list: List offers for your account — offers you sent (client) or received (freelancer). No filter needed; the tool uses your org_uid automatically and covers the whole organization, including its teams. Results are newest first. Params: team_uid (string, optional — narrow to one team, from get_account action=get_organization childOrganizations; never pass a team id as org_uid). Params: limit (integer, 1–10, default 10), page (integer, default 1), Optional: states (array of strings to filter by offer state — use role-appropriate values; returned offer state matches these keys). Client: sent, awaiting_acceptance, contract_started, awaiting_approval, expired, denied, draft, withdrawn, canceled. Freelancer/agency: awaiting_your_acceptance, contract_started, awaiting_client_approval, expired, denied, draft, withdrawn, canceled. Do NOT pass searchAttribute, id, or a filter object. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - list_mine: List your offers (same as list). Results are newest first. Params: limit (integer, 1–10, default 10), page (integer, default 1), Optional: states (array of strings to filter by offer state — use role-appropriate values; returned offer state matches these keys). Client: sent, awaiting_acceptance, contract_started, awaiting_approval, expired, denied, draft, withdrawn, canceled. Freelancer/agency: awaiting_your_acceptance, contract_started, awaiting_client_approval, expired, denied, draft, withdrawn, canceled. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.
upwork__list_offers
Agency-only writes to message room settings and membership. Does not list rooms, read messages, or send chat (get_messages / send_message). Obtain room_id from get_messages list_rooms or find_room. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Actions: - update: Update room settings. Params: input (object, required — RoomUpdateInputV2). - add_member: Add user to a room. Params: room_id (string, required), users (array of RoomUserInput, required). - remove_member: Remove user from a room. Params: room_id (string, required), user_id (string, required), org_id (string, required).
upwork__agency_rooms
Manage proposals on your job postings while reviewing applicants: shortlist/un-shortlist and decline. To HIRE an applicant, use manage_offers create_draft instead (accepting a proposal is an offer). WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Actions: - shortlist: Shortlist (or un-shortlist) a proposal on your job posting. Shortlisting flags a promising applicant for later review; it does NOT hire them (to hire, use manage_offers create_draft). Params: proposal_id (string, required), job_posting_id (string, required — numeric posting id), shortlisted (bool, optional — default true; pass false to un-shortlist). - decline: Decline a proposal on your job posting (the freelancer is notified). Unlike shortlist, this returns a preview — execute it with confirm_preview type='proposal_decline'. Params: proposal_id (string, required), job_posting_id (string, required), reason (string, required — from action=decline_reasons), message (string, optional message to applicant). - decline_reasons: List valid decline reasons for client proposals. Present them to the user and pass the chosen one to action=decline as reason.
upwork__manage_client_proposals
Create or update a job posting. For create, returns a draft for review before posting. Use confirm_draft to publish after approval. Provide skills as human-readable names (e.g., 'React', 'WordPress') — they are resolved automatically. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval. Call get_tool_help(tool_name="post_job") for the actions, parameters, and how to use this tool.
upwork__post_job
Schedule video meetings with the other party in a message room. One side requests a meeting of a set length and the other picks a time from the requester's bookable slots and books it. Times cannot be invented: only the slots free_slots returns can be booked. Get room_id from get_messages (list_rooms or find_room). WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a preview for review — call confirm_preview to execute after explicit user approval. Only one pending preview is held per action type at a time: starting this action again before the current preview is confirmed replaces it without executing it, so wait for the user's decision on the pending preview before starting another change of this type. Actions: - list: List the video meetings in a room: every booked meeting, plus the meeting request still waiting for a time if there is one. Use the pending request's event_request_id with schedule, and a booked meeting's common_id with reschedule or cancel. Each meeting carries owner: true when the CALLER booked that time and false when the other party chose it. Say which of them picked it — that is what the user wants to know about a meeting that appeared in their calendar. A booked meeting is already final for both sides. Upwork has NO ACCEPT OR DECLINE on it — its own card offers only Cancel and Reschedule — so do not ask the user to accept or approve a meeting that already exists; offer to move it or cancel it. (This is about the meeting itself. The confirm_preview step below still applies to every write this tool makes.) Params: room_id (string, required). - free_slots: Show the bookable times for the meeting requested in this room, so the user can pick one. Either party can READ these — the requester can see what they have offered, which is worth telling the user — but booking is normally the other party's step. Only bookable times are returned. Ask the user which days and times suit them first, then pass that window as from_time/to_time — unfiltered this covers the next 60 days, far too many times to read out. When the user names several separate spans ("Tuesday morning or Thursday after 2"), pass them all as windows instead of guessing one range that spans them. Converting a stated day and time into epoch milliseconds is the step that goes wrong: confirm the YEAR and apply the user's UTC offset before sending. A window already in the past is refused. Times are epoch milliseconds, which are absolute — present them in the user's own timezone with the offset stated, and read that timezone from get_account (location.timezone) rather than assuming one. The other party picks in THEIR timezone, which may differ. Pass a slot's start_time to schedule. Pass common_id instead to read where an already-booked meeting can be moved to, before reschedule. Params: room_id (string, required), common_id (string, optional — read move targets for this meeting), from_time (string, optional — epoch milliseconds; defaults to now), to_time (string, optional — epoch milliseconds; when from_time is also given it must be after it and at most 60 days after it), windows (array, optional — up to 10 {from_time, to_time} objects of epoch milliseconds, for when the user names several separate spans. A recurring preference is ONE WINDOW PER DAY, not one window: "mornings only" over a working week is five windows, one 09:00-12:00 span per day, since a single span from Monday morning to Friday noon would also match Tuesday at 3am. Ten windows is therefore about two working weeks — bound the date range with the user first rather than enumerating a month. Only slots where the whole meeting fits inside a window are returned, each window must be at least as long as the meeting, none may be in the past, and all must end within 60 days of the earliest. At most 20 slots come back). - request: Request a video meeting with the other party in a room. Returns a draft — present it and call confirm_preview with type='meeting_request' and the returned preview_id to actually send the request. THE OTHER PARTY PICKS THE TIME — that is the normal flow and what the product expects. Booking your own request is possible but Upwork presents it as scheduling a meeting with yourself, so do not offer it unless the user explicitly asks to hold a time without waiting. When the user names the days or times they want, pass them as windows. windows DOES NOT LIMIT WHAT THE OTHER PARTY SEES — they are shown every one of the user's bookable times regardless, and telling the user otherwise is wrong. What windows does is check the stated times against the user's own availability before the request goes out, and return the ones that can actually be booked. To ask the other party for a specific time, say so in words in description. Params: room_id (string, required), duration_minutes (integer, required — 15, 30, 45 or 60 only), description (string, optional note shown with the request), windows (array, optional — up to 10 {from_time, to_time} objects of epoch milliseconds, one per day for a recurring preference; see the free_slots action above for the full rules, which are identical here). Optional params are user choices: do not silently invent values. Briefly surface relevant optional inputs before the action when they could affect the outcome. If the user does not choose them, proceed with only required params plus context the user already provided. - schedule: Book the outstanding meeting request in a room into a chosen time. Pass the start_time of one of the slots free_slots returned; the end time is derived from the requested length, so the booking always matches what was asked for. Returns a draft — present it and call confirm_preview with type='meeting_schedule' and the returned preview_id to actually book it. Params: room_id (string, required), start_time (string, required — epoch milliseconds, from free_slots). - reschedule: Move a booked meeting to a new time. Address it by common_id (from list), not event_id. Read free_slots with that common_id first and pass one of the times it returns: moving a meeting onto a time the other party is not free for is refused. The end time is derived from the meeting's own length, so moving it never changes how long it runs. Returns a draft — present it and call confirm_preview with type='meeting_reschedule' and the returned preview_id to actually move it (the other party is notified). Params: common_id (string, required), room_id (string, required), start_time (string, required — epoch milliseconds, from free_slots). - cancel: Cancel a booked meeting. Address it by common_id (from list), not event_id. The reason is shown to the other participant, so use the user's own words — ask them for one rather than supplying your own. Returns a draft — present it and call confirm_preview with type='meeting_cancel' and the returned preview_id to actually cancel. Params: common_id (string, required), reason (string, required — shown to the other participant).
upwork__manage_meetings
WRITE milestone management. create, edit, delete, and reject run through MCP (draft -> confirm_draft). fund (activate) and approve move money — funding escrow and releasing payment — so they are completed by you on Upwork and return a link, NOT a draft. No list/get actions — inspect milestone state via list_contracts action=get (offer.milestones includes state, amounts, paid, submissionCount). WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval. Call get_tool_help(tool_name="manage_milestones") for the actions, parameters, and how to use this tool.
upwork__manage_milestones
Create draft offers and manage offers to freelancers. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Creates a draft that must be finalized on upwork.com by the user. Call get_tool_help(tool_name="manage_offers") for the actions, parameters, and how to use this tool.
upwork__manage_offers
Submit, edit, or withdraw freelancer proposals. Also accept or decline client job invitations. For client offers, use respond_to_offer. Freelancers (TALENT): cannot initiate a proposal room or send the first message on a proposal — the client must contact you first. To reply, use an existing room from list_freelancer_proposals action=get_room or get_messages action=find_room (context_type=proposal). If no room exists yet, tell the user the client needs to message first. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval. Call get_tool_help(tool_name="manage_proposals") for the actions, parameters, and how to use this tool.
upwork__manage_proposals
Save freelancers to your talent lists ("Your Lists"), create lists, and browse the freelancers in a list. Get freelancer_id (personId) from find_freelancers. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Actions: - list_lists: List your talent lists ("Your Lists"). No params. Returns each list's list_id (only for custom lists), list_type, title, and talent_count. - create_list: Create a new talent list. Params: title (string, required), description (string, optional). - delete_list: Delete a talent list. Params: list_id (string, required — a custom list's id). - save: Save (favorite) a freelancer. Params: freelancer_id (string, required — personId from find_freelancers), list_id (string, optional — a custom list's id from list_lists). OMIT list_id to add to your default "Favorites" list, which the tool creates automatically if it doesn't exist yet. - unsave: Remove a freelancer from a list. Params: freelancer_id (string, required), list_id (string, optional — the custom list to remove from; omit to remove from your default "Favorites" list). - list_talents: List the freelancers in a list. Params: list_id (string, optional — a custom list's id; omit to list all saved freelancers across your lists), limit (integer, 1–20, default 20), offset (number, default 0). Note: newly saved freelancers may take a moment to appear here — use lists_for_talent for an immediate check. - lists_for_talent: Show which of your lists a freelancer is in. Params: freelancer_id (string, required — personId).
upwork__manage_talent_lists
Accept, decline, or request changes to a client offer. Use this tool for all offer responses. 'decline' and 'request_changes' run through MCP (draft -> confirm_preview). 'accept' is legally binding and must be completed by you on Upwork — it returns a link. Use list_offers action=list_mine to find your offers and the offer ID. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a preview — call confirm_preview only after explicit user approval. Actions: - accept: Get the Upwork link to ACCEPT an offer. Accepting is legally binding (it starts the contract) and must be done by the person on Upwork — this returns a finalize_url, it does NOT accept the offer. The offer_id must come from list_offers (action=list_mine or get). Params: offer_id (string, required). - decline: Decline an offer from a client (not binding; confirm_preview type='offer_decline'). The offer_id must come from list_offers (action=list_mine or get). Params: offer_id (string, required), reason (string, optional — one of: terms, busy, duplicate, no_response, spam, error, other, requirements), message (string, optional — message to the client). - request_changes: Request changes to an offer / counter-offer (NOT binding — the client must approve and send an updated offer; confirm_preview type='offer_request_changes'). Params: offer_id (string, required — the offer to change), description (string, required — the changes you're requesting), hourly_rate (string, required — requested rate, e.g. '55.00'), currency (string, default USD), weekly_limit (number, optional), message (string, optional — note to the client).
upwork__respond_to_offer
Manage your own marketplace job lists: save (favorite) a job to come back to it, or hide a job to keep it out of your search results. Both lists are private — the client is never notified, and hiding is not feedback about the client or a review of any kind. Hidden jobs are already excluded from future search results by the backend, so no extra filtering is needed in find_jobs. Get job_id from find_jobs (search or get). Browse saved jobs with find_saved_jobs. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Actions: - save: Save a job to your saved jobs list. Params: job_id (string, required — job posting ID). - unsave: Remove a job from your saved jobs list. Params: job_id (string, required — job posting ID). - hide: Hide a job so it stops appearing in your search results, recording why. Params: job_id (string, required — numeric id from find_jobs), reason (string, required — one of: not_interested, vague_description, unrealistic_expectations, too_many_applicants, too_old, poor_client_reviews, doesnt_match_skills, overqualified, too_low_budget, location_mismatch). The client is not notified and cannot see this. - unhide: Un-hide a job you previously hid, letting it appear in search results again. Params: job_id (string, required — numeric id from find_jobs). - hide_status: Check whether you have hidden a job, and for what reason. Params: job_id (string, required — numeric id from find_jobs).
upwork__save_job
Create rooms and send messages. message is max 10240 characters — if the user's text is longer, ask them to shorten it rather than sending it truncated. Each file_attachments item needs file_id and file_name from start_attachment_upload; include image_id when present. Freelancers cannot send the first message on a proposal — see PROPOSAL MESSAGING. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Actions: - create_room: Create a group room. Params: input (object, required — RoomCreateInputV2). - send: Send a message to a room. Params: room_id (string, required), message (string, required unless file_attachments is set). file_attachments (array, optional). - send_to_user: Send a message to a user (auto-creates 1-on-1 room if needed). Starting a conversation with a freelancer you are not yet connected to uses one of a limited number of new connections per day; the response includes remaining_connections. Optionally attach a job via job_posting_id to share it — the recipient gets a link plus a job id their assistant can open with find_jobs get. Params: user_id (string, required), org_id (string, required — recipient's org ID), job_posting_id (string, optional), message (string, required unless file_attachments is set). file_attachments (array, optional). - message_proposal: Send a message to a proposal applicant (auto-creates room if needed). Params: job_posting_id (string, required), proposal_id (string, required), message (string, required unless file_attachments is set). file_attachments (array, optional). - edit: Edit a sent message. Params: room_id (string, required), story_id (string, required), message (string, required unless file_attachments is set).
upwork__send_message
Requests a secure file upload from the user. Creates a short-lived upload session and returns task_id plus fallback_url. In MCP App-capable hosts, an inline upload UI may appear; otherwise share fallback_url with the user. The inline upload UI supports up to 7 MB per file. The fallback_url page supports up to 100 MB per file and 300 MB total; use it for larger files. Never ask for base64 text or local file paths. Before calling upload, you MUST know the upload context. Ask the user to choose messages, proposals, offer, milestones, job, or invitation when it is not obvious from the conversation. Never guess a context. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Actions: upload. Call get_tool_help(tool_name="start_attachment_upload") for the parameters and how to use this tool.
upwork__start_attachment_upload
Confirm and execute a previously prepared draft for job postings, proposals, invitation accepts, invitations, milestones, profile updates, and offer decline / request-changes. Requires draft_id from the prior draft action. Do NOT use to ACCEPT an offer — accepting is finalized on upwork.com via the finalize_url returned by respond_to_offer accept. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. You MUST present full action details and receive explicit approval before executing. Each write requires separate confirmation even if the user said "approve all". Actions: - confirm: Confirm and execute a draft using draft_id only. Params: type (string, required), draft_id (string, required — from the create draft response). Do not pass the returned params; they are loaded from server storage.
upwork__confirm_draft
Submit milestones for client review. Use this to request approval on completed milestone work. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a preview — call confirm_preview only after explicit user approval. Actions: - submit: Submit a milestone for client review/approval. Params: milestone_id (string, required), message (string, required — note to the client), amount (object, optional — { decimal_amount: string, currency: string } to submit a partial amount), attachments (array of strings, optional — file uids to attach as deliverables; upload them first with the 'milestones' upload context).
upwork__submit_milestones
Change your agency: portfolio projects (add, edit, reorder, remove). Read the current state with get_agency. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a preview for review — call confirm_preview to execute after explicit user approval. Only one pending preview is held per action type at a time: starting this action again before the current preview is confirmed replaces it without executing it, so wait for the user's decision on the pending preview before starting another change of this type. Actions: - create_project: Add a portfolio project to this agency's showcase. Params: title (string, required), overview (string, required — what the project involved), project_url (string, optional), completion_date (string, optional — yyyy-mm-dd), skills (array of strings, optional — Upwork skill ids). Attachments are not supported yet. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - update_project: Update a portfolio project. Pass project_id plus only the fields you want to change — the tool reads the current project and merges, because the upstream call replaces the whole record and would otherwise blank anything omitted. The draft's carried_over lists exactly which fields are preserved; position is changed with reorder_projects, not here. Existing attachments cannot be preserved through this action, so the draft warns when the project has any. Params: project_id (string, required — from list_projects), title, overview, project_url, completion_date, skills (all optional). Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - reorder_projects: Reorder the portfolio. Params: project_ids (array of strings, required — EVERY project id from list_projects, in the order you want them, most prominent first). A partial list is rejected upstream, so call list_projects first and send the complete set. The draft preview shows the resulting order by title — confirm that, not the rank numbers. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply. - delete_project: Remove a portfolio project. Params: project_id (string, required — from list_projects). Deletion is permanent, and the result is verified by re-reading the portfolio because the upstream call reports acceptance rather than removal. Optional params are refinements: do not silently invent values. If the user makes a broad request, briefly surface the most relevant available refinements and proceed with only the required params plus context the user already provided. Ask before applying optional filters when the user asks for a selective result such as best, top, cheapest, near me, urgent, or only. After returning results, mention useful refinements the user can apply.
upwork__update_agency
Update contract conditions. pause and restart run through MCP (draft -> confirm_preview). Changing the weekly hours limit is completed by you on Upwork and returns a link, not a direct change. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a preview — call confirm_preview only after explicit user approval. Actions: - pause: Prepare a contract pause draft. Params: contract_id (string, required), message (string). - restart: Prepare a draft to restart a paused contract. Params: contract_id (string, required), message (string). - update_hourly_limit: Get the Upwork link to change a contract's weekly hours limit. Changing the limit notifies the freelancer and must be done by you on Upwork — this returns a finalize_url, it does NOT change the limit. Params: contract_id (string, required).
upwork__update_contract
Manage freelancer profile: availability, employment, languages, education, and other experience. WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION WRITE OPERATION — REQUIRES EXPLICIT USER CONFIRMATION. Returns a draft for review — call confirm_draft to execute after explicit user approval. Call get_tool_help(tool_name="update_profile") for the actions, parameters, and how to use this tool.
upwork__update_profile
Retrieve a pending server-stored preview without consuming it. Actions: - get: Get a pending preview for review. Params: type (required — the preview type), id (required — the preview_id returned by the creating action).
upwork__get_preview
Deprecated alias of get_preview (identical behaviour) — prefer get_preview. Actions: - get: Get a pending preview for review. Params: type (required — the preview type), id (required — the preview_id returned by the creating action).
upwork__get_draft
Get the full reference for a tool: its complete description and input schema, including every action and all required and optional parameters. Call this before using a tool whose listed description is brief and you need the full field list. Params: - tool_name (string, required) — the tool to describe (a name from search_tools or the tool list).
List your available Upwork accounts (Freelancer, Client, Agency). Call this first.
App-only tool that persists files uploaded through the inline MCP App UI. The model does not call this tool.
Upwork ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Upwork's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Upwork alternatives on ChatGPT?
As of 2026-10-18, Upwork competes with American Traveler Jobs, Fonzi Talent, GetMeDesign, Hacesfalta, Lawtrades, MatchMyCrew.com, NannyFYI, NexoRush and 5 more in ChatGPT Talent Marketplaces & Freelance Hiring, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.