Quickstart
Nothing to install. Three steps, and the third returns real postings.
1. Get in
Give your client the endpoint and sign in when it asks. It registers itself — no client id, no secret, nothing to paste. Claude and ChatGPT both do this.
If your client cannot run an authorization flow, mint a token at /connect and paste that instead. Both ways land on the same account: one plan, one trial, one history.
https://buyer.moxlade.com/mcp/The trailing slash matters: without it you get a redirect, and a client that does not replay a POST body across one fails in a way that looks like our bug.
2. Prove it works
get_plan takes no arguments, costs nothing against your caps, and answers on
every plan state — so it tells you the connection is good without spending
anything.
{
"name": "get_plan",
"arguments": {}
}{
"plan": "paid",
"state": "active",
"trial_ends_at": null,
"price_usd_month": 49,
"billing": "flat monthly, no credits, no per-call fee",
"saved_searches": "matching",
"subscribe": null,
"manage_or_cancel": "write to [email protected]",
"label": "glama-sandbox",
"usage": {
"calls_today": 45,
"daily_call_cap": 500,
"distinct_corpus_questions_today": 3,
"daily_distinct_corpus_question_cap": 120,
"resets_at": "UTC midnight",
"note": "repeating a corpus question you already asked today does not spend another distinct question; it still spends a call."
}
}Synthetic sandbox data — the shape is production's, the numbers are not.
You should get your plan, its state, and usage — today's calls against the
daily cap. If instead you get a 401, the token is wrong or missing; see
refusals, which explains why there are two different ones.
3. Your first real question
Same envelope, a different tool. This searches the live corpus:
{
"name": "search_jobs",
"arguments": {
"query": "Django",
"limit": 3
}
}{
"count": 3,
"matched": 3,
"capped_at": 3,
"window_days": 90,
"jobs": [
{
"upwork_id": "sbx01",
"title": "<untrusted-scraped-content>Senior Django engineer for an internal analytics API</untrusted-scraped-content>",
"description": "<untrusted-scraped-content>We need a Django REST API over an existing warehouse. Long term, part time.</untrusted-scraped-content>",
"url": "https://example.invalid/j/sbx01",
"date_posted": "2026-09-02T14:47:39.986313+03:00",
"skills": "Django, Python, PostgreSQL",
"price_type": "HOURLY",
"price": null,
"price_min": 55,
"price_max": 80,
"category_name": "Web, Mobile & Software Dev",
"subcategory_name": "Back-End Development",
"client_location": "Germany",
"total_spent": 412000,
"avg_hourly_rate": 62,
"buyer_payment_verified": true,
"client_total_hired": 61,
"client_total_applicants": 12
},
{
"upwork_id": "sbx02",
"title": "<untrusted-scraped-content>Django + HTMX dashboard, 3 week engagement</untrusted-scraped-content>",
"description": "<untrusted-scraped-content>Replace a spreadsheet workflow with a small internal dashboard.</untrusted-scraped-content>",
"url": "https://example.invalid/j/sbx02",
"date_posted": "2026-08-30T14:47:39.986313+03:00",
"skills": "Django, HTMX, Tailwind",
"price_type": "FIXED",
"price": 4200,
"price_min": null,
"price_max": null,
"category_name": "Web, Mobile & Software Dev",
"subcategory_name": "Full Stack Development",
"client_location": "United States",
"total_spent": 1870000,
"avg_hourly_rate": 48,
"buyer_payment_verified": true,
"client_total_hired": 148,
"client_total_applicants": 31
},
{
"upwork_id": "sbx08",
"title": "<untrusted-scraped-content>Small Django bug fix, one afternoon</untrusted-scraped-content>",
"description": "<untrusted-scraped-content>A migration is failing on deploy. We have the traceback.</untrusted-scraped-content>",
"url": "https://example.invalid/j/sbx08",
"date_posted": "2026-07-28T14:47:39.986313+03:00",
"skills": "Django, Python",
"price_type": "FIXED",
"price": 250,
"price_min": null,
"price_max": null,
"category_name": "Web, Mobile & Software Dev",
"subcategory_name": "Back-End Development",
"client_location": "Portugal",
"total_spent": 22000,
"avg_hourly_rate": 51,
"buyer_payment_verified": true,
"client_total_hired": 12,
"client_total_applicants": 6
}
]
}Synthetic sandbox data — the shape is production's, the numbers are not.
Read result.structuredContent: matched is how many postings exist for that
phrase, jobs is the page you got, and next_cursor is there while more
remain. Those postings are now in your feed, which is what lets get_buyer
and get_buyer_quality answer about them.
Where to go next
Workflows — the six sequences, with call order and cost. Start here if you know what you want to accomplish.
Filter reference — the filter language, if a phrase is not precise enough.
Tool reference — all 15 of them, with arguments and result fields.
Example prompts — if you would rather just ask your agent.