Skip to main content
Glama

upwork-mcp

An MCP server for Upwork automation. Search jobs, draft and submit proposals, manage messages and contracts — all from Claude Desktop or any MCP-compatible client.

Features

  • Job Search — keyword search with filters (budget, hourly rate, experience level, client rating, recency), automatic scoring and red-flag detection

  • Proposal Workflow — draft from templates, preview, then submit with explicit confirmation; daily limit enforced

  • Client Vetting — 7-condition red-flag checker (payment verification, rating, hire history, account age, repost count, proposal volume, hourly rate floor)

  • Messages — list unread conversations, read threads, draft and send replies

  • Contracts — list active/past contracts, view details and work diary entries

  • Session Safety — persistent Chromium profile, Cloudflare detection, 7-day idle expiry, domain restriction to upwork.com

  • Audit Log — every tool call appended to ~/.upwork-mcp/audit.log (metadata only, no content)

Requirements

  • Python 3.11+

  • uv (recommended) or pip

  • A valid Upwork account

Installation

git clone https://github.com/kubegrind/upwork-mcp
cd upwork-mcp
uv sync
uv run playwright install chromium

Using pip

git clone https://github.com/kubegrind/upwork-mcp
cd upwork-mcp
pip install -e .
playwright install chromium

Configuration

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "upwork": {
      "command": "uv",
      "args": [
        "--directory",
        "/absolute/path/to/upwork-mcp",
        "run",
        "upwork-mcp"
      ]
    }
  }
}

Claude Code

claude mcp add upwork -- uv --directory /absolute/path/to/upwork-mcp run upwork-mcp

Environment Variables

Variable

Default

Description

UPWORK_MCP_HOME

~/.upwork-mcp

Data directory for profile, logs, templates

UPWORK_MCP_MIN_HOURLY_RATE

25

Minimum acceptable hourly rate for red-flag detection

Authentication

The server uses a persistent Chromium browser profile. On first run, authenticate manually:

uv run upwork-mcp --no-headless

A browser window will open. Log in to Upwork normally. The session is saved to ~/.upwork-mcp/profile/ and reused on subsequent runs. Sessions expire after 7 days of inactivity.

Tools

Jobs

Tool

Description

upwork_search_jobs

Search by keyword with filters; returns scored, ranked results

upwork_get_job_details

Full job details including client history and interview rate

upwork_score_job

Score a specific job 1–10

upwork_flag_client

Check a client against 7 red-flag conditions

upwork_run_saved_search

Run a saved search from ~/.upwork-mcp/searches/<name>.json

Proposals

Tool

Description

upwork_get_proposals

List submitted proposals with status

upwork_get_proposal_details

Details for a specific proposal

upwork_draft_proposal

Draft a proposal from a template

upwork_preview_proposal

Preview a draft before submission

upwork_submit_proposal

WRITE — submit a proposal (requires confirmed: true)

upwork_withdraw_proposal

WRITE — withdraw a submitted proposal (requires confirmed: true)

Messages

Tool

Description

upwork_get_messages

List unread conversations

upwork_get_conversation

Read the last 10 messages in a thread

upwork_draft_message

Draft a reply for review

upwork_send_message

WRITE — send a message (requires confirmed: true)

Contracts

Tool

Description

upwork_get_contracts

List active and past contracts

upwork_get_contract_details

Contract details and milestones

upwork_get_work_diary

Hours and memo entries for a contract

Profile

Tool

Description

upwork_get_my_profile

Name and title from your profile

upwork_get_connects_balance

Current connects balance with low-balance warning

upwork_get_profile_stats

JSS, Top Rated status, and total earnings

Session & Audit

Tool

Description

upwork_check_session

Verify the session is authenticated

upwork_close_session

WRITE — close the browser session

upwork_rotate_session

WRITE — restart the browser context

upwork_view_audit_log

View the last N audit log entries

Proposal Templates

Templates live in ~/.upwork-mcp/templates/. The default template is loaded from default.txt if it exists. Pass a filename via template_name to use a custom template.

Supported variables:

{job_title}         {client_name}       {key_skill}
{estimated_timeline} {rate}             {years_experience}
{industries}        {custom_paragraph}  {start_date}
{your_name}

Example template (~/.upwork-mcp/templates/default.txt):

Hi {client_name},

I noticed you're looking for {key_skill} help on {job_title}.
I have {years_experience} years of relevant experience and can deliver {estimated_timeline}.

My rate is {rate}.

{your_name}

Saved Searches

Create JSON files in ~/.upwork-mcp/searches/ to save search configurations:

{
  "query": "devops kubernetes",
  "experience_level": "expert",
  "budget_min": 500,
  "client_rating_min": 4.5
}

Run with upwork_run_saved_search(search_name="devops").

Job Scoring

Jobs are scored 1–10 using a weighted model:

Factor

Weight

Budget match

30%

Skill match

25%

Client quality

20%

Proposal competition

15%

Recency

10%

Jobs scoring below 4.0 are filtered from results. Jobs scoring 7.0 or above are marked [HIGH PRIORITY].

Safety

  • WRITE tools (submit_proposal, withdraw_proposal, send_message, close_session, rotate_session) require confirmed: true — the model cannot act without explicit user confirmation

  • Daily proposal limit — hard block at 10 submissions per day

  • Domain restriction — browser navigation is restricted to upwork.com

  • No credential exposure — cookies and tokens are never returned, logged, or printed

  • Path traversal protection — template and saved search filenames are validated with Path.is_relative_to()

  • Audit log — all tool calls recorded with timestamp, action type, target, and status

Development

uv sync --extra dev
uv run pytest
uv run ruff check src
uv run mypy src

License

MIT

A
license - permissive license
-
quality - not tested
-
maintenance - not tested

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/kubegrind/upwork-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server