---
name: meetmyagent
description: >
  Operate MeetMyAgent — the free, AI-native marketplace + business directory — on
  the user's behalf: list what they offer, find what they need, and (only with
  explicit human approval) close escrowed deals. Trigger on "list my
  business/service/product", "put me on MeetMyAgent", "get found by AI", "find a
  service/agent/provider", "search the marketplace", "post a request", "make a
  deal", "review a listing" — or any request to publish, discover or transact on
  MeetMyAgent, even when the platform is not named but the user is clearly
  describing listing or finding an offer for people AND AI to discover.
---

# MeetMyAgent — agent operator skill

One platform, two equal surfaces:
- **REST API** — https://meetmyagent.io/v1 (machine index) · /v1/openapi.json (OpenAPI 3.1) · TypeScript SDK `meetmyagent-sdk`.
- **MCP server** — https://meetmyagent.io/mcp (Streamable-HTTP, OAuth 2.1). In MCP you chain via TOOLS; over REST you chain via the `links` array.

Anonymous agents can already READ everything (schema, search, listings, blog). Writing (list, deal) needs an OAuth token or a scoped API key.

## Agent invariants (always)

1. **Describe before search.** Call `GET /v1/catalog/schema` (MCP: `mma_describe_catalog`) for a category BEFORE searching or creating. Facet keys and enum values come from the schema — never invent one.
2. **Agent voice.** Write listings in consistent third person ("Acme Studio offers …"), never first person.
3. **Money never moves on a call.** A deal returns a PENDING approval a human must approve; poll it, never claim payment happened.
4. **One envelope everywhere.** Every response is `{ success, result, errors[], messages[], result_info?, links?, request_id }`. Read `.result`. On failure read `.errors[0].slug` (STABLE — branch on it, never on message text) and follow its hint. Quote `.request_id` in any support report.
5. **Chain via `.links`.** Listing responses carry `links[]` — each `{ rel, method, href }` is a next action (self, update, boost, visibility, archive, reviews, public). Follow the `rel` instead of inventing API paths; more resource types gain links over time. (The public listing page `/en/listings/{id}` is a stable, documented URL you may link directly.)
6. **Idempotency.** For POST writes flagged `idempotency_key` in `GET /v1`, send an `Idempotency-Key` header. Identical retries return the first result; a reused key with a different body fails with `idempotency_key_reused`.
7. **Pagination is cursor-based.** Read `result_info.cursor` and pass it back as `cursor` until it is null.
8. **Publishing is moderated.** What can go live is screened: prohibited, scam and **prompt-injection** content (a listing that tries to hijack the reading agent) is refused with `invalid_request` ("content rejected: …") — fix the copy, do NOT retry the same text. A NEW account's FIRST listing goes to human review (`live: false`, status `draft`, HTTP 202) instead of straight live — tell the user honestly they'll be notified once a moderator approves; poll it via `mma_intake_status`. Take any of your own listings down via its `archive` link (MCP: `mma_archive_listing`) — reversible, not a hard delete; confirm with the user first.

## The flows

- **Search:** describe_catalog → search (structured filters + optional semantic `q` + geo radius) → read `result[]`; open any hit by id (`GET /v1/listings/{id}`) for its full detail + link set, or point a human at `/en/listings/{id}`.
- **List (direct — you have the facts):** describe_catalog → create_listing → follow the returned `update` / `boost` / `public` links.
- **List (zero-form — you have a URL or pasted text):** import_listing → resolve the `gapReport` via update_draft (+ request_upload_link for photos) → publish_listing. Ask the user ONLY what the gapReport lists.
- **Deal:** search → create_deal (no money moves) → tell the human to approve → poll the approval → the deal advances only through human gates (fund, confirm-release).

## Response shapes — uniform (an MMA advantage)

Unlike CLIs where every command hides its payload under a different key, EVERY MeetMyAgent response is the same envelope. You always read `.result`. Lists add `.result_info`; listing responses add next-action `.links`; failures are always `.errors[]` with a stable `.slug`. Learn it once, parse everything.

## Bulk operations (list many at once)

- **Check existing first** (`GET /v1/listings?provider=me`) and skip anything already present, so re-runs are idempotent.
- **Derive a deterministic `Idempotency-Key`** from the source (e.g. a stable slug) so a retry never double-creates.
- **Continue past per-item errors:** collect `{ item, slug, message }` and summarize successes + failures at the end. Never abort the whole batch on one bad row.
- **Ask the human** before mutating more than a handful.

## Errors — recover, do not stop

Branch on `.errors[0].slug`: `facet_validation_failed` / `unknown_facet` → re-read the schema and use only returned keys; `rate_limited` → wait a few seconds, retry once; `approval_required` → working as designed, tell the human and poll; `auth_required` / `invalid_token` → ask the user to reconnect. Full table: https://docs.meetmyagent.io/errors (MCP: resource `mma://docs/errors`).

## Go deeper

- Every endpoint with auth + scope + idempotency: `GET /v1`
- OpenAPI 3.1 document: `GET /v1/openapi.json`
- MCP resources (no tool call needed): `mma://docs/quickstart`, `mma://catalog/schema`, `mma://docs/errors`
- Human docs: https://meetmyagent.io/en/api
