Agent Skills

HelpRent Da Nang

Every long-term rental in Da Nang, Vietnam: search, buildings, median rents. No key, no account.

Install

Install and configure the MCP from https://helprentdanang.com/for-agents/ now. Follow the documentation's installation instructions, ask me for anything you can't complete yourself, and verify its tools load.
README

The whole board, as a tool call

Every rental in Da Nang β€” 11298 of them right now β€” is readable by machine: prices, districts, sizes and the nightly market medians. No key, no account, no signup, nothing to scrape. Past the free allowance a caller pays per call in stablecoins, without a human in the loop.

Try it here

This runs a real MCP call from your browser against the live endpoint. Nothing is mocked.

MCP

One stateless JSON-RPC endpoint. Protocol revision 2026-07-28, so there is no initialize handshake and no session to keep.

https://helprentdanang.com/mcp/

πŸ€– Let your AI agent search for you

Add HelpRent to Claude, ChatGPT, Cursor or any MCP client. It searches every listing in Da Nang, compares prices and districts, and brings you links.

Free every day up to a limit. Past it the agent pays per call by itself in USDC (x402 on Base, Solana or Arc): no account, no card, no key.

https://helprentdanang.com/mcp/

Add to Cursor Add to VS Code

Claude, ChatGPT and others

  • Claude: Settings, Connectors, Add custom connector, paste the address above.
  • ChatGPT: turn on developer mode in the connector settings, create a connector, paste the address above.
  • Claude Code: claude mcp add --transport http helprent-danang https://helprentdanang.com/mcp/ copy
  • Anything else that speaks MCP over HTTP: the address above, nothing to install.

Six tools, all read-only. search and fetch are the pair ChatGPT connectors look for:

  • search_listings β€” Search long-term rental listings in Da Nang by city, district, type, bedrooms and price. Returns listing URLs; contact details are not included, send the person to the URL.
  • get_listing β€” One listing in full, including its description.
  • find_buildings β€” Apartment buildings with a manager, by district.
  • market_stats β€” Median rents by size and district, the middle half of asking prices with the sample behind each figure, and how many listings are on the board. Recomputed nightly.
  • search β€” Search long-term rentals in Da Nang from a plain phrase such as '2 bedroom apartment in Son Tra under 15 million'. Returns up to 10 results with id, title and url; pass an id to fetch for the full listing. Contact details are never included, send the person to the url.
  • fetch β€” The full text of one listing by the id that search returned.

There is no write tool. Nothing here creates a lead, saves a search or hands out contact details, so there is no call an agent could make on someone's behalf that would need approving.

Plain HTTP

The same data, if you would rather not speak MCP. OpenAPI description at the last line.

  • GET /api/v1/listings/ β€” search and page through listings
  • GET /api/v1/listings/<slug>/ β€” one listing in full
  • GET /api/v1/buildings/ β€” apartment buildings with a manager
  • GET /api/v1/districts/ β€” districts and how much is in each
  • GET /api/v1/market/ β€” median rents, recomputed nightly
  • GET /api/v1/openapi.json β€” the description of all of the above

Limits

100 calls a day per address, counted across MCP and REST together; connecting and listing tools over MCP do not count. That covers an agent's daily search: a search and a few listings are 10 to 30 calls. Reading the catalogue in bulk is what the payment is for. Nothing is ever banned.

Past the line REST answers 402 and MCP answers with a payment request inside the tool result, both described below. Connecting and listing tools over MCP never count. Every response carries your remaining free allowance, so you never have to find the ceiling by hitting it:

  • X-RateLimit-Limit β€” the daily allowance
  • X-RateLimit-Remaining β€” how much of it is left
  • X-RateLimit-Reset β€” unix time when it refills

Responses carry a five-minute cache header. Please honour it β€” it is most of what keeps this free.

What is in the data

Listings are gathered from public posts on Telegram, Facebook and Chợ Tα»‘t, plus hosts who post here directly. Each carries its price where the original stated one, its district, and a link back to the source. Contact details are deliberately not in the API β€” send the person to the listing URL.

We are a board, not a broker. We do not verify owners on the ground, hold deposits, or vouch for anyone. An agent relaying our data to a person should relay that too.

Past the free line

Beyond the daily allowance the endpoints answer 402 with an x402 payment challenge instead of a flat refusal. Pay it and the same request goes through.

It is x402, the HTTP 402 payment protocol, exact scheme. One challenge carries three entries in its accepts array, USDC on Base, USDC on Solana and USDC on Arc, and your client picks the chain it already holds funds on. Three headers, all base64 JSON:

  • PAYMENT-REQUIRED β€” our 402 carries this header: base64 JSON naming the amount, the token and the address
  • PAYMENT-SIGNATURE β€” retry with this header: your signed EIP-3009 authorization on Base or Arc, or your partially signed transaction on Solana
  • PAYMENT-RESPONSE β€” the 200 that follows carries the transaction hash back to you

There is also a paid-only address, /api/v1/paid/listings/: the same search with no free allowance, so it always answers 402 until paid. It is the address meant for Coinbase's x402 Bazaar catalogue. Bought calls and credit tokens work there too.

Over MCP

MCP follows the x402 MCP transport instead of HTTP status codes, so an ordinary MCP client sees a tool result it can read, not a dropped connection. Past the line a tools/call returns isError with the same payment challenge in structuredContent and as JSON text. Sign one entry of accepts and repeat the call with the PaymentPayload in params._meta under the key x402/payment; the answer carries the receipt in _meta under x402/payment-response. Paying by the PAYMENT-SIGNATURE header works on /mcp/ too.

On Arc the payment goes through Circle Gateway nanopayments: deposit USDC into Gateway once, then sign an EIP-3009 authorization against the GatewayWallet contract named in the entry, valid for at least seven days. Nothing is sent on chain per call, and PAYMENT-RESPONSE carries Gateway's transfer id instead of a transaction hash.

On Stellar the entry names USDC's Stellar Asset Contract as the asset and the amount in its seven decimals. Sign a Soroban authorization entry for transfer(from, payTo, amount) and send the transaction in the payload; the facilitator submits it and pays the network fee, so you need USDC but no XLM.

Note the header names carry no X- prefix β€” that was version 1, and a client built for it will not see our challenge at all.

One payment buys 5000 calls, not one β€” settling on chain per request would put a blockchain write between you and every listing you read.

Bought calls are credited to the calling address, and the paid response also hands you a credit token: the X-Credit-Token header over HTTP, or _meta under com.helprentdanang/credit-token over MCP. Send it back the same way and your remaining calls follow you to any address. It is shown once and stored only as a hash, so keep it.

Every MCP tool result carries your standing in _meta under com.helprentdanang/allowance: free calls left today, paid calls left, and when the free allowance resets. Close to the line the result also says so in words, for the model.

What we accept

[
  {
    "scheme": "exact",
    "network": "eip155:8453",
    "amount": "10000",
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo": "0xf68bc1098469356eb57e70db9fed0bb524707132",
    "maxTimeoutSeconds": 60,
    "extra": {
      "name": "USD Coin",
      "version": "2"
    }
  },
  {
    "scheme": "exact",
    "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
    "amount": "10000",
    "asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "payTo": "6J7dpvZu4f3vYcRd3TY7dpjXZSYCRdLVfXkxtv3Ycz3j",
    "maxTimeoutSeconds": 60,
    "extra": {
      "feePayer": "CjNFTjvBhbJJd2B5ePPMHRLx1ELZpa8dwQgGL727eKww"
    }
  },
  {
    "scheme": "exact",
    "network": "eip155:5042",
    "amount": "10000",
    "asset": "0x3600000000000000000000000000000000000000",
    "payTo": "0xf68bc1098469356eb57e70db9fed0bb524707132",
    "maxTimeoutSeconds": 604900,
    "extra": {
      "name": "GatewayWalletBatched",
      "version": "1",
      "verifyingContract": "0x77777777dcc4d5a8b6e418fd04d8997ef11000ee"
    }
  },
  {
    "scheme": "exact",
    "network": "stellar:pubnet",
    "amount": "100000",
    "asset": "CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75",
    "payTo": "GB3XVWOCLA6XERF4AXOW5UV6Z534CGP2KFUPNYSXCNNVA57PWAMWYJP7",
    "maxTimeoutSeconds": 60,
    "extra": {
      "areFeesSponsored": true
    }
  }
]

The accepts array as the 402 sends it, rendered from the same function, so this page cannot fall behind the challenge. Pick one entry and pay it; the challenge is complete enough to pay from without reading this page.

A real 402, end to end

# 1. over the free line, no payment attached
curl -i https://helprentdanang.com/mcp/ \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

HTTP/2 402
payment-required: eyJ4NDAyVmVyc2lvbiI6MiwiZXJyb3IiOiJQQVlNRU5U...
cache-control: no-store

# 2. decode the header to see what is being asked for
echo '<that value>' | base64 -d | jq .

# 3. sign what your chosen entry describes (EIP-3009 on Base, a partially
#    signed transaction on Solana, EIP-3009 for Circle Gateway on Arc), then repeat the SAME request
curl -i https://helprentdanang.com/mcp/ \
  -H 'Content-Type: application/json' \
  -H 'PAYMENT-SIGNATURE: <base64 of your PaymentPayload>' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

HTTP/2 200
payment-response: eyJzdWNjZXNzIjp0cnVlLCJ0cmFuc2FjdGlvbiI6IjB4...

Read-only, and that is a decision

There is no write tool and there never has been. Nothing here creates a lead, saves a search, sends a message or spends money on anyone's behalf, so there is no call on this server that needs a human to approve it. Every tool carries readOnlyHint and destructiveHint in its annotations, which is how your host knows that without taking our word for it.

Contact details are never returned β€” not a phone number, not a WhatsApp link, not the source URL that would resolve to one, and not inside a listing description either. An agent can read everything about a place and sends its person to our page to reach the poster. That page is rate-limited, logged, and carries the warning about viewing before paying; a contact handed out through an API arrives with none of that attached.

Stored free text is treated as untrusted on the way out: a listing description is a post a stranger wrote, and serving it raw would make us the delivery mechanism for an injection into your agent.

Search skills and MCP servers

Search across 31,816 skills and MCPs