write-proposal

Installation
SKILL.md

Write an Upwork proposal

Create a focused proposal grounded in the freelancer's real profile and work history. Optimize for relevance and credibility, not volume or generic persuasion.

Select the account

Call list_accounts and choose an account whose raw role is TALENT or FL_AGENCY. Ask the user when more than one is eligible. Retain org_uid and role for every later call, but refer to the account by name and role_label.

Read the job

  1. Call find_jobs with action get. Its id parameter accepts a numeric job id, a ~02… ciphertext, or a full Upwork job URL, so a link the user pasted can be passed through unchanged.
  2. To find candidate jobs first, use find_jobs action search when the user supplies search terms, or action smart_search when they want work matched to their own profile. Do not pass profile skills into smart_search; the recommender already knows the profile. Its default mode is best_match. Whenever you return those results, say that Most Recent is also available, and switch to mode: most_recent when they ask for the newest work. Date filters (days_posted, or from_date / to_date) apply only to most_recent; action search cannot filter by date. Search rows do not include connects_cost; read that from action get when the user opens a specific job. A result with applied true means this freelancer already applied — do not recommend applying again.
  3. Surface the exact title, scope, budget, required skills, client preferences, screening questions, and the Connects cost to apply when the response includes them.
  4. A job's client.rating is the average score other freelancers gave that client after working with them, not the client's rating of freelancers. Surface a low rating when the user is deciding whether to apply, and relay the response's client_rating_basis framing rather than inventing your own.
  5. When a search returns no rows, read empty_reason and say what it means; do not report that the marketplace is empty. If no_personalization, use action search for the whole marketplace. When there is no empty_reason, say only that nothing matched these criteria; an upstream restriction looks the same, so do not assert either.

Rule out an existing invitation or proposal

Do this before drafting. Upwork rejects a duplicate application upstream, so skipping the check wastes the user's turn and can look like a server fault.

Installs
87
GitHub Stars
13
First Seen
Sep 16, 2026