Metadata-Version: 2.4
Name: lead-upwork
Version: 0.2.0
Summary: MCP server for Upwork via browser automation
License-Expression: Apache-2.0
License-File: LICENSE
Requires-Python: >=3.12
Requires-Dist: camoufox[geoip]>=0.4.0
Requires-Dist: mcp>=1.0.0
Requires-Dist: patchright>=1.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: python-dotenv>=1.0.0
Description-Content-Type: text/markdown

# Upwork MCP Server

<p align="center">
  <a href="https://pypi.org/project/upwork-mcp/"><img src="https://img.shields.io/pypi/v/upwork-mcp?label=PyPI&color=blue" alt="PyPI"></a>
  <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/pypi/pyversions/upwork-mcp?label=Python" alt="Python"></a>
  <a href="https://github.com/SARAMALI15792/Lead-upworkFTE/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-green.svg" alt="License"></a>
  <a href="https://github.com/astral-sh/uv"><img src="https://img.shields.io/badge/built%20with-uv-black" alt="uv"></a>
</p>

<p align="center">
  <strong>MCP server that lets AI agents search jobs, manage proposals, read messages, and track contracts on Upwork — via real browser automation.</strong>
</p>

---

## Table of Contents

- [Quick Start](#quick-start)
- [Features](#features)
- [How It Works](#how-it-works)
- [Installation](#installation)
- [Authentication](#authentication)
- [Available Tools](#available-tools)
- [Usage Examples](#usage-examples)
- [CLI Reference](#cli-reference)
- [Development](#development)
- [Troubleshooting](#troubleshooting)
- [License](#license)

---

## Quick Start

### 1. Add to your MCP config

Copy-paste this into your MCP client settings (Claude Code, Cursor, Claude Desktop, etc.):

```json
{
  "mcpServers": {
    "upwork": {
      "command": "uvx",
      "args": ["upwork-mcp"]
    }
  }
}
```

### 2. Run the login flow (once)

```bash
uvx upwork-mcp --login
```

A browser window opens — log in to Upwork and solve any CAPTCHA. Session cookies are saved automatically.

### 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 by keyword, category, budget range, experience level, and job type |
| **📋 Proposals** | View, submit, and withdraw proposals with cover letters |
| **💬 Messages** | Read inbox, view conversation history, send messages |
| **🤝 Contracts** | View active/ended contracts, check work diary entries |
| **👤 Profile** | View freelancer profile, connects balance, JSS score, and earnings stats |
| **🛡️ Anti-detection** | Uses Chrome DevTools Protocol (CDP) to bypass Cloudflare bot detection |

---

## 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

---

## Installation

### Prerequisites

| Requirement | Version | Install |
|------------|---------|---------|
| Python | ≥ 3.12 | `python --version` |
| uv | latest | `pip install uv` or [official installer](https://docs.astral.sh/uv/) |
| Google Chrome | latest | [Download](https://www.google.com/chrome/) |

### Install from PyPI (recommended)

```bash
uvx upwork-mcp
```

That's it — `uvx` downloads and runs it in an isolated environment. No clone, no install.

### Install from source

```bash
git clone https://github.com/SARAMALI15792/Lead-upworkFTE.git
cd Lead-upworkFTE
uv sync
```

---

## Authentication

### First-time login

```bash
uvx upwork-mcp --login
```

This opens Chrome, navigates to Upwork, and waits for you to:
1. Click the Cloudflare checkbox (if present)
2. Enter your credentials
3. Complete any CAPTCHA

Once logged in, session cookies are saved to `~/.upwork-mcp/`.

### Check session status

```bash
uvx upwork-mcp --check
```

### Clear session (logout)

```bash
uvx upwork-mcp --logout
```

> **Tip**: Run `--login` periodically if your session expires. Upwork cookies typically last a few days.

---

## Available Tools

### Jobs

| Tool | Description |
|------|-------------|
| `upwork_search_jobs` | Search jobs with filters for query, category, budget, experience, type |
| `upwork_get_job_details` | Get full details for a specific job URL |

### Proposals

| Tool | Description |
|------|-------------|
| `upwork_get_proposals` | List your submitted proposals (active/ended/archived) |
| `upwork_get_proposal_details` | Get cover letter, bid, and messages for a proposal |
| `upwork_submit_proposal` | Submit a new proposal to a job |
| `upwork_withdraw_proposal` | Withdraw an existing proposal |

### Messages

| Tool | Description |
|------|-------------|
| `upwork_get_messages` | List inbox conversations |
| `upwork_get_conversation` | Get full message history for a conversation |
| `upwork_send_message` | Send a message in a conversation |
| `upwork_get_unread_count` | Get count of unread messages |

### Contracts

| Tool | Description |
|------|-------------|
| `upwork_get_contracts` | List your contracts (active/ended/all) |
| `upwork_get_contract_details` | Get milestones, hours, and feedback for a contract |
| `upwork_get_work_diary` | Get work diary entries for a contract |

### Profile & Session

| Tool | Description |
|------|-------------|
| `upwork_get_my_profile` | Get freelancer profile info (name, rate, skills, etc.) |
| `upwork_get_connects_balance` | Get available connects count |
| `upwork_get_profile_stats` | Get total earnings, hours worked, jobs completed |
| `upwork_check_session` | Verify if the saved browser session is still valid |
| `upwork_close_session` | Close the browser connection and clean up |

---

## 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?
```

---

## CLI Reference

```
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

```
upwork-mcp/
├── pyproject.toml              # Package config (hatchling build)
├── README.md
├── LICENSE
├── .gitignore
├── src/upwork_mcp/
│   ├── __init__.py
│   ├── server.py               # MCP server entry point + CLI
│   ├── browser/
│   │   ├── __init__.py
│   │   ├── client.py           # Chrome CDP browser wrapper
│   │   ├── auth.py             # Interactive login flow
│   │   └── pages/
│   │       └── __init__.py     # Page selectors and helpers
│   ├── tools/
│   │   ├── __init__.py
│   │   ├── jobs.py             # Job search & details
│   │   ├── proposals.py        # Proposal management
│   │   ├── messages.py         # Inbox & messaging
│   │   ├── contracts.py        # Contracts & work diary
│   │   └── profile.py          # Profile, connects, stats
│   └── utils/
│       ├── __init__.py
│       ├── config.py           # Configuration management
│       └── logging.py          # Logging setup
├── 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/
│   ├── conftest.py
│   ├── test_browser.py
│   └── test_tools.py
└── uv.lock                     # Dependency lock file
```

### Run tests

```bash
uv run python scripts/test_all.py
```

### Build the package

```bash
uv build
```

---

## Troubleshooting

### Session expired

```bash
uvx upwork-mcp --login
```

### Cloudflare CAPTCHA appears during tool calls

Run with a visible browser so you can solve it manually:

```json
{
  "mcpServers": {
    "upwork": {
      "command": "uvx",
      "args": ["upwork-mcp", "--no-headless"]
    }
  }
}
```

### Chrome not found

Install the bundled Chromium:

```bash
uvx patchright install chromium
```

### "Not logged in" error

Your Upwork session expired. Re-run:

```bash
uvx 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.

---

## License

[Apache 2.0](LICENSE)
