---
name: mural
description: Operate Meta Agent Tools — registry of MCP servers, agent skills, plugins and OKF knowledge bundles; likes, comments, hop visits, pending queue, x402 listing/contact, IndexNow-style OKF submission. Use when working with Meta Agent Tools, agentalog.com, OKF Index or the mural workspace.
---

# Meta Agent Tools — skill para agentes

**Live:** https://agentalog.com  
**UI humana:** busca dentro de cada tipo → lista com stats → ficha em sub-aba do tipo (README na abertura) → instalação sob demanda. Agentes começam em `/developers` e consomem API/OpenAPI/MCP; não dependem do HTML ou dos exemplos de instalação de terceiros.

**Descoberta:** `GET /api/` · `/llms.txt` · `/openapi.json` · `GET /v0.1/servers`  
**SEO (13/09/2026):** todo registro é rastreável — página HTML por registro em `/l/<id>` (linha da API + README + JSON-LD, sem JS), índice navegável `/catalog/` (tipo → assunto ou publicador → páginas de 50 → registro), `/sitemap.xml` (páginas e nós do índice) e `/sitemap-listings.xml` (todo registro, em shards de 50 mil gerados no c3). IndexNow = CI.

**Catálogo:** `src/lib/apidocs.js`  
**MCP (remoto, recomendado):** `POST https://agentalog.com/mcp` — Streamable HTTP, JSON-RPC 2.0.
Pluga direto no cliente MCP; não precisa deste repositório. Confira com `GET https://agentalog.com/mcp`.
**MCP (stdio, local):** `node ~/src/mm/scripts/mcp/server.mjs --product mural`

Paridade UI/API/skill/MCP no mesmo commit: `AGENTS.md` do produto e `AGENTS-API.md` da raiz.

## Auth

- `POST /api/guest` → `X-Guest-Token: mr_…` (like, comentário e hop); no navegador o convidado mora
  também no cookie HttpOnly `guest`. A emissão tem teto por rede (20 por hora).
- Registrar: sessão da conta MM (humano, no navegador: entra em `/conta/global`; cookie HttpOnly +
  `X-CSRF-Token` de `/api/auth/bootstrap`; grátis) **ou** x402 $0.10 (agente). Logo depois de entrar, a tela
  da conta faz o claim (`POST /api/auth/claim`): registros, likes e comentários do convidado passam para a
  conta — o like que a conta já tinha no mesmo registro fica com o convidado. Escrita com o cookie de uma
  sessão que acabou responde 401 `session_ended` (entre de novo), nunca vira o convidado.
  `POST /api/auth/start` e `/verify` respondem 410; não há bearer de conta para agentes.
- ⚠️ **Ter guest token NÃO impede pagar.** Guest cai no 402 pagável, igual ao anônimo.
- ✅ **Valida antes de cobrar.** Corpo recusado (400) e cota estourada (429) vêm ANTES do 402:
  nenhum pagamento liquida por registro que já se sabe que não entra. Corpo válido sem pagamento
  continua recebendo o 402 com o preço.

## Operações

| Tool | HTTP |
|------|------|
| `api_index` | `GET /api/` |
| `list_listings` | `GET /api/listings` (**varredura inteira:** siga `next` até `null` — sem `q` é cursor (`next_cursor`/`cursor`, ordens `recent`, `stars`, `nome`) e não há teto; `offset` continua aceito, sem teto, mas o banco lê as linhas saltadas; `kind=mcp\|skill\|plugin\|okf`, `origin=official\|smithery\|casdoor\|indices\|marketplace\|directory\|gemini\|majiayu\|seed\|community` (`indices` = servidor MCP que só os índices de terceiros conhecem, com o que cada um mediu em `mcp_index_signals`), `q` — busca de texto pelo índice FTS5: toda palavra é exigida (nome, resumo, descrição, identificador de origem e excerto do README), ordem por bm25 com o nome pesando mais, vezes 1 + 0,05·ln(1 + estrelas) + 0,1 se houve push em 180 dias + 0,1 se há README, empate por estrelas; kind/topic/transport words become filters unless `interpret=0`, a cauda `low` (sinal baixo, selo LOW) vem em toda lista DEPOIS das `live`; `low=0` a deixa de fora) |
| — | Para pessoas: a home com recorte na URL (`/?kind=mcp&topico=finance`, `/?ns=io.github.x`, `/pt?…`) sai do Worker com título, `<h1>`, description e canonical do recorte (F6.1); a abertura lista os recortes prontos por assunto com a contagem do catálogo. `ns` é o publicador: o namespace reverso do registro oficial (`io.github.<conta>` para quem publica pelo GitHub; o chip mostra sem o prefixo) — o recorte `?ns=<ns>` é a página do publicador (F6.2): cabeçalho com nome, quantos registros vivos e estrelas somadas, vindos de `publicador` no `GET /api/facets?ns=<ns>` (só com um `ns`), e o link "todos deste publicador" limpa o resto do recorte. A canônica do recorte que tem nó no índice (`?kind=`, `?kind=&topico=`, `?ns=`) é o nó de `/catalog/`; a página de cada registro é `/l/<id>` |
| `list_mcp_servers` | `GET /v0.1/servers` (subregistry MCP) |
| `get_listing` | `GET /api/listings/:id` — `topico` é inferido do texto (regra de palavras e, onde ela não acha nada, modelo de linguagem com confiança ≥ 0,8; ninguém declara); quando veio do modelo, `payload.topico_llm` traz `{topico, confianca, trecho, v}` com o trecho que justificou |
| `get_listing_readme` | `GET /api/listings/:id/readme` — só quando a linha da lista ou a ficha traz `readme_api` (ausente = não coletou; a rota responde 404); `readme_bytes` na lista diz o tamanho antes de abrir. `readme_fonte` na ficha e `fonte` na rota dizem de onde veio: `repo` (README do repositório GitHub) ou `npm`/`pypi` (README do registro do pacote, quando não há repositório) |
| — | `GET /api/volatil?ids=a,b` — downloads, instalações e versão frescos (cache de 15 min); a ficha já os aplica |
| `listing_history` | `GET /api/listings/:id/history` — a linha do tempo do repositório do registro (F7): até 5 eventos, do mais recente para o mais antigo, `{em, tipo, de?, para?}` com `tipo` em `abandono` (12 meses sem push), `sumiu`, `renomeado`, `readme_mudou`, `manifesto_mudou`; lista vazia = nada mudou desde que a série começou (o registro existe); a ficha traz o mesmo em `historico` |
| `feed_find` | `GET /api/feeds?dominio=<domínio>` — **este site publica feed?** Devolve todo feed conhecido daquele domínio |
| `feed_search` | `GET /api/feeds` — índice de feeds RSS/Atom/JSON, listas OPML e sites que só viram feed por uma ponte (RSS-Bridge). Filtro e texto na MESMA consulta: dentro de um parâmetro os valores são OU, entre parâmetros são E. `q`, `tipo=rss2\|rss1\|atom\|json`, `midia=audio\|video`, `comunidade=fediverse\|indieweb\|mastodon\|friendica\|wordpress\|funkwhale`, `recurso=content\|itunes\|podcast\|media\|slash\|wfw\|georss`, `origem=index\|blogroll\|bridge`, `lista=web\|catalogo\|planeta`, `ano=<AAAA>` (ano do item mais novo visto; `0` = sem data). Sem `q`, a ordem é a densidade medida e `next_cursor` é keyset — siga `next` para varrer tudo. Contagem por valor em `GET /api/feeds/facets`; ficha em `GET /api/feeds/:id` e página em `/feeds/<id>` |
| `feed_posts` | `GET /api/feeds/:id/items` — **o que esse feed publicou**, como a NOSSA fila leu: até 40 posts na ordem do feed, com `titulo`, `quando`, `autor`, `resumo`, `tags` (categorias do autor), `media` (o anexo do episódio) e `comentarios`, SEM o corpo. `bytes` diz quanto texto há guardado antes de abrir. 200 com `itens` vazio = feed conhecido que a fila ainda não leu; 404 = id que não é nosso |
| `feed_post` | `GET /api/feeds/:id/items/:ord` — **um post inteiro** (`ord` 0 é o mais novo): `conteudo` em Markdown e `conteudo_html` com a formatação do autor passada por lista de permissão. Os dois nascem na LEITURA do feed, não no pedido — nenhum dos dois carrega script. `link` leva ao original |
| — | É a NOSSA cópia, na NOSSA agenda, endereçada por id deste índice — nunca por uma URL que você entrega. Não somos proxy e não buscamos nada em seu nome |
| — | Para pessoas: `/feeds/` lista os recortes (podcasts, texto completo, IndieWeb, listas de leitura…), cada um com página própria e paginação por link real |
| `mcp_index_signals` | `GET /api/indices/sinais?listing=<id>` — **o que os índices de MCP independentes mediram deste registro**: Truespar, Wellknown, agent-tools.cloud, Link (hultra), Paygent, Neuronto e Nerq, um sinal por índice com `credito` (nome, site, licença), `mede` (o que aquele índice observa: handshake, sonda de chamada, reputação paga, vida do repositório, só descoberta), `estado` na palavra da casa (`vivo` · `fora` · `parado` · `abandonado` · `apagado` · `desconhecido`) e `estado_na_fonte` na palavra deles. Casa só pelo MESMO objeto: nome no registro oficial, URL exata do endpoint ou `owner/repo` — domínio não casa. Coleta 1×/dia no nosso host; atribuição obrigatória, e o derivado do Link sai sob ODbL |
| `mcp_index_search` | `GET /api/indices/itens` — navegar os sinais: `fonte`, `estado`, `casou=0` (o que os índices conhecem e o catálogo ainda não) ou `casou=1`, `q`, `limit`/`offset`. As fontes, a licença de cada uma, a contagem por estado e a última rodada: `GET /api/indices` |
| `go_listing` | `GET /api/go/:id` (302) |
| `like_listing` | `POST /api/listings/:id/like` |
| `list_comments` | `GET /api/listings/:id/comments` |
| `create_listing` | `POST /api/listings` (sessão grátis · agente 402 x402). Skill: URL do `SKILL.md`. Nasce `pending`; o 201 traz `status_api`. |
| `listing_status` | `GET /api/listings/:id/status` — a decisão da fila (`pending` · `live` · `low` · `hidden` · `blocked`) e o `reason` quando a moderação deixou um, sem credencial e sem o conteúdo; cache 60 s, consulte a cada poucos minutos |
| `submit_okf` | `POST /api/okf/ping` (OKF Index — grátis, sem conta; a mesma fila de `okfindex.com/api/ping`; ver abaixo) |
| `billing` | `GET /api/billing` |
| `contact` | `POST /api/contact` (agente $0.10) · 1º envio sai na hora; seguintes 429 + `Retry-After` (60s→2×, teto 1h) |

Admin (`ADMIN_EMAIL` / `ADMIN_TOKEN`): `GET /api/me` traz `carga.falhas[]`; `GET|POST /api/admin/carga` dispara lote e marca visto; `POST /api/admin/listings/:id` decide (`approve` · `hide` · `block`) com `reason` (obrigatório em `block`, até 300), que quem submeteu lê em `listing_status`, e aceita `fix` (`name`, `tagline`, `body`, `category`) junto de `approve` para corrigir antes de publicar — nunca a URL. Sem tool MCP — é operador.

Fora das tools: as contagens do catálogo por tipo, procedência, categoria e estado saem em
`GET /api/facets` (é o que alimenta os filtros da tela); comentário seu se apaga com
`DELETE /api/comments/:id` — comentário alheio responde 404, não 403. Curtida, comentário e visita
de cada registro que tem algum saem em `GET /api/contadores` (lidos de onde são gravados, cache de
1 min); tráfego de smoke não conta em nenhum deles.

`GET /coleta/readme/:arquivo` é a cópia Markdown já presente no disco da origem
(por exemplo, `owner/repository.md`), sob a mesma quota e passe MAT. Prefira
`get_listing_readme` e `/api/listings/:id/readme`: incluem metadados e o histórico
anterior no R2 quando o objeto ainda não está no disco.

## OKF Index (kind `okf`)

Bundles do **Open Knowledge Format** — árvore de markdown com frontmatter YAML que o agente lê
inteira, cuja raiz é um `index.md` com `okf_version`. A spec não define convenção de descoberta nem
registro; o **OKF Index** (https://okfindex.com — busca, ficha, estatística e MCP próprios, mesmo
backend) é a resposta a isso, e o mural indexa e exibe os mesmos bundles. Só entra bundle cuja raiz foi LIDA e tem `okf_version` —
não é lista de repositório que menciona OKF. **Não fixamos versão:** vale o `okf_version` que o bundle declarar (medido 07/09/2026: 0.1 e 0.2 convivem, ~40% já em 0.2).

- **De onde vêm:** as raízes públicas no GitHub (varredura fatiada — medido 07/09/2026:
  **2.818 bundles em 1.178 repositórios**) e os domínios que submetem os seus.
- **Submeter o seu, grátis e sem conta** (`POST /api/okf/ping`, protocolo do IndexNow):
  1. publique `https://SEU-HOST/SUA-CHAVE.txt` contendo exatamente a chave (8–128 de `[a-zA-Z0-9-]`);
  2. `POST /api/okf/ping` com `{"host","key","urlList":[…]}` — `keyLocation` opcional, no MESMO host;
  3. resposta **202**: a chave ainda não foi conferida. Buscamos o arquivo da chave ANTES de ler
     qualquer URL sua. Nada é publicado se ela não bater.
- **Bundle mudou?** Re-envie a URL. É esse o canal de frescor — o índice relê e a linha atualiza.
- Tetos: 100 URLs por pedido, 200 por host por dia UTC.
- Não somos o registro oficial de OKF nem afiliados ao Google, que publica a spec.

## Cota e preços

`GET /api/pricing` (tool `pricing`) apresenta as franquias e tarifas públicas.
`GET /api/billing` (tool `billing`) conserva o catálogo de cobrança do produto.
Consulte antes de uma operação paga; o desafio 402 informa o valor do pedido.

- **Grátis:** navegação comum, descoberta, comentários, like, comentar e hop.
- **Coleta identificada:** GPTBot, ClaudeBot, CCBot, Meta-ExternalAgent, Amazonbot,
  AhrefsBot e MJ12bot têm 1.000 leituras/dia UTC por família. O excesso responde 402
  oferecendo o pacote MAT: US$1/1.000 leituras/30 dias, sem renovação automática.
  Confira `GET /api/acesso` (`api_access`) e seu `enabled` antes de comprar.
  Gere e guarde `mat_<32 hex aleatórios>_<64 hex aleatórios>`, compre explicitamente
  em `POST /api/acesso` (`api_access_buy`) e use `X-API-Pass` na origem
  `https://api.agentalog.com` ou `api_pass` nas tools de leitura. Saldo em `/api/uso`
  (`api_usage`); uma resposta bem-sucedida de até 1 MiB = uma leitura.
  O saldo MAT é próprio; não reutilizar o passe `api_` dos outros três acervos.
- **Grátis com a conta MM:** 1 registro/dia, máx. 3 na fila.
- **Toda submissão passa por revisão humana:** nasce `pending` e só uma pessoa aprova. Depois do
  `create_listing`, acompanhe por `listing_status` (`status_api` do 201); `public: true` = no ar.
  Quem registrou com a conta MM recebe um e-mail com a decisão e o `reason`; agente e convidado
  não têm e-mail e acompanham pelo status.
- **Pago (agente):** registro $0.10 · contato $0.10 — x402, USDC na Base.
- Números em vigor: `GET /api/billing` e o bloco `quota` de `GET /api/`.

## Cota estourada

Operações avulsas respondem **402** com `accepts[]`; pague e repita com `X-PAYMENT`.
Na leitura do catálogo, o 402 indica a compra separada do pacote em `/api/acesso`;
após confirmar o pagamento, repita a leitura com `X-API-Pass`. Retry de leitura
usa `Idempotency-Key` (`retry_key` na tool), mesmo recurso por até cinco minutos.
Nunca interpretar descoberta ou consulta de saldo como autorização para gastar.

## Pesquisa OKF e original

`GET /api/bundles` (`search_bundles`) e `GET /api/bundles/:id` (`get_bundle`) são idênticos
nos dois produtos; `/api/okf/stats` (`index_stats`) conta todo o índice antes de abrir a aba.
Filtros: `concept` (texto do extrato da raiz, até 80 caracteres), `concepts` (0,1-5,6-20,21-100,101+),
`type` (declarado na raiz), `license` (repo), além de `q`, `origin`, `repo`, `version`, `language`,
`sort`, `limit`, `offset`. Cada faceta aceita até 5 valores separados por vírgula.
`concept` pesquisa só os primeiros 1000 caracteres indexados da raiz, não os arquivos dos conceitos.
Na UI a ficha alterna Formatted/RAW. O RAW busca o `index_url` original com frontmatter no navegador,
limite 256 KiB/10 s, sem proxy ou credenciais; se o publicador negar CORS, abra a origem.

## Acervos públicos de dados

`GET /api/` → `docs.data_indexes` descobre quatro acervos de leitura: endereços CNEFE,
metadados PNCP, domínios observados em CT e arquivos de programação XMLTV. As mesmas raízes
estão em `/llms.txt`, `/llms-full.txt`, `/okf/index.md` e `/developers#dados`. Abra o
`formats.json` adequado e siga a hierarquia e `links.proximo` (até 20 itens por página).
Atualização manual: confira fonte e referência. Respeite `Retry-After` em 429/503. Não
encaminhe credenciais do produto a esses hosts. Leia somente o recorte necessário à tarefa.

<!-- GERADO por scripts/monta-ui.mjs — fonte: .agents/skills/<produto>/SKILL.md. Não edite. npm run ui -->
