MCP server for Upwork via browser automation
Project description
Upwork MCP Server
MCP server that lets AI agents search jobs, manage proposals, read messages, and track contracts on Upwork โ via real browser automation.
Table of Contents
- Quick Start
- Features
- How It Works
- Installation
- Authentication
- Available Tools
- Usage Examples
- CLI Reference
- Development
- Troubleshooting
- License
Quick Start
1. Add to your MCP config
Copy-paste this into your MCP client settings (Claude Code, Cursor, Claude Desktop, etc.):
{
"mcpServers": {
"upwork": {
"command": "uvx",
"args": ["lead-upwork-mcp"]
}
}
}
2. Authenticate (once)
Pick one:
-
Interactive login (recommended for first-time):
uvx lead-upwork-mcp --login
Browser opens โ log in manually, solve any CAPTCHA, session saved automatically.
-
Auto login (AI-driven, pass credentials as params):
uvx lead-upwork-mcpThen call
upwork_login_autowith email/password from your AI agent.
3. Start using it
Ask your AI agent: "Show my Upwork jobs", "Check my messages", "Submit a proposal to this job", etc.
Features
| Category | Capabilities |
|---|---|
| ๐ Jobs | Search, filters, recommendations, saved searches, advanced discovery |
| ๐ Proposals | View, submit, withdraw, draft, templates, bulk submission |
| ๐ฌ Messages | Read inbox, conversations, send, search, manage threads |
| ๐ค Contracts | View contracts, milestones, work diary, earnings breakdown |
| ๐ค Profile | Profile info, connects, stats, skills, endorsements, analytics |
| ๐ค Clients | Client profiles, feedback, relationship tracking, activity monitoring |
| ๐ Session | Interactive login, auto-login, resume, logout, session check, health check |
| ๐ก๏ธ Anti-detection | Uses Chrome DevTools Protocol (CDP) to bypass Cloudflare bot detection |
| โก Rate Limiting | Smart throttling (8s between searches), exponential backoff (10s/20s retries), extended cache (15min) |
| 41 Tools | All implemented and ready โ no planned or missing tools |
How It Works
Upwork blocks most automation tools through Cloudflare. This server sidesteps that by connecting to your real Chrome browser via CDP (Chrome DevTools Protocol):
AI Agent โ MCP Server (stdio) โ Chrome CDP โ Upwork (with your real cookies)
- No API keys needed โ uses your authenticated browser session
- Cloudflare bypass โ your real browser profile with history and cookies
- No headless bot โ runs inside your actual Chrome, not a detected automation browser
- Session persistence โ cookies survive between runs
- CAPTCHA detection โ real CAPTCHAs and Cloudflare challenges escalate to the user via exception to the agent; invisible reCAPTCHA badges are ignored
Performance & Rate Limiting
This server implements a three-layer defensive approach to prevent Cloudflare rate limiting on rapid job searches:
- Request Rate Limiting โ Enforces 8-second minimum interval between consecutive searches
- Exponential Backoff โ Retries with increasing delays (10s, 20s) if Cloudflare blocks occur
- Extended Cache โ Caches search results for 15 minutes to reduce redundant API calls
Result: Multiple searches work reliably without triggering rate limits. The system automatically recovers from temporary blocks.
Installation
Prerequisites
| Requirement | Version | Install |
|---|---|---|
| Python | โฅ 3.12 | python --version |
| uv | latest | pip install uv or official installer |
| Google Chrome | latest | Download |
Install from PyPI (recommended)
uvx lead-upwork-mcp
That's it โ uvx downloads and runs it in an isolated environment. No clone, no install.
Install from source
git clone https://github.com/SARAMALI15792/Lead-upworkFTE.git
cd Lead-upworkFTE
uv sync
Authentication
Interactive login
uvx lead-upwork-mcp --login
Opens Chrome, navigates to Upwork, and waits for you to:
- Click the Cloudflare checkbox (if present)
- Enter your credentials
- Complete any CAPTCHA or 2FA
Once logged in, session cookies are saved to ~/.lead-upwork/.
Auto login (AI-driven)
Call the upwork_login_auto tool with your credentials:
- Pass
emailandpasswordโ fills the login form via CDP automation - Optional
tfa_codefor two-factor authentication codes - Detects Cloudflare and CAPTCHA challenges โ returns a
blockedstatus so the agent can ask the user to solve them manually - After the user solves a challenge, call
upwork_login_resumeto continue waiting for the dashboard
# Example: agent calls upwork_login_auto
result = await upwork_login_auto(email="user@example.com", password="***")
# If blocked by CAPTCHA, ask user to solve it, then:
result = await upwork_login_resume()
Check session status
uvx lead-upwork-mcp --check
Or call upwork_check_session from your AI agent.
Clear session (logout)
uvx lead-upwork-mcp --logout
Or call upwork_logout from your AI agent.
Tip: Run
--loginorupwork_loginperiodically if your session expires. Upwork cookies typically last a few days.
Available Tools
41 tools across 7 categories โ all implemented.
| Category | Tools | Count |
|---|---|---|
| ๐ Jobs | upwork_search_jobs, upwork_get_job_details, upwork_search_jobs_advanced, upwork_get_recommended_jobs |
4 |
| ๐ Proposals | upwork_get_proposals, upwork_get_proposal_details, upwork_submit_proposal, upwork_withdraw_proposal, upwork_search_proposals, upwork_create_proposal_draft, upwork_get_proposal_templates, upwork_suggest_proposal_content, upwork_bulk_submit_proposals |
9 |
| ๐ฌ Messages | upwork_get_messages, upwork_get_conversation, upwork_send_message, upwork_get_unread_count, upwork_search_messages, upwork_manage_conversation |
6 |
| ๐ค Contracts | upwork_get_contracts, upwork_get_contract_details, upwork_get_work_diary, upwork_get_contract_milestones |
4 |
| ๐ค Profile | upwork_get_my_profile, upwork_get_connects_balance, upwork_update_profile, upwork_get_earnings_breakdown, upwork_get_profile_stats, upwork_get_skills_endorsements, upwork_get_profile_analytics |
7 |
| ๐ค Clients | upwork_get_client_profile, upwork_get_past_clients, upwork_get_client_feedback, upwork_track_client_activity |
4 |
| ๐ Session | upwork_login, upwork_login_auto, upwork_login_resume, upwork_logout, upwork_check_session, upwork_close_session, upwork_browser_health_check |
7 |
Usage Examples
Search for jobs
Search for Python developer jobs on Upwork with budget over $1000
Find entry-level fixed-price AI agent projects
Get job details
Get details for: https://www.upwork.com/jobs/~01234567890
Manage proposals
Show my active proposals
Submit a proposal to https://www.upwork.com/jobs/~01234567890
with a $500 bid and this cover letter: "I have 5 years of Python experience..."
Read and send messages
Check my Upwork messages
Reply to the last conversation: "Thanks, I'll get started right away"
Check contracts and earnings
Show my active contracts
What's my total earnings on Upwork?
Auto-login
Log in to Upwork with email user@example.com and password ****
I'm blocked by a CAPTCHA, I'll solve it now... ok try again
CLI Reference
lead-upwork-mcp [OPTIONS]
Options:
--login Open browser for manual Upwork login
--check Verify if the saved session is still valid
--logout Clear the saved browser session
--no-headless Show the browser window (useful for debugging)
--timeout MS Page timeout in milliseconds (default: 30000)
--transport MCP transport type (default: stdio)
Development
Project Structure
lead-upwork-mcp/
โโโ pyproject.toml # Package config (hatchling build)
โโโ README.md
โโโ LICENSE
โโโ .gitignore
โโโ src/upwork_mcp/
โ โโโ __init__.py
โ โโโ server.py # MCP server entry point + CLI (41 tools)
โ โโโ sdk.py # SDK interface
โ โโโ browser/
โ โ โโโ __init__.py
โ โ โโโ client.py # Chrome CDP browser wrapper
โ โ โโโ auth.py # Login flows: interactive, auto, resume, logout
โ โ โโโ exceptions.py # LoginError, CloudflareChallengeError, CaptchaChallengeError, TFARequiredError
โ โโโ tools/
โ โ โโโ __init__.py
โ โ โโโ jobs.py # Job search & details (4 tools)
โ โ โโโ proposals.py # Proposal management (9 tools)
โ โ โโโ messages.py # Inbox & messaging (6 tools)
โ โ โโโ contracts.py # Contracts & work diary (4 tools)
โ โ โโโ profile.py # Profile, connects, stats (7 tools)
โ โ โโโ clients.py # Client profiles & tracking (4 tools)
โ โโโ utils/
โ โโโ __init__.py
โ โโโ config.py # Configuration management, URL constants, paths
โ โโโ retry.py # Retry helpers
โโโ scripts/
โ โโโ test_all.py # Integration test suite
โ โโโ debug_search.py # Search diagnostics
โ โโโ debug_search_path.py # Search pipeline smoke test
โ โโโ inspect_pages.py # Page structure inspection
โ โโโ test_search_direct.py # Direct search testing
โโโ tests/
โ โโโ __init__.py
โ โโโ conftest.py
โ โโโ test_auth.py
โ โโโ test_browser.py
โ โโโ test_clients.py
โ โโโ test_contracts.py
โ โโโ test_jobs.py
โ โโโ test_messages.py
โ โโโ test_profile.py
โ โโโ test_proposals.py
โ โโโ test_tools.py
โโโ uv.lock # Dependency lock file
Run tests
uv run pytest tests/ -q
All 146 tests pass.
Build the package
uv build
Troubleshooting
Session expired
uvx lead-upwork-mcp --login
Or call upwork_login_auto with your credentials.
Cloudflare CAPTCHA appears during tool calls
Run with a visible browser so you can solve it manually:
{
"mcpServers": {
"upwork": {
"command": "uvx",
"args": ["lead-upwork-mcp", "--no-headless"]
}
}
}
Or use the auto-login tools: upwork_login_auto detects challenges and returns a blocked status, then upwork_login_resume picks up after the user solves them.
Chrome not found
Install the bundled Chromium:
uvx patchright install chromium
"Not logged in" error
Your Upwork session expired. Re-run authentication:
uvx lead-upwork-mcp --login
Parallel tool call conflicts
The server serializes all tool calls internally โ no manual workaround needed. If you see race conditions, make sure you're on the latest version.
Cloudflare rate limiting on multiple searches
Multiple rapid searches may trigger rate limiting. The server now handles this automatically:
- Enforces 8-second spacing between searches
- Automatically retries with exponential backoff (10s, 20s delays)
- Caches results for 15 minutes to reduce redundant requests
If you still see blocked_by_upwork_cloudflare errors, wait 30-60 seconds and try again.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lead_upwork_mcp-0.3.0.tar.gz.
File metadata
- Download URL: lead_upwork_mcp-0.3.0.tar.gz
- Upload date:
- Size: 229.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3a61e150e9386534804e00c11ae5b29a0bc8a6f2bff4fde67dfdf27f91929aaf
|
|
| MD5 |
2d5144db45fd5528353402a33bd2d4e4
|
|
| BLAKE2b-256 |
0bebff9dfcad43f42ce0f70675fd86aac14fb16621fe752889b0ef1c297c089f
|
File details
Details for the file lead_upwork_mcp-0.3.0-py3-none-any.whl.
File metadata
- Download URL: lead_upwork_mcp-0.3.0-py3-none-any.whl
- Upload date:
- Size: 54.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b14dff033377c1c63a8a3b1375bfaa002e98f805bacba628546058f33ee7855
|
|
| MD5 |
d1942f2111ce72507bdc230c6ca0d61f
|
|
| BLAKE2b-256 |
9fa9a8bb64b279bbd0731f2d87def3a6cd34816d69d38bbdf362c19129403f9f
|