HasData Instagram MCP Server
Perfis públicos do Instagram e feeds de postagens por nome de usuário, com hashtags e menções analisadas.
Documentação
Servidor MCP do Instagram
Um servidor de Model Context Protocol (MCP) hospedado que oferece ao Claude, Cursor, Windsurf e qualquer outro cliente MCP duas ferramentas somente leitura do Instagram. Consulte um perfil público pelo nome de usuário e percorra o feed público de postagens, como JSON estruturado.
Ele lê dados públicos sobre contas. Ele não age como uma conta. Não há nada para conectar e nenhuma conta sua envolvida em nenhum ponto do fluxo.
1.000 créditos grátis todo mês, sem necessidade de cartão, o que equivale a 100 chamadas ao Instagram.
https://mcp.hasdata.com/mcp?apis=instagram
Conteúdo
- O que você precisa
- Início rápido
- Exemplos de prompts
- Ferramentas
- Erros e caminhos de falha
- Preços, plano gratuito e limites
- Seleção de ferramentas
- Como se compara
- Perguntas frequentes
- Links do HasData
- Desenvolvimento
- Contribuição
- Licença
O que você precisa
Um cliente MCP que fale HTTP transmitível com cabeçalhos personalizados. Uma chave de API do HasData do painel de controle, gratuita para criar sem cartão, e o plano gratuito cobre 100 chamadas por mês. Nada mais. Este é um servidor remoto, então o caminho mais simples é uma URL e um cabeçalho, sem contêiner para executar. Um cliente somente stdio pode usar o inicializador @hasdata/instagram-mcp (npm) ou hasdata-instagram-mcp (PyPI).
Início rápido
| URL | https://mcp.hasdata.com/mcp?apis=instagram |
| Transporte | HTTP, transmitível |
| Cabeçalho de autenticação | x-api-key: HASDATA_API_KEY |
A URL do servidor é a mesma para todos os clientes. Nós a executamos na prática no Claude Code e no Claude Desktop. Os outros blocos seguem o formato documentado de cada cliente para um servidor remoto.
Clientes com suporte a OAuth podem adicionar a mesma URL como um conector e entrar sem colocar uma chave em um arquivo de configuração.
Claude Code
claude mcp add --transport http instagram "https://mcp.hasdata.com/mcp?apis=instagram" \
--header "x-api-key: HASDATA_API_KEY"
Claude Desktop
O Claude Desktop carrega apenas servidores locais (stdio) do arquivo de configuração, então ele alcança um servidor remoto por meio de um inicializador stdio. O pacote @hasdata/instagram-mcp é esse inicializador, e ele lê a chave do ambiente.
claude_desktop_config.json:
{
"mcpServers": {
"instagram": {
"command": "npx",
"args": ["-y", "@hasdata/instagram-mcp"],
"env": { "HASDATA_API_KEY": "YOUR_KEY" }
}
}
}
Prefere Python em vez de Node? Troque o inicializador pelo pacote PyPI, que o uvx executa sem instalação manual:
{
"mcpServers": {
"instagram": {
"command": "uvx",
"args": ["hasdata-instagram-mcp"],
"env": { "HASDATA_API_KEY": "YOUR_KEY" }
}
}
}
Um cliente com suporte a OAuth pode, em vez disso, adicionar a URL como um conector personalizado e pular o inicializador.
Cursor
.cursor/mcp.json:
{
"mcpServers": {
"instagram": {
"url": "https://mcp.hasdata.com/mcp?apis=instagram",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}
Windsurf
~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"instagram": {
"serverUrl": "https://mcp.hasdata.com/mcp?apis=instagram",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}
Cline
{
"mcpServers": {
"instagram": {
"url": "https://mcp.hasdata.com/mcp?apis=instagram",
"type": "streamableHttp",
"headers": { "x-api-key": "HASDATA_API_KEY" },
"disabled": false
}
}
}
VS Code
.vscode/mcp.json:
{
"servers": {
"instagram": {
"type": "http",
"url": "https://mcp.hasdata.com/mcp?apis=instagram",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}
Gemini CLI
~/.gemini/settings.json:
{
"mcpServers": {
"instagram": {
"httpUrl": "https://mcp.hasdata.com/mcp?apis=instagram",
"headers": { "x-api-key": "HASDATA_API_KEY" }
}
}
}
Exemplos de prompts
Cada um destes é uma chamada de ferramenta, a menos que a contagem diga o contrário.
Busque o perfil de
@nasae me diga o número de seguidores, se é verificado e todos os links na biografia.
Uma chamada, 10 créditos. Para uma conta pública, a resposta do perfil já traz as doze postagens mais recentes, então uma pergunta de acompanhamento sobre atividade recente não precisa de uma segunda chamada.
Compare
@nasa,@natgeoe@bbcearthem seguidores, contas seguidas e se cada uma é verificada.
Três chamadas, 30 créditos. Uma por nome de usuário.
Percorra as últimas cinquenta postagens de
@nasae liste cada hashtag com a frequência com que aparece.
Cinco chamadas, 50 créditos. Doze postagens chegam por chamada, e cinquenta exigem cinco páginas.
Para as últimas doze postagens de
@natgeo, liste as contas mencionadas em cada legenda e o tipo de cada postagem.
Uma chamada, 10 créditos. Menções e hashtags chegam já extraídas da legenda nos objetos de postagem.
Duas coisas fazem isso funcionar. Hashtags e menções chegam como matrizes extraídas da legenda, e um agente as conta em vez de executar uma regex sobre o texto. E uma consulta de perfil retorna o feed recente na mesma resposta. É por isso que tantas perguntas de pesquisa são resolvidas em uma única chamada.
Ferramentas
| Ferramenta | O que retorna |
|---|---|
hasdata_instagram_comments_getInstagramComments | Busca os comentários de uma postagem ou reel público pela URL e retorna a própria postagem com sua legenda, mídia, likesCount, commentsCount e timestamp, depois cada comentário com seu texto, número de curtidas, data e autor. 10 créditos por chamada |
hasdata_instagram_posts_getInstagramPosts | Busca as postagens mais recentes de uma conta pública do Instagram pelo nome de usuário (handle) e retorna cada postagem com seu id, shortcode, legenda, tipo, productType, link permanente, URLs de mídia e tamanho em pixels, contagens de curtidas e comentários, horário da publicação, além de hashtags, menções, usuários marcados e membros de carrossel. 10 créditos por chamada |
hasdata_instagram_profile_getInstagramProfile | Busca um perfil público do Instagram pelo nome de usuário (handle) e retorna id, nome completo, biografia, links da bio, URL da foto de perfil, contagens de seguidores e seguidos, o indicador de verificado e as doze postagens mais recentes. 10 créditos por chamada |
Três ferramentas, todas somente leitura. Duas são baseadas no handle de uma conta pública, a terceira na URL de uma única postagem. Os exemplos abaixo foram reduzidos de chamadas reais, e os números neles mudam conforme as contas publicam. Leia-os como formatos. O nome de cada ferramenta leva à referência do endpoint.
Os exemplos são o payload, não a resposta inteira. Um resultado tools/call carrega um bloco de texto, e esse texto é em si JSON contendo url, status, text e json, com os dados extraídos sob json. De uma resposta JSON-RPC bruta, o caminho é result.content[0].text, analisado, depois .json. Um cliente de chat desembrulha isso para você, e código que fala diretamente com o endpoint não faz isso.
Obter um perfil do Instagram
hasdata_instagram_profile_getInstagramProfile
Um perfil público por handle.
| Parâmetro | Tipo | Obrigatório | Observações |
|---|---|---|---|
handle | string | sim | Nome de usuário sem o @, como aparece na URL do perfil |
Retorna id, username, fullName, biography, verified, os contadores followersCount e followsCount, profilePicUrl, o fbid interno, a matriz bioLinks e latestPosts.
O que é garantido e o que não é, medido em vinte contas: id, username, followersCount, followsCount, profilePicUrl e fbid vieram todas as vezes. fullName, biography, verified, bioLinks e latestPosts vieram para toda conta pública e são os que devem ser lidos com um valor padrão.
Uma conta privada responde com
private: truee pouco mais. Sem biografia, sem contadores além dos números de seguidores, sem postagens. Faça uma ramificação nesse indicador antes de tocar no restante do payload.
bioLinksé uma matriz de objetos, não de strings. Cada entrada carregaurl,title, o wrapperredirectUrldo próprio Instagram elinkType. Leia.urlquando quiser o destino.
{
"id": "528817151",
"username": "nasa",
"fullName": "NASA",
"biography": "Making the seemingly impossible, possible. ✨",
"verified": true,
"followersCount": 104345698,
"followsCount": 91,
"profilePicUrl": "https://scontent.cdninstagram.com/v/t51.2885-19/…",
"fbid": "17841401474538262",
"bioLinks": [
{
"url": "https://www.nasa.gov",
"title": "NASA.gov Homepage",
"redirectUrl": "https://l.instagram.com/?u=https%3A%2F%2Fwww.nasa.gov%2F&e=…",
"linkType": "external"
}
],
"latestPosts": [ "…the most recent posts, same shape as the posts tool…" ]
}
Obter postagens do Instagram
hasdata_instagram_posts_getInstagramPosts
O feed público de postagens de um handle, página por página.
| Parâmetro | Tipo | Obrigatório | Observações |
|---|---|---|---|
handle | string | sim | Nome de usuário sem o @ |
limit | número | Limite aproximado de postagens em uma resposta. Doze é o máximo real, e valores maiores não buscam mais | |
nextPageToken | string | O pagination.nextPageToken da resposta anterior |
limité um limite aproximado, não uma contagem exata. Doze postagens é uma página do Instagram e o teto máximo para uma única chamada, elimit: 50retorna doze. Abaixo do teto, a contagem chega perto do número solicitado sem sempre corresponder a ele, e o quão perto depende da conta. Medido em@nasa, um limite de 2 retornou 4 postagens, 6 retornou 6, 11 retornou 10 e 13 retornou 12. Trate como "não mais que aproximadamente isso" e leia o comprimento da matriz em vez de presumir.
A resposta carrega posts e pagination, e nada mais. Versões anteriores repetiam os campos de identidade da conta junto com o feed, então código escrito para esse formato precisa de uma chamada de perfil para nome e avatar.
Cada postagem carrega id, shortcode, caption, type, productType, url, ownerUsername, ownerId, displayUrl e images, o tamanho em pixels como dimensionsWidth e dimensionsHeight, e hasdataLink, um link pronto para o endpoint de comentários daquela postagem. hashtags e mentions aparecem apenas quando a legenda os tem. Um carrossel carrega seus membros em childPosts, e taggedUsers lista as contas marcadas na mídia.
Os contadores de engajamento chegam com o feed. Cada postagem carrega
likesCountecommentsCount, e o horário da publicação duas vezes:timestampcomo um instante ISO completo epublishDatecomo o dia do calendário. Classificar um feed por popularidade ou filtrá-lo por data não precisa de uma segunda chamada. Isso mudou em 2026-10-07; versões anteriores do payload não carregavam nenhum dos quatro.
{
"posts": [
{
"id": "3983374110243288826",
"shortcode": "DdHyaYAifb6",
"caption": "Cementing their names in history.\n\nThe Artemis III crew is leaving their mark […] @NASAKennedy",
"type": "Carousel",
"productType": "carousel_container",
"mentions": ["@NASAKennedy", "@EuropeanSpaceAgency", "@Astro_Luca"],
"url": "https://www.instagram.com/p/DdHyaYAifb6/",
"hasdataLink": "https://api.hasdata.com/scrape/instagram/comments?url=…",
"commentsCount": 1053,
"likesCount": 121490,
"dimensionsWidth": 1440,
"dimensionsHeight": 1800,
"displayUrl": "https://scontent.cdninstagram.com/v/t51.…",
"images": ["https://scontent.cdninstagram.com/v/t51.…"],
"timestamp": "2026-09-10T21:20:24.000Z",
"publishDate": "2026-09-10",
"ownerUsername": "nasa",
"ownerId": "528817151",
"taggedUsers": [{ "id": "549403870", "username": "nasakennedy", "fullName": "NASA's Kennedy Space Center" }],
"childPosts": [{ "id": "3983374043612570267", "type": "Image", "productType": "carousel_item" }]
}
],
"pagination": {
"morePostsAvailable": true,
"nextPageToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…",
"hasdataLink": "https://api.hasdata.com/scrape/instagram/posts?handle=nasa&nextPageToken=…"
}
}
Hashtags e menções mantêm seus prefixos # e @, o que importa se você estiver juntando-os a uma lista que você mesmo construiu. morePostsAvailable é o indicador para ramificar ao paginar, e hasdataLink é a mesma próxima página expressa como uma URL REST, útil quando você quer reproduzir a chamada de um agente manualmente.
Obter os comentários de uma postagem
hasdata_instagram_comments_getInstagramComments
O fio de comentários sob uma postagem ou reel, e a própria postagem.
| Parâmetro | Tipo | Obrigatório | Observações |
|---|---|---|---|
url | string | sim | Um link /p/, /reel/ ou /tv/, com ou sem o segmento de nome de usuário |
nextPageToken | string | Token da resposta anterior | |
includeMusic | booleano | Também retorna o som de um reel em post.music, tanto para faixas licenciadas quanto para áudio original |
Use isto quando o próprio fio de comentários for o ponto. O objeto post repete os números de engajamento que o feed já carrega, então classificar ou datar um feed não precisa desta chamada, e gastar uma requisição por postagem para coletar números que chegaram com o feed é desperdício.
Retorna post, comments e pagination. Um comentário carrega id, text, timestamp, likesCount e um owner com id, username e profilePicUrl. pagination informa moreCommentsAvailable ao lado de nextPageToken, então uma caminhada pode parar sem gastar uma requisição para descobrir o fim.
{
"post": {
"shortcode": "DdHyaYAifb6",
"type": "Carousel",
"productType": "carousel_container",
"ownerUsername": "nasa",
"timestamp": "2026-09-10T21:20:24.000Z",
"likesCount": 120648,
"commentsCount": 1020
},
"comments": [
{
"id": "18188486875408374",
"text": "I like to become a astronomer",
"timestamp": "2026-10-05T07:38:17.000Z",
"likesCount": 0,
"owner": { "id": "40744210101", "username": "nisha_karippolil" }
}
],
"pagination": { "moreCommentsAvailable": true, "nextPageToken": "…" }
}
Prompts e recursos
O servidor oferece um prompt, um fluxo de trabalho pronto que um cliente pode oferecer em vez de fazer o usuário compor uma chamada de ferramenta.
| Prompt | O que faz |
|---|---|
instagram_profile | Consulta um perfil público do Instagram. |
A lista é servida sem chave de API, então um cliente pode lê-la antes de o usuário se cadastrar.
Erros e caminhos de falha
Seu cliente quase nunca vê um código de erro HTTP vindo de uma chamada de ferramenta. A camada MCP responde com 200 e coloca a falha dentro do resultado, com isError definido como true e o motivo como texto. O agente lê uma mensagem onde você poderia esperar uma linha de status.
Uma chave errada aparece como saída de ferramenta, não como conexão falha. Listar ferramentas aceita qualquer chave não vazia, e o cliente completa o handshake e mostra verde. A primeira chamada de ferramenta então retorna com isError: true e o texto HasData API error: 401 Unauthorized. Fique atento a essa string, porque nada antes no fluxo reporta o problema.
Uma chave ausente é o único erro HTTP real. A autorização roda antes de qualquer ferramenta, e a conexão em si falha com 401.
Um argumento que quebra o schema é rejeitado antes de virar uma requisição. O servidor responde com isError: true e o texto MCP error -32602: Input validation error, nomeando o campo. Nada é buscado e nada é cobrado.
Um handle que não resolve é um erro limpo, não dados vazios. Ele retorna isError: true com HasData API error: 400 Bad Request e requestMetadata.status definidos como error. Esse é o caso bom, porque a falha é inequívoca. Teste a flag em vez do comprimento do array.
Uma conta cujos dados não são públicos não retorna feed de posts. As ferramentas cobrem contas públicas, e não há nada para ler em uma que não é. Trate um latestPosts ausente como fora de escopo e não como um feed vazio.
Resultados que carregam dados também carregam um requestMetadata.id que vale citar no suporte, além de links html e json para o artefato armazenado daquela chamada exata.
Preços, plano gratuito e limites
Cada ferramenta do Instagram custa 10 créditos por chamada bem-sucedida. O tamanho da resposta não muda o preço. Um perfil com doze posts anexados custa o mesmo que um sem nenhum.
O plano gratuito é 1.000 créditos todo mês sem cartão, ou 100 chamadas do Instagram. Ele renova com o ciclo de cobrança, então um agente de baixo volume roda no plano gratuito indefinidamente.
Planos pagos começam em US$ 59 por mês para 200.000 créditos, ou 20.000 chamadas. O preço unitário cai com o volume, de US$ 2,95 por 1.000 chamadas no plano inicial para US$ 1,19 no Basic e US$ 0,83 nos níveis Growth. Os valores atuais estão na página de preços.
Seu plano também define concorrência. O plano gratuito permite 1 requisição por vez, o Startup 5, o Basic 15, e os níveis Growth vão de 50 a 500. Trate o caso de estouro defensivamente em qualquer coisa não supervisionada, porque um agente que se espalha por vários handles vai atingir o teto antes de você.
Paginação custa uma chamada a cada vez. Um prompt que percorre cem posts em duas contas são dezoito chamadas e 180 créditos. O plano gratuito rende mais em comparações de perfil do que em rastreamentos profundos de feed.
Seleção de ferramentas
?apis=instagram expõe exatamente essas duas ferramentas. O parâmetro aceita uma lista, e ?apis=instagram,tiktok,youtube dá ao seu agente três plataformas sociais de uma vez. Remova o parâmetro e você obtém tudo o que a HasData expõe, que atualmente são 57 ferramentas.
Uma lista estreita geralmente é o padrão melhor. Um modelo escolhendo entre duas ferramentas acerta com mais frequência do que um escolhendo entre cinquenta e sete, e as próprias descrições das ferramentas custam contexto a cada turno.
Comparação entre plataformas é o motivo usual para ampliar a lista. Faça a mesma pergunta a um handle do Instagram e a um do TikTok e é um único prompt, uma vez que ambos estejam expostos.
Como ele se compara
Quase todo servidor MCP do Instagram faz algo diferente deste, e isso torna a escolha excepcionalmente clara.
Os populares operam uma conta. Alguns envolvem a Instagram Graph API para publicar posts, ler comentários e gerenciar as contas que você administra. Outros lidam com mensagens diretas. Os servidores de análise de engajamento pedem INSTAGRAM_USERNAME e INSTAGRAM_PASSWORD em um bloco de env, conforme suas próprias instruções de configuração, porque eles fazem login e navegam como você. Todos esses são a ferramenta certa quando o trabalho é operar uma conta que você controla.
Este servidor nunca faz login como ninguém, o que é um trabalho diferente. Cada pergunta que ele responde é sobre um handle que você não possui, e a chamada é idêntica seja qual for o handle.
| Servidor que opera conta | Este servidor | |
|---|---|---|
| Como atua | Sua conta, via token ou sessão | Nada, ele lê dados públicos |
| O que você configura | Credenciais ou um app da Graph API, por conta | Uma chave de API, uma vez |
| Quais handles cobre | As contas que você administra | Qualquer handle público |
| Publicação e mensagens | Sim, esse é o objetivo | Não oferecido |
| Saída | Limitada à conta que você opera | JSON para qualquer handle público, hashtags e menções parseadas |
| O que você executa | Um processo Python ou Node localmente | Uma URL e um header |
| Custo | Grátis | 10 créditos por chamada |
Duas linhas decidem. Se você precisa publicar, comentar ou responder, este servidor não pode ajudar em nada. Se você precisa dos mesmos campos em cem handles com os quais não tem relação, um servidor construído em torno das suas próprias credenciais também não pode ajudar.
O eixo decisivo é escopo, não polimento. Um servidor construído em torno do seu próprio login só alcança as contas que você administra, por melhor que seja sua saída. Este responde à mesma pergunta para qualquer handle público, e os campos voltam como arrays parseados que não custam nada para agregar.
O que este servidor não faz. Sem comentários, sem stories, sem reels além do que o feed reporta, sem mensagens diretas, sem busca por hashtag ou localização, e nada que escreva. Ele lê duas coisas bem.
FAQ
O que é um servidor MCP do Instagram?
Um servidor que expõe dados do Instagram como ferramentas que um cliente de IA pode chamar. O cliente envia uma chamada de ferramenta pelo Model Context Protocol, o servidor busca os dados e retorna JSON estruturado, e o modelo trabalha com o resultado e nunca vê uma página de HTML. Este expõe duas ferramentas somente leitura e roda remotamente. O cliente conecta a uma URL e não inicia nenhum processo local.
Existe um servidor MCP oficial do Instagram?
A Meta não publica um de propósito geral. Existe um MCP oficial para publicidade da Meta, e ele cobre contas de anúncios e campanhas, não dados de perfil e posts. Todo o resto nesse espaço é construído por terceiros.
Quais dados estão no escopo?
Campos públicos de perfil e o feed público de posts, para contas públicas, por handle. Uma conta privada ainda retorna seu cabeçalho, as contagens de seguidores e seguindo e uma flag private: true, mas sem biografia e sem posts, já que não há feed público para ler. Você é responsável por como usa os resultados, incluindo conformidade com os termos do Instagram e com a lei que se aplica a você.
Preciso hospedar ou executar algo?
Não. Este é um servidor MCP remoto em HTTP streamable. Nada para instalar, sem ambiente Python, sem processo para reiniciar.
Os dados são ao vivo ou em cache?
Ao vivo. Cada chamada busca no momento da requisição e carrega seu próprio requestMetadata.id. Duas chamadas idênticas são duas buscas separadas e não uma reprodução de uma cópia armazenada. Contadores como seguidores e curtidas acompanham a conta e se movem conforme ela se move.
Quantos posts posso obter?
Doze por chamada, uma página do Instagram, e páginas adicionais vêm de pagination.nextPageToken. Para uma conta pública, a consulta de perfil inclui os mesmos doze sem custo extra, então perguntas curtas de feed muitas vezes não precisam de nenhuma chamada de posts.
O que acontece quando o Instagram muda seu markup?
Nada do seu lado. Nós acompanhamos as mudanças e mantemos o schema de resposta estável, e nomes e tipos de campos permanecem. Um campo sem valor fica ausente do item em vez de presente e nulo, e é por isso que campos opcionais devem ser lidos com um padrão.
Posso usar um servidor para várias plataformas?
Sim. O parâmetro apis aceita uma lista, e ?apis=instagram,tiktok,youtube dá ao seu agente três plataformas de uma vez.
Quais clientes funcionam?
Qualquer cliente MCP que suporte HTTP streamable com headers personalizados. As configurações acima são testadas. Clientes com suporte a OAuth podem adicionar a URL como um conector.
Links da HasData
| Páginas de produto e construtor de requisições | Instagram Profile API e Instagram Posts API |
| Documentação do servidor | Docs do servidor MCP |
| Todas as 57 ferramentas em um servidor | HasData/hasdata-mcp |
| Tutoriais de clientes | Clientes MCP e integrações |
| As outras plataformas que parseamos | Mais 53 APIs de scraping |
| Planos e custos de créditos | Planos e custos de créditos |
| Chaves e uso | Painel da HasData |
| Lançador Node no npm | @hasdata/instagram-mcp |
| Lançador Python no PyPI | hasdata-instagram-mcp |
Desenvolvimento
Este repositório é configuração e documentação para um servidor remoto. Não há etapa de build e nada para containerizar.
Ele carrega um teste de contrato. O README promete duas ferramentas com parâmetros específicos, e a lista de ferramentas upstream pode mudar sem um commit aqui, e isso deixaria este arquivo silenciosamente mentindo para você. O teste afirma a promessa e roda semanalmente no CI, além de a cada push.
HASDATA_API_KEY=your_key_here npm test
No PowerShell:
$env:HASDATA_API_KEY = "your_key_here"; npm test
A última verificação faz uma chamada real e custa 10 créditos, que é o preço de um canário que pode falhar pelo motivo certo. Listar ferramentas funciona com qualquer chave não vazia, e um teste que só lista ferramentas permanece verde com uma chave revogada.
Contribuindo
Correções nas tabelas de ferramentas e nos exemplos de resposta são a contribuição mais útil, porque essas são as partes que se desatualizam. Inclua a chamada que você fez e a resposta que obteve. Pull requests de forks rodam a suíte sem chave, e as verificações ao vivo pulam em vez de ficarem vermelhas.
Licença
MIT. Veja LICENSE.