{
  "name": "Grade",
  "description": "Encontre TV e rádio, abra um canal e guarde seus favoritos para voltar. Pastas e M3U para o VLC. Projetos de produtores com direitos sob consulta.",
  "url": "https://gradetv.net",
  "provider": {
    "organization": "Grade",
    "url": "https://gradetv.net",
    "email": "contato@gradetv.net"
  },
  "documentationUrl": "https://gradetv.net/llms.txt",
  "protocol": "mcp",
  "protocolUrl": "https://modelcontextprotocol.io",
  "interfaces": [
    {
      "transport": "streamable-http",
      "url": "https://gradetv.net/mcp"
    }
  ],
  "capabilities": {
    "streaming": true,
    "pushNotifications": false,
    "authentication": "none"
  },
  "defaultInputModes": [
    "application/json"
  ],
  "defaultOutputModes": [
    "application/json",
    "text/markdown"
  ],
  "skills": [
    {
      "id": "api_index",
      "name": "api_index",
      "description": "Índice auto-descrito da API inteira, com os idiomas e as páginas HTML de cada um.",
      "endpoint": "GET /api/"
    },
    {
      "id": "health",
      "name": "health",
      "description": "Liveness e o commit publicado agora — é como o smoke espera o próprio deploy.",
      "endpoint": "GET /api/health"
    },
    {
      "id": "geo",
      "name": "geo",
      "description": "País e idioma sugeridos para quem está chamando. Sem país detectado pela borda, sugere BR com `source: \"fallback\"`; `detected` diz o que a borda viu.",
      "endpoint": "GET /api/geo"
    },
    {
      "id": "list_countries",
      "name": "list_countries",
      "description": "Países do catálogo com contagem playable e URL da bandeira (kind=radio conta estações).",
      "endpoint": "GET /api/countries"
    },
    {
      "id": "list_tags",
      "name": "list_tags",
      "description": "Tags das estações de rádio tocáveis, com contagem; opcionalmente por país.",
      "endpoint": "GET /api/tags"
    },
    {
      "id": "search_channels",
      "name": "search_channels",
      "description": "Busca canais públicos (filtros: q, country, category, language, network, quality, playable; kind=radio para estações de rádio, tag para tag de rádio; sort=score ordena pela saúde medida por terceiro, sort=votes pelos votos da rádio; online=1 só quem foi visto online nas últimas 48 h). É a porta de entrada do produto. A resposta varia por navegador, sistema e país de quem pede — cada canal traz `social.your_fails`, o recorte do SEU ambiente — por isso ela é `Cache-Control: private`.",
      "endpoint": "GET /api/channels"
    },
    {
      "id": "list_languages",
      "name": "list_languages",
      "description": "Idiomas que têm canal tocável, com a contagem de cada um.",
      "endpoint": "GET /api/languages"
    },
    {
      "id": "list_networks",
      "name": "list_networks",
      "description": "Redes e emissoras que têm canal tocável, com a contagem.",
      "endpoint": "GET /api/networks"
    },
    {
      "id": "list_qualities",
      "name": "list_qualities",
      "description": "Qualidades distintas encontradas nos streams do catálogo (em rádio, codec e bitrate).",
      "endpoint": "GET /api/qualities"
    },
    {
      "id": "list_subdivisions",
      "name": "list_subdivisions",
      "description": "Estados e províncias que têm canal tocável.",
      "endpoint": "GET /api/subdivisions"
    },
    {
      "id": "list_cities",
      "name": "list_cities",
      "description": "Cidades que têm canal tocável, filtráveis por país e por estado.",
      "endpoint": "GET /api/cities"
    },
    {
      "id": "get_channel",
      "name": "get_channel",
      "description": "Ficha completa de um canal, com os streams já apontando para o nosso hop.",
      "endpoint": "GET /api/channels/:id"
    },
    {
      "id": "get_channel_guide",
      "name": "get_channel_guide",
      "description": "Programação de hoje do canal (grabada por nós): agora, a seguir e a lista. Disponível nos canais com guia (`guide=1`), com validade de até dois dias. Confira a data da resposta; a ficha traz o resumo em `guide_now`.",
      "endpoint": "GET /api/channels/:id/guia"
    },
    {
      "id": "create_guest",
      "name": "create_guest",
      "description": "Cria guest ipt_… Não pede e-mail nem nada. Guarde o token: perdeu o token, perdeu a biblioteca — a não ser que a conta já o tenha reivindicado (`POST /api/auth/claim`), e aí o que ele guardou está na conta.",
      "endpoint": "POST /api/guest"
    },
    {
      "id": "get_library",
      "name": "get_library",
      "description": "A galeria inteira do dono: pastas, sub-abas, canais e as URLs de feed de cada nível.",
      "endpoint": "GET /api/library"
    },
    {
      "id": "create_category",
      "name": "create_category",
      "description": "Cria tab/categoria pessoal. Teto de 8 pastas por dono. A resposta traz a biblioteca inteira já atualizada — não precisa recarregar `GET /api/library` depois.",
      "endpoint": "POST /api/categories"
    },
    {
      "id": "create_group",
      "name": "create_group",
      "description": "Cria sub-aba numa categoria. Teto de 12 sub-abas por pasta. A resposta traz a biblioteca inteira já atualizada — não precisa recarregar `GET /api/library` depois.",
      "endpoint": "POST /api/groups"
    },
    {
      "id": "add_item",
      "name": "add_item",
      "description": "Adiciona canal à sub-aba. Teto de 40 canais por sub-aba. A resposta diz em que pasta e sub-aba o canal caiu, para a tela abrir no lugar certo. A resposta traz a biblioteca inteira já atualizada — não precisa recarregar `GET /api/library` depois.",
      "endpoint": "POST /api/items"
    },
    {
      "id": "get_history",
      "name": "get_history",
      "description": "Histórico de canais assistidos pelo dono. Exibe somente canais disponíveis no catálogo.",
      "endpoint": "GET /api/history"
    },
    {
      "id": "record_watch",
      "name": "record_watch",
      "description": "Registra um canal assistido no histórico do dono.",
      "endpoint": "POST /api/history"
    },
    {
      "id": "forget_watch",
      "name": "forget_watch",
      "description": "Tira um canal do histórico do dono.",
      "endpoint": "DELETE /api/history/:channel_id"
    },
    {
      "id": "clear_history",
      "name": "clear_history",
      "description": "Limpa o histórico inteiro do dono, de uma vez.",
      "endpoint": "DELETE /api/history"
    },
    {
      "id": "legacy_stream",
      "name": "legacy_stream",
      "description": "Metadados públicos: site oficial do canal, URL da transmissão para copiar em outro player e player legado HTTP. O botão legacy_url abre http://legacy.gradetv.net:8080/legacy?stream=ID. A página isolada aceita lang=pt/en/es/fr/de e theme=light/dark. Playlists continuam pelo hop HTTPS e mídia direto da origem. Não remove recusa de acesso nem exigência CORS. Uma leitura indexada; não busca origem nem grava no D1.",
      "endpoint": "GET /api/legacy/:id"
    },
    {
      "id": "producer_services",
      "name": "producer_services",
      "description": "Oferta de transmissão autorizada sob consulta: informações e contatos para produtores. Não ativa streams. Somente informações e captação de interesse. Não provisiona, não cobra e não ativa transmissão. Use contact.form_url no browser, contact.email por e-mail ou POST /api/contact para apresentar o projeto. O envio é livre — sem captcha nem pagamento —, uma mensagem a cada 10 s por rede.",
      "endpoint": "GET /api/producers"
    }
  ],
  "discovery": {
    "openapi": "https://gradetv.net/openapi.json",
    "llms": "https://gradetv.net/llms.txt",
    "okf": "https://gradetv.net/okf/index.md",
    "numbers": "https://gradetv.net/api/vitrine",
    "partnerships": "https://gradetv.net/api/partners",
    "api_catalog": "https://gradetv.net/.well-known/api-catalog",
    "x402": "https://gradetv.net/.well-known/x402",
    "pricing": "https://gradetv.net/pricing",
    "docs": "https://gradetv.net/docs"
  },
  "updated": "2026-10-03"
}