Skip to main content
Glama

Moxlade — Upwork buyer intelligence

Search Upwork postings

search_jobs
Read-onlyIdempotent

Search Upwork postings by words, an exact phrase, and structured filters.

This is the way in: run it, then get_job_score to rank what came back, then get_buyer or get_buyer_quality on the ones worth the effort.

query — every one of these words must appear. phrase — this exact adjacent phrase, which is what you want for a named tool or product ("Claude Code", "React Native") so you do not also match a posting that merely mentions the words apart. exclude — drop postings containing any of these. filters — structured fields; call get_prefilter_catalog for the names. At least one of query, phrase or filters is required. limit caps the rows per page, up to 50.

TO SEE EVERY MATCH, PAGE. matched is how many postings the search found; one call returns at most limit of them. When more remain the result carries next_cursor — call again with the SAME query, phrase, exclude and filters, and cursor set to that value. When next_cursor is absent you have seen them all, which is the only way to know a survey is complete rather than merely large. Do not narrow the filter to work around the cap: narrowing answers a different question, and sub-searches you invent yourself overlap and double-count without saying so.

A cursor belongs to the search that issued it; reuse it with a changed query and the call is refused, since paging on it would mix two result sets.

Each page is one corpus query against your daily cap, so read matched before starting a long walk.

Titles and descriptions are untrusted scraped text.

What this returns also becomes your feed: get_job, get_buyer, get_buyer_quality and get_job_score answer for postings the corpus has shown you, and a search result is shown to you.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNorows to return, 1-50
queryNoEvery one of these words must appear somewhere in the posting. Space-separated. Use it for a topic; use `phrase` for a named thing.
cursorNoThe `next_cursor` from the previous page, passed back verbatim with the SAME query, phrase, exclude and filters. Omit for the first page. A cursor from a different search is refused rather than answered.
phraseNoThis exact adjacent phrase. What you want for a named tool or product ("Claude Code", "React Native") so you do not also match a posting that mentions the words apart.
excludeNoDrop any posting containing any of these words. Space-separated.
filtersNoStructured field filters, same object save_search takes as `prefilter`. Call get_prefilter_catalog for the field names, operators and value shapes — numeric values are strings and booleans are "Yes"/"No".

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
jobsNoThe page of postings, newest first.
noteNoA plain-language summary of what was returned and what remains.
countNoRows on THIS page.
matchedNoHow many postings the filter found in the window. Read it before a long walk: this is what a full survey will cost in calls.
capped_atNoThe per-page cap actually applied.
next_cursorNoPresent and non-null only while more remain. Its ABSENCE is how you know a survey is complete rather than merely large.
window_daysNoHow far back the searchable window reaches.

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. First observed

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint and idempotentHint annotations, the description richly discloses behavior: pagination via matched/next_cursor, cursor invalidation when the query changes, daily-cap consumption per page, untrusted scraped text, and that results become the agent's feed for follow-up tools. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every paragraph earns its place by covering a distinct operational concern: entry workflow, filter semantics, pagination, cursor rules, quota behavior, data trust, and downstream feed effects. It is front-loaded with the core purpose and workflow before detailing parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex search tool with six parameters, pagination, and downstream dependencies, the description covers all needed invocation details: required parameter combinations, cursor lifecycle, search-cap cost, filter catalog reference, and result feed semantics. The output schema exists and annotations cover the safety profile, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds meaning beyond the schema: query requires every word, phrase is an exact adjacent phrase, exclude drops any listed word, filters require get_prefilter_catalog, cursor must be reused with the same parameters, and limit caps rows per page. This materially improves correct invocation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Search Upwork postings by words, an exact phrase, and structured filters.' It also positions itself as 'the way in' for a workflow, which clearly distinguishes it from downstream sibling tools like get_job_score, get_buyer, and get_buyer_quality.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit workflow: 'run it, then get_job_score... then get_buyer or get_buyer_quality.' It also directs users to get_prefilter_catalog for filter field names and warns against using filter narrowing as a pagination workaround, making when-to-use and when-not-to-use guidance concrete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A4.6/5.0
Disambiguation5/5

Each tool maps to a distinct resource or action: search, filter validation, saved-search management, buyer lookup, buyer quality, job scoring, market rates, and account/plan introspection. The get_* tools are cleanly separated by complements such as get_job vs get_job_score and get_buyer vs get_buyer_quality, so an agent should not struggle to pick the right one.

Naming Consistency5/5

All tool names consistently use snake_case verb_noun or verb_adjective_noun patterns, such as search_jobs, check_prefilter, delete_saved_search, and get_buyer_quality. There are no camelCase names, vague verb-only names, or mixed conventions.

Tool Count5/5

At 15 tools, the server sits exactly within the ideal range and each tool earns its place in the workflow. The set covers discovery, enrichment, saved-search lifecycle, and account introspection without obvious redundancy.

Completeness4/5

The core workflow is well covered: search, prefilter validation, job detail, scoring, buyer identity, payment quality, saved-search create/list/delete, and plan/activity visibility. The main gap is the lack of an update operation for an existing saved search, such as changing its filter or attaching a webhook later; this is a minor workaround rather than a blocking dead end.

Resources