waleeds.world
MCP · Tooling

I Wrapped the Upwork MCP in a CLI.
Here's why.

Upwork shipped an official MCP server. I put a deterministic command-line layer in front of it — so dashboards, automations and backends can build on it, not just agents.

By Waleed Ajmal· Aug 23, 2026· 5 min read Cross-posted to DEV.to
The upwork-cli README: a thin CLI wrapper over the official Upwork MCP server.
upwork-cli — a thin, deterministic wrapper over the official Upwork MCP server.

The official Upwork MCP is much more interesting than "Claude can now search Upwork."

It exposes actual Upwork functionality to agents: jobs, profiles, proposals, messages, contracts, client data, competitor bid information — and even write actions.

But there was one problem.

MCPs are designed for agents. I wanted something deterministic enough to build software on top of.

So I built a CLI around the official Upwork MCP.

Instead of asking an agent:

# fuzzy, non-deterministic
find me good n8n jobs

I can run something predictable:

upwork find_jobs search -p query=n8n --org talent

Same command. Same parameters. Structured output.

That distinction matters.

Why not just connect an agent to a frontend?

You technically can. But an agent is not a great API.

An LLM might choose a different tool, interpret the prompt differently, format its response differently, or make several unnecessary calls before getting the data you wanted.

That is useful when you want reasoning. It is annoying when your frontend just needs:

GET   jobs
GET   profile
GET   proposals
SEND  message

The CLI creates a deterministic layer between the MCP and everything else.

Upwork
   ↓
Official MCPCLI   ← deterministic layer
   ↓
API / Backend / Automations / Frontend

The agent can still sit on top when reasoning is useful. But it no longer needs to be in the middle of every operation.

This opens up much more interesting stuff

Once the MCP has a predictable interface, it stops being only an AI-assistant integration. You can build:

Dashboards

Search jobs and visualize proposal counts, client spend, hiring history, bid ranges and other signals.

Automations

Run searches every hour, score opportunities, route interesting jobs and generate alerts.

Freelancer analytics

Pull your profile, rates, work history, Connects, proposals and transactions into your own tools.

Agentic workflows

Let an agent analyze 20 jobs while deterministic commands handle actually fetching the data.

Actual applications

Put a backend in front of the CLI and suddenly the official MCP can power normal interfaces instead of only living inside Claude or another MCP client.


The CLI itself

It does its own OAuth 2.1 login (dynamic client registration + PKCE, tokens auto-refresh), then exposes every tool the server publishes through one generic dispatcher — nothing hardcoded, so it automatically covers any tool Upwork adds later.

# install
cd upwork-cli
npm install
npm link          # optional: puts `upwork` on your PATH

# authorize once — tokens persist & refresh
upwork login

Every tool and every action is a first-class command, generated live from the server's schemas, so coverage is always complete:

upwork commands                              # every tool + action, one screen
upwork find_jobs search -p query=n8n -p limit=5 --org talent
upwork get_profile get --org talent
upwork list_contracts search --org talent
upwork send_message send -p room_id=room_xxx -p text="Following up" --org talent

Write actions follow Upwork's own draft → confirm flow, and anything that binds money (accepting an offer, funding a milestone) still finalizes on upwork.com by design. The point is not to route around Upwork — it is to make the read/write surface callable from software.

One wording note. I am deliberately not saying "you can't build an API out of an agent." You can. The sharper, more defensible claim is this: an agent should not have to be your API.

Why this matters

MCP gives AI agents access to software. But once you put a deterministic layer around that access, the same infrastructure starts becoming useful for software itself.

The Upwork MCP is not just a new way to chat with Upwork. It is potentially a new programmable interface into Upwork — and that is the part I find most interesting.