# Roliki public APIs and agent integration

Roliki.md publishes a roller sports federation website and a custom WordPress product catalog at https://roliki.md/shop/. The product type is `roller_product`; this is not a WooCommerce Store API. These integrations let an external assistant retrieve public facts. They do not host an LLM, run an autonomous shopping agent, accept payments or expose customer/order data.

Catalog and federation reads remain public. Optional anonymous agent registration issues scoped credentials, and revocation invalidates them. Those operations modify only an agent registration; the existing guest order form creates a real customer request. See [authentication, agent registration and guest orders](https://roliki.md/auth.md) before using credentials or making a transaction. All prices should be interpreted with the returned currency; the shop uses Moldovan leu (`MDL`). Availability and prices may change, so recheck the exact variant before recommending or preparing an order.

## Discovery and representations

| URL | Representation and purpose |
| --- | --- |
| [/llms.txt](https://roliki.md/llms.txt) | Site guide in plain text. |
| [/shop/llms.txt](https://roliki.md/shop/llms.txt) | Shop-specific agent instructions in plain text. |
| [/auth.md](https://roliki.md/auth.md) | Agent registration, credential use, anonymous access and customer authorization. Also served at `/shop/auth.md`. |
| [/agent/auth](https://roliki.md/agent/auth) | GET returns registration discovery JSON. POST creates an anonymous agent credential. |
| [/api-docs.md](https://roliki.md/api-docs.md) | This guide in Markdown. |
| [/.well-known/api-catalog](https://roliki.md/.well-known/api-catalog) | API discovery linkset, `application/linkset+json`. |
| [/openapi.json](https://roliki.md/openapi.json) | OpenAPI 3.1.0 description for the public REST API. |
| [/.well-known/agent-skills/index.json](https://roliki.md/.well-known/agent-skills/index.json) | Skill discovery with names, descriptions, URLs and SHA-256 digests. |
| [/.well-known/mcp/server-card.json](https://roliki.md/.well-known/mcp/server-card.json) | MCP server discovery and capabilities. |
| [/mcp/server-card](https://roliki.md/mcp/server-card) | Additional MCP card route. |
| [/wp-sitemap.xml](https://roliki.md/wp-sitemap.xml) | Public URLs for pages, news, products and taxonomies. |

HTTP `Link` discovery advertises the API catalog, OpenAPI service description and this service guide. Public HTML pages also contain corresponding `<link>` elements. Follow the actual advertised links instead of guessing endpoints.

For public HTML pages, send `Accept: text/markdown` to receive a Markdown representation of the same URL. Explicit quality weights are supported: Markdown is selected when its quality is positive and at least the explicitly supplied HTML quality. The response includes `Content-Type: text/markdown`, `Vary: Accept`, a source URL and available JSON-LD structured data. `X-Markdown-Tokens` is an approximate character-based token estimate, not an exact tokenizer count. Logged-in, administrative, preview, feed, error and password-protected pages are not converted. Markdown is a reading representation; use the product's normal browser page for its interactive order form.

```sh
curl -fsS -H 'Accept: text/markdown' 'https://roliki.md/shop/'
curl -fsS 'https://roliki.md/.well-known/api-catalog'
```

The site's public policy is `Content-Signal: ai-train=yes, search=yes, ai-input=yes`, also declared in `robots.txt`. Crawling rules remain relevant. A content-use signal does not authorize submitting forms or accessing private content.

## Public REST API

Base URL: `https://roliki.md/wp-json/roliki-ai/v1`. Responses are JSON. There is no required authorization header or API key. Query strings must be URL encoded.

Public reads may optionally include a valid `Authorization: Bearer ...` agent credential. Invalid, expired or revoked supplied credentials return `401`. Credential-bearing responses are not cached. Optional registration uses `POST /agents/register` (also `POST /agent/auth`) with exactly `{"name":"shopping-assistant","method":"anonymous"}`. The issued credential lasts 24 hours and has only `catalog:read content:read` scope. `GET /agents/me` requires the credential and returns its own registration; `POST /agents/revoke` invalidates that credential. Read [auth.md](https://roliki.md/auth.md) for storage, request limits, examples and lifecycle instructions. Registration does not create a customer or WordPress user, and it does not enable order submission or reveal private information.

| Method and path | Parameters | Result |
| --- | --- | --- |
| `GET /products` | Optional `search`, `category`, `brand`, `page`, `per_page`. | Published product summaries. Category and brand filters use slugs. |
| `GET /products/{id}` | Required positive integer product ID. | Published product details and family variants. |
| `GET /content` | Optional `search`, `page`, `per_page`. | Public federation pages, posts, coach/portfolio entries and FAQs. |
| `GET /categories` | None. | Nonempty product categories and brands, with IDs, names, slugs, URLs and counts. |
| `GET /health` | None. | Plugin version and status (`ok` or `degraded`). |

Search strings and taxonomy slugs are limited to 120 characters. `page` defaults to 1 and accepts integers from 1 to 1000. `per_page` defaults to 20 and accepts integers from 1 to 50. Follow `total_pages` rather than requesting unbounded catalog dumps.

Product and content searches return `items`, `total`, `page`, `per_page`, and `total_pages`. Product summaries contain `id`, `name`, canonical `url`, `sku`, active `price`, `regular_price`, `currency`, `availability`, `sizes`, `image`, `modified` and boolean `price_from`. When `price_from` is true, the displayed parent price is the lowest family variant price: label it as a starting price, not the price of every size or color. Optional `variant_price_range` supplies `min` and `max` family variant prices when variant pricing is available.

Product details add plain-text `description`, `delivery`, `warranty`, `variants` and `purchase_instructions`. Each variant includes `variant_id`, `label`, `size`, `color`, `sku`, `price`, `regular_price`, `currency`, `availability` and a URL carrying its selection. Use the exact selected variant's price even when a parent starting price or range is provided. Variant availability can differ from the parent product. Empty delivery or warranty fields mean that no value is supplied, not that a benefit is guaranteed.

Content results include `id`, `type`, `title`, `url`, `excerpt` and `modified`. Search excerpts are summaries: fetch the canonical page, optionally as Markdown, for full context. Dates and claims on old event pages should not be treated as current schedules.

```sh
curl -fsS 'https://roliki.md/wp-json/roliki-ai/v1/categories'
curl -fsS 'https://roliki.md/wp-json/roliki-ai/v1/products?search=role&per_page=5'
curl -fsS 'https://roliki.md/wp-json/roliki-ai/v1/content?search=antrenori&per_page=5'
```

Use a product ID returned by the search when requesting `/products/{id}`. Invalid arguments can return `400`, and a missing/unpublished/protected product returns `404`. Shop unavailability can return `503`. Product and content data are public; drafts, password-protected content and private order records are excluded. Successful public catalog responses may be cached for 60 seconds, so refresh near the decision point.

## Remote MCP

Endpoint: `https://roliki.md/mcp`. Server name: `md.roliki/catalog`. This is a stateless, POST-only JSON-RPC 2.0 service using the JSON-response mode of Streamable HTTP. Requests require `Content-Type: application/json` and `Accept: application/json, text/event-stream`; omitting either accepted media type returns `406`. There is no SSE stream, session ID or persistent session requirement. Anonymous access remains available; if an agent credential is supplied it must be valid or the request returns `401`. `GET /mcp` returns `405` with `Allow: POST`; it is not a health check. Use `/wp-json/roliki-ai/v1/health` for status.

Supported protocol versions are `2025-11-25`, `2025-06-18` and `2025-03-26`. Initialize first and use the returned negotiated version in the `MCP-Protocol-Version` header for subsequent messages. The initialized notification returns `202` without a JSON-RPC result. Requests require an integer or string `id`; notifications omit it. JSON-RPC batches are not supported. Request bodies are limited to 64 KiB. An explicitly supplied browser `Origin` must be `https://roliki.md` or `https://www.roliki.md`; remote server clients normally omit `Origin`.

Safe initialization example:

```sh
curl -fsS 'https://roliki.md/mcp' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  --data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"catalog-reader","version":"1.0"}}}'
```

Then send `{"jsonrpc":"2.0","method":"notifications/initialized"}` and discover capabilities:

```sh
curl -fsS 'https://roliki.md/mcp' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-11-25' \
  --data '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'
```

Four tools are exposed; their argument bounds match the REST API:

| MCP tool | Arguments | Use |
| --- | --- | --- |
| `search_products` | Optional `search`, `category`, `brand`, `page`, `per_page`. | Find product candidates. |
| `get_product` | Required integer `id`. | Read one product and its current variants. |
| `search_site` | Optional `search`, `page`, `per_page`. | Find public federation content. |
| `list_categories` | Empty object. | Read category and brand filters. |

Tools are marked read-only, non-destructive and idempotent. Successful `tools/call` responses contain the result object in `structuredContent` as well as a text content block with serialized JSON. Use `structuredContent` directly or parse the text block. Tool failures set `isError` and supply an explanatory text block rather than successful structured data.

```json
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"search_products","arguments":{"search":"role","per_page":5}}}
```

`resources/list` exposes these exact public document URIs:

| Resource name | URI |
| --- | --- |
| `roliki-site-guide` | `https://roliki.md/llms.txt` |
| `roliki-authentication` | `https://roliki.md/auth.md` |
| `roliki-api-guide` | `https://roliki.md/api-docs.md` |

Read a resource with `resources/read` and its advertised `uri`. Resources return textual document contents. `resources/templates/list` returns an empty list. Resources are not subscribable and there are no list-change notifications.

`prompts/list` offers `shopping-guide`, with no required arguments. `prompts/get` with `{"name":"shopping-guide"}` returns guidance to clarify size, sport and budget, query the live catalog, compare variants and obtain customer confirmation before orders. The prompt is an instruction template for a client assistant, not a hosted conversation or purchasing service. `ping` is also supported. Unknown methods return JSON-RPC method errors. Honor `429` and `Retry-After` if rate limiting is active; do not send parallel floods or probe order endpoints.

## Browser WebMCP

Public site pages load a browser tool integration for clients supporting `document.modelContext` or the earlier `navigator.modelContext` interface. Its four read-only tools are `search_products`, `get_product`, `search_site` and `list_categories`, with the argument schemas described above. They retrieve anonymous public REST data and return serialized JSON.

A fifth browser tool, `open_product`, takes a required positive integer `id`, validates it through the public product API, and navigates the current browser tab to that product's canonical same-origin URL. It opens the page only; it does not select a variant, fill a form or submit an order. Discover the browser tools and their schemas at runtime. Opening a product or preparing its form does not authorize submission. The remote MCP server exposes only its four read-only tools and has no navigation or order-submission tool.

WebMCP availability depends on the browser's experimental implementation. Feature detection is required. If the browser lacks the API, use the public REST API or remote MCP endpoint; the ordinary website and guest form continue to work.

## Skills and evolving discovery formats

The skill index advertises these Markdown guides:

- [shop-catalog](https://roliki.md/.well-known/agent-skills/shop-catalog/SKILL.md): find and compare products, sizes, variants, prices and availability.
- [federation-content](https://roliki.md/.well-known/agent-skills/federation-content/SKILL.md): find federation information, coaches, events and contacts.

Each `SKILL.md` has YAML `name` and `description` frontmatter matching the discovery entry. Fetch the file before applying its workflow. Digests identify the served document bytes and can change when the guide changes.

API catalog relations, content signals, agent skill discovery, MCP server cards and WebMCP have evolving specifications and differing client support. The skill index currently identifies discovery schema `0.2.0`; the cards advertise their schema and transport explicitly. Treat these as the implemented discovery surfaces, not a guarantee that every crawler or assistant recognizes every format. Use ordinary HTTPS retrieval, OpenAPI and the documented MCP methods as concrete fallback interfaces. Integrations must rediscover schemas and supported protocol versions when updating clients.

## Safe research and shopping

Use public GET endpoints or read-only MCP tools for inspection. Cite canonical links with recommendations. Keep historical federation material distinct from current announcements. Ask the customer about sport, fit, size, budget and preferences when that changes the recommendation. Never infer a size, stock guarantee, delivery commitment or warranty from missing fields.

The shop's existing `POST /wp-json/roliki-shop/v1/order` creates a real order request and can notify staff. It is outside the public read-only API and MCP tool set. Do not invoke it during discovery, diagnostics or testing. For a customer-authorized order, use the guest form and follow [auth.md](https://roliki.md/auth.md), including the rule against automatic retries after an ambiguous failure.
