haraj-mcp
haraj-mcp is an MCP server that gives any MCP-aware agent 21 tools for searching, browsing, and inspecting listings on haraj.com.sa (Saudi Arabia's largest classifieds marketplace) in real time.
Discovery —
trending_keywords(top searches),search_suggest(search-box autocomplete),related_tags(cities-with-counts for a tag),live_streams(open live shopping streams).Feed / search —
fetch_feed(tag-based homepage/category feeds withbefore_update_datecursor pagination),search(keyword search with city/tag/date filters, geohashnear, image/video-only),promoted_posts(promoted carousel),sellers_list(sellers per tag).Post detail —
get_post_details(post + similar posts/images/offers, the canonical fetch-by-id),post_like_info(likes/follow state),comments,post_contact(contact text + mobile + WhatsApp flag),locker_shipment_offer(Locker shipping eligibility/price).User —
user(full profile: rating, followers, badges, location history),is_following_user,follow_user(mutation, toggles follow),user_mention_suggestions.Account —
notes(notifications, optionally mark read),outgoing_buy_requests(escrow history),is_following_tag,check_auth(validate.envJWT/lastRequestId and report expiry).Result shaping — feed/search/promoted tools default to a compact post summary (
id,title,price_sar,url,city, up to 3thumb_urls,image_count, tags) and acceptfull=Truefor the entire Post object; thumb URLs can be passed to a vision tool to view photos.Practical use — supports multi-step agent workflows such as "find an RTX 4090 deal" (search → detail → seller → contact → shipping) and answers natural-language questions about live marketplace listings, trending terms, and sellers. Uses authenticated haraj GraphQL + livestream endpoints, with tools annotated for read-only/mutating behaviour.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@haraj-mcpwhat's trending on haraj today?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
haraj-mcp
A Model Context Protocol (MCP) server for haraj.com.sa — the largest classified-ads marketplace in Saudi Arabia.
This server exposes 21 tools to any MCP-aware agent (Claude Desktop, Cursor, opencode, Zed, etc.) so it can search and fetch marketplace listings in real time, no copy-paste of curl commands required.
All tools mirror the real haraj.com.sa operations captured from a live browser session (2026-08-17). No hallucinated filters — every argument matches what the live front end actually sends in its GraphQL calls.
Claude Desktop / Cursor / opencode
│
│ MCP (JSON-RPC over stdio)
▼
┌──────────────┐
│ haraj-mcp │ ── HTTPS ──▶ graphql.haraj.com.sa
│ (Python) │ + livestream.haraj.com.sa
└──────────────┘Tools exposed (21)
Discovery
Tool | Purpose |
| Top trending search terms (default 7 days) |
| Live search-box autocomplete (top 10) |
| Cities-with-counts for a given tag |
| Currently-open haraj live shopping streams |
Feed / search
Tool | Purpose |
| Tag-based feed (homepage + category pages). |
| Keyword search. |
| Promoted-post carousel for a tag |
| Sellers per tag (real estate etc.) |
Post detail
Tool | Purpose |
| Post + 3 related groups (via the real |
|
|
| Comment list |
|
|
|
|
User
Tool | Purpose |
| Full profile (rating, followers, location history, badges) |
| bool |
| Mutation: toggles follow |
| For @-mentions |
Account
Tool | Purpose |
| Notifications (the bell icon) |
| "Buy with confidence" escrow history |
| bool |
| Verify |
For fetch_feed, promoted_posts, and search, pass full=True to get the entire Post object instead of a compact summary. The compact summary has these keys:
{
"id": 185926519,
"title": "...",
"price_sar": 650.0,
"price_display": "650 SAR",
"url": "https://haraj.com.sa/...",
"city": "الشرقيه",
"geo_city": "الدمام",
"post_date": 1785729404,
"has_image": true,
"image_count": 3,
"thumb_urls": [
"https://mimg6cdn.haraj.com.sa/.../a.jpg",
"https://mimg6cdn.haraj.com.sa/.../b.jpg",
"https://mimg6cdn.haraj.com.sa/.../c.jpg"
],
"tags": ["شاشات", "..."],
"has_price": true
}The compact result includes up to 3 image URLs (thumb_urls). Pass any of those URLs to your vision tool to view the post's photos. For posts with more than 3 images, the rest are in the full Post object (full=True) or in get_post_details(post_id) — image_count tells you the total.
Related MCP server: opensooq-mcp
Install
cd /mnt/W/Desktop/Software/haraj-mcp
pip install -e .This installs the haraj-mcp console script on your PATH.
Configure auth
cp .env.example .env
# Edit .env and paste your HARAJ_JWT and LAST_REQUEST_ID.How to get fresh values (they expire every ~10 days):
Open https://haraj.com.sa in Chrome and log in.
F12 → Network tab → click any
graphql.haraj.com.sarequest.In Headers, copy
authorization(starts withBearer eyJ…) andlastRequestId.Paste into
.envand restart the MCP server.
You can verify with check_auth — it returns the JWT's exp claim and seconds_remaining.
Wire into your MCP client
opencode / Claude Desktop / Cursor
Add this to your client's MCP config (usually ~/.config/opencode/opencode.json, ~/Library/Application Support/Claude/claude_desktop_config.json, or ~/.cursor/mcp.json):
{
"mcpServers": {
"haraj": {
"command": "haraj-mcp",
"cwd": "/mnt/W/Desktop/Software/haraj-mcp"
}
}
}The server reads .env from cwd, so secrets stay in the project directory and don't leak into your MCP client config.
Custom .env location
Set HARAJ_MCP_ENV=/path/to/.env in the env block of the MCP config.
Example agent prompts
Once wired in, your agent can answer:
"What's trending on haraj today?"
"Fetch the latest 20 posts in
حراج السيارات(the cars category)."
"Search haraj for
RTX 4090in the last week (during_date=1week)."
"Get the seller's profile and all their current listings for post_id=185354313."
"What shipping fee do I pay if I buy this post via Locker?"
"What are people typing in the search box after
شاشة?"
"List all open live shopping streams right now."
Run without an MCP client (debug)
Pipe JSON-RPC messages directly into the server:
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0"}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_regions","arguments":{}}}' | python -m haraj_mcpTests
python tests/test_smoke.py12 tests cover: tool registration (21 tools), live version URL, sec-ch-ua-platform-version header, initalChars typo preservation, real search variables, compact serializer shape, JWT validation (valid/expired/malformed), check_auth error handling, a full stdio end-to-end test, tool annotations (all four hints declared as booleans on every tool), and JSON-schema descriptions on every tool parameter.
Agent guide
For a per-tool "what is this used for" reference (and example agent workflows), see docs/AGENT_GUIDE.md. It explains:
The 21 tools organized by use case (discovery, feed/search, post detail, user, account)
Common multi-step workflows (e.g. "find me a deal on an RTX 4090" → 5 chained tool calls)
Pagination cheatsheet (which tools use which cursor)
Privacy / safety notes (which tools return sensitive data like IBANs and mobile numbers)
Conversation snippets showing the agent calling tools
Share docs/AGENT_GUIDE.md with the LLM client (or use it as a reference when writing system prompts).
Project structure
haraj-mcp/
├── pyproject.toml
├── README.md
├── LICENSE
├── .env.example
├── src/haraj_mcp/
│ ├── __init__.py
│ ├── __main__.py # entry point: `python -m haraj_mcp`
│ ├── server.py # FastMCP setup, 21 tool registrations
│ ├── tools.py # the 21 tool implementations
│ └── auth.py # .env reader + JWT validation
├── haraj/ # GraphQL client (captured from live haraj.com.sa)
│ ├── client.py
│ ├── models.py
│ ├── queries.py # 20 exact-captured query strings
│ ├── constants.py
│ ├── auth.py
│ └── images.py
└── tests/test_smoke.pyWhat changed in v0.2.0
v0.1.0 had 4 tools (search_haraj, get_post, list_regions, check_auth) that I had hallucinated from the live GraphQL schema — many of the supported filters were never used by the real site.
v0.2.0 replaces them with 21 tools that mirror the actual operations haraj.com.sa uses. Captured from a real browser session on 2026-08-17 (219 requests, 173 GraphQL POSTs). The key fixes:
searchno longer has hallucinated filters (carExtraInfo,priceRange,userLocation,notTag,authorUsername); only the variables the live site actually sends (search,cities,city,tag,tags,page,limit,onlyWithImage,onlyWithVideo,hideShowRooms,orderByPostId,duringDate,near)searchSuggestpreserves the live wire's typoinitalChars(the server requires it)The
versionURL param bumped to2026-08-11 22(was2026-08-03 15)Added
sec-ch-ua-platform-versionheader (sent on every live call)ViewOptionshasmustLoginToView(only present onpostsop)New
live_streamstool for the non-GraphQLlivestream.haraj.com.saendpointget_post_detailsnow uses the propersimilarPosts(id:)endpoint (not the ID-as-keyword hack)
What changed in v0.3.0
Compact post results now include up to 3 image URLs (thumb_urls) plus an image_count field. The agent can pass any of those URLs to its vision tool to view the post's photos. For posts with more than 3 images, the rest are available via full=True (entire Post object) or get_post_details(post_id). The cap of 3 keeps the listing response small (a typical photo is 200-500 KB; 3 URLs ≈ 1-2 KB of metadata).
What changed in v0.4.0
Every tool now declares all four MCP tool-annotation hints (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) as explicit booleans, so hosts can reason about and warn on tool behaviour (and OpenAI's directory accepts the server). Read-only tools are marked readOnlyHint=true; notes and follow_user are marked as mutating, and check_auth is marked local-only (openWorldHint=false). Added an MIT LICENSE file.
What changed in v0.5.0
Every tool parameter now carries a human-readable description in its JSON schema (via Annotated[..., Field(description=...)]), taking schema description coverage from 0% to 100% across all 52 parameters. This raises the Glama TDQS score for tools that were previously penalized for bare parameter schemas.
License
MIT — see LICENSE.
Available Tools
21 toolscheck_authARead-onlyIdempotent
Verify the JWT and lastRequestId in .env are still valid. Returns {ok, expires_at, seconds_remaining, user_id} or {ok: false, error} if the JWT is missing or expired.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, and openWorldHint=false. The description adds useful behavior: it returns {ok, expires_at, seconds_remaining, user_id} or {ok: false, error} when the JWT is missing or expired. It does not clarify failure behavior for an invalid lastRequestId, so it stops short of full transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: the first states the purpose, the second states the return shape and error case. It is front-loaded, precise, and every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description competently describes the return object and error object. However, it only mentions the error case for a missing or expired JWT, leaving the failure behavior for an invalid lastRequestId unspecified. This is a minor but real gap for a tool that claims to verify both values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so parameter semantics are not applicable and the baseline is 4. Mentioning JWT and lastRequestId from .env provides useful context but does not describe any input parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Verify the JWT and lastRequestId in .env are still valid.' It clearly distinguishes the tool from unrelated social-media siblings and tells the agent exactly what operation is performed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the phrase 'still valid,' suggesting a pre-flight or session-check context, but the description provides no explicit when/when-not guidance or alternatives. For a zero-parameter auth check, this is minimally viable but leaves the agent to infer timing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
commentsCRead-onlyIdempotent
Comment list for a post. Required: post_id. Optional: page, oldest_first (default true).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Zero-based page index. | |
| post_id | Yes | Haraj post id. | |
| oldest_first | No | Return oldest comments first (false = newest first). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is fully covered elsewhere. The description adds nothing beyond that: no pagination limits, no ordering caveats, no indication of how many comments are returned per page.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short fragments, fully front-loaded, with zero filler. It is terse to the point of omitting useful context, but every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with a complete input schema and no output schema, this is minimally adequate. However, return shape and pagination behavior across pages are left entirely unexplained, which an agent needs to page correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description merely restates required/optional status and the oldest_first default, which the schema already documents, adding no new semantic meaning such as the page size or ordering interaction.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource and action: a comment list scoped to a post. An agent can tell it retrieves comments rather than posts or users, though it does not name a sibling tool or contrast with get_post_details which might also surface comment data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description only implies usage through the required post_id mention. It offers no when-to-use guidance, no prerequisites (e.g. auth or post visibility), and no pointer to an alternative if a different comment view is wanted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_feedARead-onlyIdempotent
Fetch the post feed for a tag (the homepage + category pages). Required: tag (Arabic category name like 'حراج السيارات' or 'حراج الأجهزة'). Optional: city (Arabic region like 'الشرقيه'), cities (list of regions), page (default 0), limit (default 21), before_update_date (Unix seconds cursor — pass the last item's updateDate to get the next page), only_with_image (default true), only_with_video (default false), order_main_by_post_id (default false), full (return full Post objects, default false = compact). Returns {count, has_next_page, view_options, posts}.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | Yes | Arabic category/tag name, e.g. 'حراج السيارات' (cars) or 'حراج الأجهزة' (devices). | |
| city | No | Single Arabic region name to filter by, e.g. 'الشرقيه'. | |
| full | No | Return full Post objects instead of compact summaries. | |
| page | No | Zero-based page index. | |
| limit | No | Number of posts to return (clamped to 1-100). | |
| cities | No | List of Arabic region names to filter by (multi-city). | |
| only_with_image | No | Only return posts that have at least one image. | |
| only_with_video | No | Only return posts that have a video. | |
| before_update_date | No | Pagination cursor in Unix seconds — pass the last item's updateDate to get the next page. | |
| order_main_by_post_id | No | Order the main feed by post id instead of update date. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description still adds real value beyond that: it discloses the return shape {count, has_next_page, view_options, posts}, the cursor contract, and several non-obvious defaults (only_with_image=true, limit=21).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One dense but front-loaded block: purpose first, then required parameter, then optional parameters, then return shape. For ten parameters this is compact, though the run-on parameter list is harder to scan than a short list would be.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description correctly compensates by naming the top-level response keys and the pagination field, and it covers the required tag plus every optional flag. An agent has enough to call and page through this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter is already documented in the schema and the baseline is 3. The description largely restates those defaults and only adds the Cursor mechanics, which the schema also carries.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Fetch the post feed for a tag') and adds domain scope ('the homepage + category pages'), so an agent immediately knows this is category-browsing rather than a keyword query. It never names or contrasts a sibling such as 'search' or 'promoted_posts', which is the only thing keeping it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the tag-based framing and the pagination hint ('pass the last item's updateDate to get the next page') tell an agent how to page, but not when to choose this over 'search' or 'promoted_posts'. No exclusions or prerequisites are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
follow_userA
Follow (or unfollow) a user. Required: username. Returns the new is_following state.
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes | Haraj username to follow/unfollow. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the write/idempotent/open-world profile, so the bar is lower, and the description adds real value beyond them: it discloses that the result is the new is_following state (no output schema exists to carry this) and that repeated calls toggle rather than set, which is exactly why idempotentHint=false. It still says nothing about idempotency-adjacent edge cases like following yourself or rate limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with what the tool does and the toggle semantics, with no filler. The 'Required: username' clause mildly duplicates the schema's required array, which is the only small redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with a full annotation set, the description covers the verb, the toggle semantics, the required input, and the return value (important given no output schema). Nothing an agent needs in order to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single parameter is documented in the schema itself ('Haraj username to follow/unfollow'), so the schema does the heavy lifting. The description restates that username is required but adds no format, casing, or identifier-type detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb pair and resource ('Follow (or unfollow) a user'), which is the key detail an agent needs since the operation is a state toggle rather than an absolute set. It does not explicitly name the sibling it is not, such as is_following_user, but the verb+resource pair is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the verb itself, and the toggle behavior hints at the condition under which it flips state, but there is no explicit guidance on when to call this versus the read-only sibling is_following_user, nor any mention of prerequisites such as authentication or target-user existence.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_post_detailsARead-onlyIdempotent
Fetch a post + 3 related groups (similar posts in the same tag/city, similar images, related offers). This is the canonical 'fetch by id' — there is no direct getById operation in the GraphQL API. Required: post_id. full (default true = full similarPosts response).
| Name | Required | Description | Default |
|---|---|---|---|
| full | No | Return the full similarPosts response instead of a summary. | |
| post_id | Yes | Haraj post id, e.g. 185926519. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the bar is lower, and the description still adds real value: it discloses that the response bundles three categories of related data and that 'full' toggles between the full similarPosts response and a summary. It omits cost/size implications of that bundling, but the response-shape disclosure goes beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with what is returned and the canonical-id framing, then the required parameter, then the flag behavior. No filler, no repetition of the tool name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the return-shape burden and does so by enumerating the post plus the three related groups, and it explains the one non-obvious flag. Only minor gaps remain, such as pagination or response size for the full mode.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented with types, defaults, and an example id, making 3 the baseline. The description's note that full defaults to true and controls similarPosts verbosity largely restates the schema rather than adding meaning beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Fetch) and resource (a post) plus the exact payload shape: post + three related groups (similar posts by tag/city, similar images, related offers). It also preempts confusion with siblings by declaring itself the canonical 'fetch by id' operation, so an agent can distinguish it from post_contact, post_like_info, or comments without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Tells the agent this is the canonical by-id retrieval path and notes there is no direct getById in the GraphQL API, which answers the 'when do I use this' question. It does not, however, name sibling alternatives or state exclusions (e.g., use comments/post_contact for those resources), so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
is_following_tagARead-onlyIdempotent
True/false whether the authenticated user follows tag.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | Yes | Arabic tag name to check the authenticated user's follow status for. | |
| city | No | Optional Arabic region name to scope the check. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description usefully adds that the result is a true/false boolean scoped to the authenticated user, which compensates for the absent output schema, but it says nothing about failure modes, missing tags, or unauthenticated behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, front-loaded sentence that states the check and the return type with no filler. Nothing could be cut without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter boolean read tool with full schema coverage and rich annotations, the description covers the essentials, including the return type that would otherwise be missing without an output schema. Only the optional city scoping and edge-case behavior go unmentioned.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with both `tag` (required, Arabic tag name) and `city` (optional scoping region) fully documented in the schema. The description adds nothing about parameters, so the baseline 3 applies; notably it never hints that a city scoping option exists.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific check (follow status of a tag) and even names the return value (true/false), which is more than a tautology. It implicitly separates itself from sibling is_following_user by specifying a tag rather than a user, though it never names or contrasts that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the purpose – an agent reading it knows to call it when it needs a boolean follow check for a tag. However, there is no explicit when-to-use, no when-not-to-use, and no mention of alternatives such as is_following_user or related_tags.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
is_following_userBRead-onlyIdempotent
True/false whether the authenticated user follows username.
| Name | Required | Description | Default |
|---|---|---|---|
| username | Yes | Haraj username to check. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is fully covered. The description adds one genuinely useful behavioral detail, that the relationship is evaluated from the authenticated user's perspective, but says nothing about behavior for nonexistent users or whether an auth failure is surfaced as an error.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with zero filler, front-loading the return type and the subject of the query. Nothing could be removed without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter boolean predicate with no output schema, the description tells the agent what it returns (true/false) and whose perspective it uses, which is enough to call it correctly. Minor gaps remain around auth requirements and unknown-user behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single `username` parameter is already documented in the schema as a Haraj username. The description merely echoes the parameter name, adding no format or resolution semantics beyond it, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific predicate (true/false) over a specific resource (follow relationship between the authenticated user and `username`). It is clearly distinguishable from the mutation sibling `follow_user` by the boolean framing, though it never names that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no stated preconditions (e.g. must be authenticated), and no routing to alternatives such as `follow_user` or `is_following_tag`. Usage is only inferable from the predicate wording.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
live_streamsBRead-onlyIdempotent
Currently-open haraj live shopping streams. Non-GraphQL REST endpoint. Returns [{id, title, cover_url, streamer, num_messages, num_viewers, started_at}]. limit (default 40; the server caps it).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of streams to return (the server caps it). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and openWorld behavior, so safety is covered. The description adds the returned field list and the server-side cap on limit, but says nothing about auth requirements, pagination, error behavior, or what happens if no streams are live.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short, front-loaded sentences with no filler; the resource and return shape come first. 'Non-GraphQL REST endpoint' is the one line of marginal value to an agent, but it costs almost nothing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by naming the return fields, and the single optional parameter is fully covered by the schema. For a simple read-only list tool this is nearly sufficient, though it omits empty-result and auth context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the single limit parameter is already documented with its default and server cap. The description only restates this, adding no syntax, range, or edge-case guidance beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific resource and scope: 'currently-open haraj live shopping streams', which is clearly distinct from siblings like fetch_feed, trending_keywords or promoted_posts. No explicit verb ('list') and no direct sibling callout, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'currently-open' qualifier implies when the data is relevant, but there is no when-to-use guidance, no exclusions, and no mention of alternatives for closed streams or other feed tools. The agent must infer routing entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
locker_shipment_offerCRead-onlyIdempotent
{offerId, isEligible, price} for a post's Locker shipping option. Required: post_id.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | Haraj post id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and no destructiveness, so the safety profile is covered structurally. The description adds nothing beyond that — no info on whether the offer is live, cached, region-dependent, or what triggers eligibility. For an openWorldHint tool, the external-dependency behavior is undisclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is short, but the leading curly-brace fragment is undecodable without reading the name and reads like an internal note rather than a front-loaded purpose statement. Brevity here comes at the cost of clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read tool with no output schema, the description should at least confirm that it returns an offer object and state its meaning. Instead it leaves the action, the domain concept, and the return semantics all implicit, which is insufficient even for a one-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter 'post_id' is documented ('Haraj post id.'). The description only repeats the requirement without adding format, valid-range, or sourcing detail — baseline 3 applies when the schema carries the load.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a literal return-shape stub ('{offerId, isEligible, price}') rather than stating a verb and resource. It never says what the tool actually does — retrieve or request a Locker shipping offer for a post. An agent must infer the action from the name alone, and no sibling is differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The only guidance is 'Required: post_id,' which restates the schema's required field. There is no indication of when to call this versus get_post_details or other post-related siblings, and no context about what a 'Locker shipping option' means in the domain.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notesBIdempotent
User notifications (the bell icon). set_read (default false) marks them as read on the server.
| Name | Required | Description | Default |
|---|---|---|---|
| set_read | No | Mark the notifications as read on the server. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=true, and openWorldHint=true, so the mutation profile is covered structurally. The description adds that set_read persists the change 'on the server', which is a modest but real behavioral detail beyond the annotations. It does not describe volume, ordering, or return shape.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, no filler. The resource identification is front-loaded and the parameter behavior follows immediately. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read/mark-read tool with no output schema, the description covers the essentials but omits what the tool returns (notification list shape, counts, pagination) and any usage context. Adequate but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for the single set_read parameter, and the description largely mirrors the schema ('marks them as read on the server') plus the default. Baseline 3 applies since the schema already documents the parameter fully and the description adds no syntax or semantics beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The name 'notes' is opaque, but the description corrects this immediately with a specific resource: 'User notifications (the bell icon)'. It also names the optional mutation behavior via set_read. No sibling tool covers notifications, so no further differentiation is needed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description never says when to call this tool, in what context (e.g., polling for user activity), or what alternatives exist among the many sibling tools. Nothing beyond the implied 'use this to see notifications' is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
outgoing_buy_requestsBRead-onlyIdempotent
'Buy with confidence' (وساطة) escrow requests the user has placed. Optional: page (default 0).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Zero-based page index. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so the safety and side-effect profile is fully covered. The description adds only the pagination default, which the schema already documents. Given annotations carry the behavioral burden, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Very short, front-loaded with the resource identity and followed by the optional pagination note. No wasted sentences, though the branded parenthetical is slightly ornamental.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-param read tool with full annotation coverage and no output schema, the description is minimally sufficient. It doesn't indicate ordering, result shape, or pagination limits, but none of that is strictly required given the annotations and simple schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single param ('page') has a documented 'Zero-based page index.' description. The description merely repeats the default. Baseline 3 applies since the schema does the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (outgoing buy/escrow requests placed by the user) with a clear directional scope. The Arabic gloss '(وساطة)' and 'Buy with confidence' branding add texture, but it's clear this is a read of the user's own escrow requests. It does not explicitly differentiate from siblings, most of which are unrelated anyway.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implied usage as a listing of the current user's outgoing escrow requests, but no explicit when-to-use or when-not-to-use guidance, and no alternative tool is named. Adequate but with a clear gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_contactCRead-onlyIdempotent
{contactText, contactMobile, shouldEnableWhatsApp} for a post. Required: post_id.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | Haraj post id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and idempotentHint=true, so the description should clarify it's a safe read. However, the description's format ('{...} for a post') resembles a mutation payload, which could confuse. It adds no behavioral context beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is terse but poorly structured. The brace notation is confusing and the required parameter is tacked on at the end without clear separation. It lacks a clear statement of purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with a single parameter and no output schema, the description should at least state what information it returns (contact details). Instead, it's ambiguous and provides no context about the tool's behavior or output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%; post_id is fully documented in the schema. The description lists related fields but since only post_id is a parameter, it adds minimal value beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description does not state what the tool does. It lists fields in braces and says '{contactText, contactMobile, shouldEnableWhatsApp} for a post' without a verb like 'get' or 'retrieve'. An agent cannot confidently determine the tool's action from this.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives like get_post_details or comments. The description is purely a field listing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_like_infoCRead-onlyIdempotent
{is_like, total, is_following} for a post. Required: post_id.
| Name | Required | Description | Default |
|---|---|---|---|
| post_id | Yes | Haraj post id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint, so the safety profile is covered. The description adds value by enumerating the returned fields ({is_like, total, is_following}) in the absence of an output schema, but it does not clarify whose like status is returned or any auth requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is a single, front-loaded sentence with no filler, and the required parameter is flagged clearly. The telegraphic style borders on under-specification rather than excess, but nothing wasteful is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter read tool this is adequate: the return fields are enumerated despite there being no output schema, and the required input is stated. It still leaves the semantics of is_like/is_following (presumably relative to the authenticated user) unexplained, which a caller may need.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single post_id parameter is fully documented in the schema as 'Haraj post id.', so the description's 'Required: post_id' adds nothing new. Baseline 3 applies when the schema already carries the parameter meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (a post) and the data it exposes ({is_like, total, is_following}), so an agent can infer it reads like/engagement status. However, it never states a verb like 'get' or 'retrieve' and offers no differentiation from siblings such as comments or get_post_details, leaving the operation type to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance at all: no indication of when this is preferable to get_post_details, comments, or other post-related siblings. The only usage-like content is a restatement of the required parameter, which does not tell the agent when to select this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
promoted_postsBRead-onlyIdempotent
Fetch the promoted-post carousel for a tag. Required: tag. Optional: city. Returns {count, posts}.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | Yes | Arabic tag name for the promoted carousel, e.g. 'حراج الأجهزة'. | |
| city | No | Arabic region name to filter by. | |
| full | No | Return full Post objects instead of compact summaries. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the safety profile is covered. The description adds the return shape '{count, posts}', which is genuinely useful given no output schema. It says nothing about rate limits, auth, or pagination, so it is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences, front-loaded with the verb and resource, no filler. The 'Required/Optional' clause mildly duplicates the schema, which prevents a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, describing the return payload is the right instinct and it is partially done. However, the description omits the third parameter 'full' and its effect on the return shape, which is the one piece of behavior an agent most needs for this fetch tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both the Arabic tag/region semantics and the 'full' flag are already documented in the schema; baseline 3 applies. The description arguably goes backwards by implying the return is always '{count, posts}' when full=true yields full Post objects.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: 'Fetch the promoted-post carousel for a tag.' That is concrete enough for an agent to know what comes back. It stops short of distinguishing itself from look-alike siblings such as fetch_feed or live_streams, which is the only thing keeping it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no statement of when to use this tool versus alternatives like fetch_feed or search. 'Required: tag. Optional: city.' only restates the schema's required/optional structure rather than giving selection guidance. An agent must infer the use case entirely.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchARead-onlyIdempotent
Search haraj by keyword. Required: keyword. Optional: cities (list), city, tag, tags (list), page, limit, only_with_image (default true), only_with_video (default false), hide_show_rooms (default false), order_by_post_id (default false), during_date ('1days'|'3days'|'1week'|'1months'), near ('@lat,lon' e.g. '@26.4336,50.1116'), full (default false = compact). Returns {keyword, count, has_next_page, view_options, posts}.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | Restrict the search to a single Arabic tag. | |
| city | No | Single Arabic region name to filter by. | |
| full | No | Return full Post objects instead of compact summaries. | |
| near | No | Geohash location filter like '@26.4336,50.1116'. | |
| page | No | Zero-based page index. | |
| tags | No | Restrict the search to a list of Arabic tags. | |
| limit | No | Number of posts to return (clamped to 1-100). | |
| cities | No | List of Arabic region names to filter by. | |
| keyword | Yes | Search keyword (Arabic or English), e.g. 'RTX 4090' or 'شاشة'. | |
| during_date | No | Time window: '1days', '3days', '1week', or '1months'. | |
| hide_show_rooms | No | If true, hides dealer posts (real-estate filter). | |
| only_with_image | No | Only return posts that have at least one image. | |
| only_with_video | No | Only return posts that have a video. | |
| order_by_post_id | No | Order results by post id instead of relevance/date. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this as a safe, read-only, idempotent, open-world read. The description adds material context beyond that: the compact-vs-full return mode and the exact return envelope ({keyword, count, has_next_page, view_options, posts}), which tells the agent what to expect back. It still omits pagination semantics (page/count interaction) and rate-limit behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the purpose well and stays compact, but then enumerates all 14 parameters with their defaults, which duplicates a schema that already carries 100% description coverage. That parameter dump is largely non-earning text where a pointer to the schema would have sufficed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 14 parameters, no output schema, and no enum declarations, the description supplies the missing return shape and confirms default behaviors, which is enough for an agent to call it correctly. Minor gaps remain around pagination/has_next_page semantics and relative ordering when order_by_post_id is false.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are already fully documented by the schema, including defaults, ranges (limit 1-100), and the during_date and near formats. The description largely restates those same parameters and formats, adding no new semantics, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Search haraj by keyword') and enumerates the filterable dimensions, so an agent immediately knows this is the keyword-driven post search. It does not, however, distinguish itself from siblings like search_suggest or trending_keywords, which also touch search/query concepts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the required/optional split and the parameter list, but there is no explicit when-to-use guidance, no exclusions, and no reference to alternative tools such as search_suggest for query discovery or fetch_feed for browsing. An agent must infer context from the schema alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_suggestARead-onlyIdempotent
Live search-box autocomplete. Returns the top 10 suggestions for a typed prefix. Required: prefix (e.g. 'شاشة'). Optional: tag.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | Optional Arabic tag to scope the suggestions. | |
| prefix | Yes | Text typed in the search box, e.g. 'شاشة'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive, open-world behavior, so the safety profile is covered. The description adds a genuine behavioral trait beyond that: the result is capped at the top 10 suggestions, which tells the agent to expect a bounded, ranked list. It doesn't mention rate limits or auth needs, keeping it below 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with zero filler; the core purpose leads and the parameter summary follows. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter, read-only lookup with full schema coverage and no output schema, the description supplies enough: what it returns (top 10), scoping (prefix, optional tag), and the safe-read nature via annotations. Only the absence of guidance against sibling tools keeps it from 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — both `prefix` and `tag` are documented in the schema with the same Arabic example ('شاشة') the description repeats. The description therefore adds no meaning beyond what the schema already provides, which is the baseline-3 case.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: 'Live search-box autocomplete' that 'Returns the top 10 suggestions for a typed prefix.' That is unambiguous. It does not, however, distinguish itself from siblings such as search, trending_keywords, or related_tags, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Live search-box autocomplete' implies the usage context (as-you-type prefix matching) but never states when to prefer this over the sibling `search` tool or when it is inappropriate. Usage is inferable, not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sellers_listCRead-onlyIdempotent
Sellers for a tag (used by real-estate / business / investment pages). Required: tags (list of Arabic tag names).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Zero-based page index. | |
| tags | Yes | List of Arabic tag names (real-estate/business/investment pages). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is fully covered. The description adds only the 'Arabic tag names' input constraint and the domain hint, but says nothing about result volume, pagination behavior, or the open-world data source.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the resource and scoping key, then the required-input fact. No filler, though the domain parenthetical is somewhat ambiguous about which repository of sellers it refers to.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description ideally would hint at what a 'sellers' result contains and how paging works. It supplies the input constraint and usage domain but leaves the return shape and pagination semantics unstated, so it is adequate but incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: the page parameter is documented as a zero-based index and tags as a list of Arabic tag names. The description merely restates the required tags argument, adding no format, limits, or semantics beyond the schema. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Sellers for a tag" names the resource and its scoping key, which lets an agent infer it lists sellers associated with a given tag. However it is a noun fragment with no explicit verb and no comparison to related tools such as related_tags or user, so the boundary is only weakly drawn.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical '(used by real-estate / business / investment pages)' gestures at context but never states when to call this tool versus alternatives, nor any prerequisites or exclusions. An agent gets no routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
trending_keywordsBRead-onlyIdempotent
Top trending search terms over the last N days. range_in_days (default 7). Returns [{keyword, score}].
| Name | Required | Description | Default |
|---|---|---|---|
| range_in_days | No | Look-back window in days (default 7). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description usefully adds the return payload shape ([{keyword, score}]) and the default window, which matters because there is no output schema, but it says nothing about volume, rate limits, or ordering guarantees.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the resource and scope, then the parameter note, then the return shape. Efficient, though the parenthetical default duplicates the schema and could be dropped.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter read-only tool with full annotation coverage, the description supplies the one thing structured fields don't: the return shape. Nothing critical for correct invocation appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the sole parameter is fully documented in the schema, including its default. The description merely repeats the default value and adds no format, range, or semantics beyond it, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (top trending search terms) and scope (last N days), which distinguishes it from near-neighbors like search_suggest and related_tags. It stops short of explicitly naming a sibling it replaces, so it lands just below the top band.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use or when-not-to-use guidance is given, and no alternative tool is named. An agent must infer that this is the discovery/trending path rather than the query-suggestion path (search_suggest) purely from the wording.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
userARead-onlyIdempotent
Full user profile (rating, followers, location history, badges). Pass either username (URL-encoded Arabic works) or user_id. rating_summary_only (default false) returns just the rating block.
| Name | Required | Description | Default |
|---|---|---|---|
| user_id | No | Numeric Haraj user id (alternative to username). | |
| username | No | Haraj username (URL-encoded Arabic is accepted). | |
| rating_summary_only | No | Return only the rating block instead of the full profile. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and openWorldHint, so the agent knows this is a safe, repeatable read. The description adds the notable behavioral detail that rating_summary_only defaults to false and returns just the rating block, but doesn't disclose auth requirements, rate limits, or whether the profile is public/private. With annotations covering safety, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact sentences, front-loaded with what the tool returns, followed by parameter guidance and the summary flag behavior. No wasted words, though the parenthetical badge list is slightly dense.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only profile retrieval tool with 100% schema coverage and annotations carrying safety, the description is complete enough. It covers what is returned, how to identify the user, and a key output mode. Missing only edge-case behavior like errors for nonexistent users, but that is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all three parameters in detail. The description reinforces the username/user_id alternative and the rating_summary_only behavior, but adds no syntax or format details beyond the schema. Baseline 3 is correct when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (full user profile) and enumerates its contents (rating, followers, location history, badges), which is a clear verb-less but content-rich purpose. It doesn't explicitly distinguish itself from siblings like is_following_user or user_mention_suggestions, but the 'full profile' framing implies retrieval.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says to pass either username or user_id, which is genuine usage guidance, but it doesn't say when to use this tool versus alternatives like is_following_user or user_mention_suggestions. Usage is implied for profile retrieval but no exclusions or alternative routing is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
user_mention_suggestionsARead-onlyIdempotent
Recent @-mention candidates for the comment / DM composer. Returns [{userId, username, handler}].
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the full safety profile (readOnly, idempotent, non-destructive, openWorld), so the description's contribution is the result shape and the recency scoping implied by "recent." It does not disclose count, pagination, or the source of "recent," so it adds only modest context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero filler; the purpose is front-loaded before the return shape. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and no output schema, the description supplies the essential return shape it needs to. It is nearly complete, though it leaves the recency window and result count unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is nothing for the description to clarify and the baseline of 4 applies. The result-shape note is a bonus rather than compensation for a coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (@-mention candidates) and scopes it to the comment/DM composer, making the intent clear without opening the schema. It does not explicitly contrast with nearby siblings like search_suggest or user, so it stops short of full disambiguation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Embedding it as "for the comment / DM composer" implies the calling context, but there is no explicit when-to-use or when-not-to-use guidance versus alternatives such as user or search_suggest. Usage is only inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
19 tool updates
v0.5.0- Changed
comments3 fields changed- added
Input schema / properties / oldest_first / descriptionAdded value: +"Return oldest comments first (false = newest first)." - added
Input schema / properties / page / descriptionAdded value: +"Zero-based page index." - added
Input schema / properties / post_id / descriptionAdded value: +"Haraj post id."
- Changed
fetch_feed10 fields changed- added
Input schema / properties / before_update_date / descriptionAdded value: +"Pagination cursor in Unix seconds — pass the last item's updateDate to get the next page." - added
Input schema / properties / cities / descriptionAdded value: +"List of Arabic region names to filter by (multi-city)." - added
Input schema / properties / city / descriptionAdded value: +"Single Arabic region name to filter by, e.g. 'الشرقيه'." - added
Input schema / properties / full / descriptionAdded value: +"Return full Post objects instead of compact summaries." - added
Input schema / properties / limit / descriptionAdded value: +"Number of posts to return (clamped to 1-100)." - added
Input schema / properties / only_with_image / descriptionAdded value: +"Only return posts that have at least one image." - added
Input schema / properties / only_with_video / descriptionAdded value: +"Only return posts that have a video." - added
Input schema / properties / order_main_by_post_id / descriptionAdded value: +"Order the main feed by post id instead of update date." - added
Input schema / properties / page / descriptionAdded value: +"Zero-based page index." - added
Input schema / properties / tag / descriptionAdded value: +"Arabic category/tag name, e.g. 'حراج السيارات' (cars) or 'حراج الأجهزة' (devices)."
- Changed
follow_user1 field changed- added
Input schema / properties / username / descriptionAdded value: +"Haraj username to follow/unfollow."
- Changed
get_post_details2 fields changed- added
Input schema / properties / full / descriptionAdded value: +"Return the full similarPosts response instead of a summary." - added
Input schema / properties / post_id / descriptionAdded value: +"Haraj post id, e.g. 185926519."
- Changed
is_following_tag2 fields changed- added
Input schema / properties / city / descriptionAdded value: +"Optional Arabic region name to scope the check." - added
Input schema / properties / tag / descriptionAdded value: +"Arabic tag name to check the authenticated user's follow status for."
- Changed
is_following_user1 field changed- added
Input schema / properties / username / descriptionAdded value: +"Haraj username to check."
- Changed
live_streams1 field changed- added
Input schema / properties / limit / descriptionAdded value: +"Maximum number of streams to return (the server caps it)."
- Changed
locker_shipment_offer1 field changed- added
Input schema / properties / post_id / descriptionAdded value: +"Haraj post id."
- Changed
notes1 field changed- added
Input schema / properties / set_read / descriptionAdded value: +"Mark the notifications as read on the server."
- Changed
outgoing_buy_requests1 field changed- added
Input schema / properties / page / descriptionAdded value: +"Zero-based page index."
- Changed
post_contact1 field changed- added
Input schema / properties / post_id / descriptionAdded value: +"Haraj post id."
- Changed
post_like_info1 field changed- added
Input schema / properties / post_id / descriptionAdded value: +"Haraj post id."
- Changed
promoted_posts3 fields changed- added
Input schema / properties / city / descriptionAdded value: +"Arabic region name to filter by." - added
Input schema / properties / full / descriptionAdded value: +"Return full Post objects instead of compact summaries." - added
Input schema / properties / tag / descriptionAdded value: +"Arabic tag name for the promoted carousel, e.g. 'حراج الأجهزة'."
- Changed
related_tags2 fields changed- added
Input schema / properties / city / descriptionAdded value: +"Optional Arabic region name to scope the counts to." - added
Input schema / properties / tag / descriptionAdded value: +"Arabic tag name to get city post-counts for, e.g. 'حراج السيارات'."
- Changed
search14 fields changed- added
Input schema / properties / cities / descriptionAdded value: +"List of Arabic region names to filter by." - added
Input schema / properties / city / descriptionAdded value: +"Single Arabic region name to filter by." - added
Input schema / properties / during_date / descriptionAdded value: +"Time window: '1days', '3days', '1week', or '1months'." - added
Input schema / properties / full / descriptionAdded value: +"Return full Post objects instead of compact summaries." - added
Input schema / properties / hide_show_rooms / descriptionAdded value: +"If true, hides dealer posts (real-estate filter)." - added
Input schema / properties / keyword / descriptionAdded value: +"Search keyword (Arabic or English), e.g. 'RTX 4090' or 'شاشة'." - added
Input schema / properties / limit / descriptionAdded value: +"Number of posts to return (clamped to 1-100)." - added
Input schema / properties / near / descriptionAdded value: +"Geohash location filter like '@26.4336,50.1116'." - added
Input schema / properties / only_with_image / descriptionAdded value: +"Only return posts that have at least one image." - added
Input schema / properties / only_with_video / descriptionAdded value: +"Only return posts that have a video." - added
Input schema / properties / order_by_post_id / descriptionAdded value: +"Order results by post id instead of relevance/date." - added
Input schema / properties / page / descriptionAdded value: +"Zero-based page index." - added
Input schema / properties / tag / descriptionAdded value: +"Restrict the search to a single Arabic tag." - added
Input schema / properties / tags / descriptionAdded value: +"Restrict the search to a list of Arabic tags."
- Changed
search_suggest2 fields changed- added
Input schema / properties / prefix / descriptionAdded value: +"Text typed in the search box, e.g. 'شاشة'." - added
Input schema / properties / tag / descriptionAdded value: +"Optional Arabic tag to scope the suggestions."
- Changed
sellers_list2 fields changed- added
Input schema / properties / page / descriptionAdded value: +"Zero-based page index." - added
Input schema / properties / tags / descriptionAdded value: +"List of Arabic tag names (real-estate/business/investment pages)."
- Changed
trending_keywords1 field changed- added
Input schema / properties / range_in_days / descriptionAdded value: +"Look-back window in days (default 7)."
- Changed
user3 fields changed- added
Input schema / properties / rating_summary_only / descriptionAdded value: +"Return only the rating block instead of the full profile." - added
Input schema / properties / user_id / descriptionAdded value: +"Numeric Haraj user id (alternative to username)." - added
Input schema / properties / username / descriptionAdded value: +"Haraj username (URL-encoded Arabic is accepted)."
21 tool updates
v0.3.0- First observed
check_auth - First observed
comments - First observed
fetch_feed - First observed
follow_user - First observed
get_post_details - First observed
is_following_tag - First observed
is_following_user - First observed
live_streams - First observed
locker_shipment_offer - First observed
notes - First observed
outgoing_buy_requests - First observed
post_contact - First observed
post_like_info - First observed
promoted_posts - First observed
related_tags - First observed
search - First observed
search_suggest - First observed
sellers_list - First observed
trending_keywords - First observed
user - First observed
user_mention_suggestions
TDQS
Scored across 21 tools
Each tool targets a clearly distinct resource or action. While several tools return posts (fetch_feed, search, promoted_posts) or relate to users (follow_user, is_following_user, user), the descriptions precisely differentiate their scopes and use cases.
All names use snake_case, which is consistent, but the grammatical pattern is mixed: some are verb_noun (fetch_feed, get_post_details), some are noun phrases (promoted_posts, post_like_info), and some are is_* predicates (is_following_tag). This inconsistency makes the set less predictable.
21 tools is on the high side for a single server, falling into the borderline heavy range per the rubric. Although each tool appears to cover a distinct API feature, the sheer number increases cognitive load and could be consolidated.
The surface covers many read operations and a few write actions (follow_user, notes set_read), but notable write operations are missing: creating or editing posts, liking/unliking, posting comments, following/unfollowing tags, and sending messages. These gaps limit agent autonomy for core marketplace interactions.
Maintenance
Related MCP Connectors
All HasData scraping tools in one MCP server: Google, TikTok, Instagram, maps, e-commerce and more.
Hosted MCP server for DataLikers — Instagram & TikTok data API. 51 tools: Instagram user search by demographics (gender/age/race/country/city), profiles, bulk lookup, engagement, posts & reels, comments, hashtags, locations, stories, highlights, music, business accounts, top users; TikTok users, videos, comments, hashtags, playlists and top charts. Streamable HTTP, Bearer API key. Free tier: 100 requests on signup at https://datalikers.com/p/1by27bwg
One MCP server for 180+ live web-data APIs returning clean JSON from sites that block scrapers.
MCP server for 500+ pay-per-call web scraping, search, social, business, and financial data tools.
1
Related MCP Servers
AlicenseCqualityAmaintenanceHosted MCP server for 3,093 structured public web-data tools across 420 platform groups, returning clean JSON for search, maps, commerce, social, and finance.6500536 npm1MIT- AlicenseNot gradedqualityDmaintenanceA read-only MCP server that gives LLM agents live access to OpenSooq, the largest classifieds marketplace in Kuwait, enabling search, pricing, seller reputation, and deal finding.2MIT
- FlicenseNot gradedqualityBmaintenanceRemote MCP server for Saudi real estate data, giving AI assistants access to 65,000+ rental and sale property listings across 5 Saudi cities with market analytics and price trends.1-
- AlicenseNot gradedqualityAmaintenanceMCP server for the OLX.ba API that enables searching, publishing, editing, and managing listings (ads), including image handling, sponsorships, categories, locations, and user account operations through 36 tools covering all official API endpoints.15 npm6MIT