Moxlade
Checking your account
View as Markdown

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