Tema
Empacotar um .adapp
Pacotes .adapp são gerados pelo comando Artisan mcp:pack-app. Ele monta o manifest.json, calcula o checksum e grava o ZIP — você nunca escreve esses arquivos na mão.
Assinatura do comando
bash
php artisan mcp:pack-app
{catalog?} # ID (UUID) ou name (slug) de um McpCatalog a empacotar
{--openapi=} # caminho do spec OpenAPI (.json ou .yaml/.yml) — modo alternativo
{--out=} # caminho de saída do .adapp
{--endpoint=} # endpoint HTTPS do servidor MCP
{--name=} # slug do pacote (OBRIGATÓRIO no modo --openapi)
{--label=} # label legível
{--description=} # descrição
{--category=} # categoriaSem --out, o pacote é gravado em storage/app/adapp/.
Modo catálogo
Empacota um McpCatalog já existente (e o McpServer associado, se houver).
bash
php artisan mcp:pack-app atende-direito --out=atende-direito.adapp- Se o catálogo tiver um
McpServervinculado, oendpointé lido deMcpServer.config(chavesendpointouurl). - Se não houver server associado, informe
--endpointexplicitamente. - O manifest gerado leva
tools[]+ os arquivostools/*.jsona partir das tools já persistidas do servidor.
bash
php artisan mcp:pack-app <uuid-do-catalogo> --endpoint=https://mcp.exemplo.com/v1Modo OpenAPI
Empacota diretamente a partir de um spec OpenAPI, sem passar por um catálogo existente.
Tenha um spec OpenAPI válido (
.json,.yamlou.yml) com pelo menos um servidor emservers[], URL HTTPS e porta 443 — outras portas são rejeitadas.Rode o comando informando
--openapi,--namee--out(obrigatórios neste modo):bashphp artisan mcp:pack-app --openapi=spec.json \ --name=minha-api \ --label="Minha API" \ --out=minha-api.adappSe o spec não tiver
servers[0].urlutilizável, informe o endpoint manualmente:bashphp artisan mcp:pack-app --openapi=spec.json \ --name=minha-api --label="Minha API" --out=minha-api.adapp \ --endpoint=https://api.exemplo.comO comando gera
manifest.json(comtransport: openapi) +openapi.jsondentro do ZIP. As tools não são materializadas no pacote — só serão derivadas no momento do import.
OpenAPI → tools
No import, o conversor deriva uma tool para cada combinação path + método HTTP:
- Nome da tool: usa
operationIdquando presente; senão o fallback émetodo_path(slug do path template, ex.:get_v1_test). inputSchema: montado a partir deparameters(path/query/header) +requestBody(application/json).required_secrets: derivados dossecurity schemesdo spec, no formato{ key, label, required }.http_binding: gerado automaticamente por tool (ver Manifesto → http_binding).
Resolução de $ref no spec é só local (#/components/...) — referências externas não são seguidas — com profundidade máxima de 10 níveis, como proteção anticiclo.
Regras de endpoint e porta
O(s) servidor(es) em servers[] do spec precisam respeitar:
- URL HTTPS obrigatória.
- Porta 443, OU qualquer porta ≥ 1024 que não esteja na blocklist.
- Portas < 1024 são bloqueadas.
- Blocklist explícita, independente da faixa:
8080,8443,9090,9200,5432,6379,11211.
Security schemes suportados
| Suportado | Rejeitado (422) |
|---|---|
apiKey (em header ou query) | oauth2 |
http com bearer | openIdConnect |
http com basic | apiKey em cookie |
Cada scheme suportado vira uma entrada em required_secrets ({ key, label, required }) e o credential_ref da tool aponta para ela (ex.: "required_secrets[0].key").
Ícone
Ícones não são baixados por URL — isso é uma decisão de segurança para evitar SSRF durante o empacotamento. Só arquivos locais com extensão png, jpg, jpeg ou webp são embarcados no pacote; caso contrário, manifest.icon fica null.
Próximos passos
- Importar um .adapp — como publicar o pacote gerado no catálogo global.
- Templates e exemplos — receita fim-a-fim (gerar → empacotar → importar).
