kond-royalties-agent
Allows querying royalty performance data from Sony Music (Somlivre) including metrics like royalties, quantity, and dimensions such as artist, period, and origin.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@kond-royalties-agentMostre os royalties do artista Anitta em 2024"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
KOND Royalties Agent
V1 simplificada do agente analitico da KOND.
Arquitetura:
agente customizado
servidor MCP (Streamable HTTP para producao)
Postgres (multiplos schemas) como fonte principal
catalogo semantico em PT-BR
relatorios em PDF como artefatos
Objetivo
Responder perguntas de performance de royalties de artistas com:
linguagem natural em portugues do Brasil
metricas semanticas consistentes, com dominios deliberadamente separados: royalties (streams, unidades, royalties) e financeiro (receita, custo do ERP Omie) — ver referencia de vocabulario abaixo
graficos e tabelas como artefatos
relatorios PDF sob demanda
Related MCP server: dbecho
Escopo da V1
Postgres direto (uma conexao, varios schemas via
search_path)sem frontend proprio
foco em MCP + prompts + artefatos
hospedagem compartilhada em producao (Docker + Caddy + OAuth)
Estrutura
docs/: visao de arquitetura e decisoesmcp_server/: servidor MCP e ferramentasprompts/: instrucoes do agente e exemplosreporting/: geracao de artefatos e PDFsemantic_catalog/: metricas, dimensoes e fontes aprovadasconfig/: conexao Postgres e dicionario de colunastests/: testes unitarios iniciaisDockerfile,docker-compose.yml: imagem e deploy do transporte HTTP
Status do schema de dados
Revalidado em 2026-07-24 contra o Postgres de producao. O agente consulta
public.vw_ft_dados_analiticos_union, uma view que unifica a performance de
royalties de todas as origens/distribuidoras de audit (DSU, Orchard,
Universal, Warner Chappell, Warner Music) por artista e periodo (mes).
Separacao royalties x financeiro (2026-07-24): Omie (ERP financeiro —
contas a pagar/receber) foi removido desta view — era uma inclusao parcial
e acidental (ver TODO.md, secao Resolvido), e semanticamente e um
dominio diferente de royalty. Omie agora vive exclusivamente na fonte
omie_detail, com metricas e vocabulario proprios (Receita/Custo/
Resultado), deliberadamente distintos de Royalties/Direitos autorais para
nunca serem confundidos/somados numa mesma resposta — ver a referencia de
vocabulario abaixo. Colunas da view unificada tambem foram renomeadas para
PT-BR nesse mesmo dia.
Ver config/postgres_sources.yml e config/column_dictionary.yml para o
detalhe completo (incluindo notas de qualidade de dados) e TODO.md para
pendencias de investigacao.
Referencia de vocabulario: metricas, colunas e sinonimos
Cada fonte do catalogo semantico (semantic_catalog/catalog.yml) declara
seus proprios metrics/dimensions, com expression_hint resolvendo para
a coluna real. O planner (mcp_server/planner.py) infere fonte/metrica a
partir de palavras-chave da pergunta em PT-BR — a tabela abaixo documenta
esse mapeamento.
Metricas
Metric key | Dominio | Label (PT) | Coluna/expressao real | Onde existe | Sinonimos (roteamento por pergunta) |
| Royalty | Royalties |
|
| royalties, royalty, direitos autorais, remuneração autoral, repasse, arrecadação, monetização |
| Ambos | Quantidade |
|
| quantidade, streams, unidades, shows, quantity, reproduções, playback, plays, play |
| Financeiro (Omie) | Receita |
| so | receita, faturamento |
| Financeiro (Omie) | Custo |
| so | custo, custos, despesa, despesas |
| Financeiro (Omie) | Resultado |
| so | lucro, resultado (roteiam a fonte, nao a metrica) |
| Financeiro (Omie) | A pagar/receber |
| so | sem sinonimo dedicado — so via parametro |
Dimensoes (royalty_performance/uniao)
Dimension key | Coluna real | Label (PT) | Sinonimos |
|
| Periodo | periodo, por mes, por data, mensal, anual, trimestre, semestre, data, dia, ano, mês |
|
| Artista | artista, artist, cantor, cantora, banda, grupo, mc, dj, intérprete, talento, dupla, projeto, collab, colab |
|
| Origem | origem, distribuidora, sistema de origem, publisher, plataforma, fonte |
|
| Tipo de royalty | tipo de royalty, categoria de royalty, tipo de receita, categoria de receita, revenue type, tipo de arrecadação, tipo de faturamento, rubrica, linha de receita |
| subquery via | Gravadora | gravadora, label, selo, master, master rights, produtora, companhia, produtora fonográfica |
Roteamento de fonte (qual dominio uma pergunta acessa)
Fonte | Gatilho | Sinonimos |
| fallback padrao | usada quando nada abaixo casa |
| palavra-chave isolada | omie, financeiro, fluxo de caixa, contas a pagar, contas a receber, erp, receita, custo, custos, despesa, despesas, lucro, resultado |
| palavra-chave isolada | show, shows, evento, eventos, contrato de show |
| nome da plataforma + palavra-chave de faixa | plataforma: orchard / universal / som livre, somlivre, sony(music) / warner chappell(l) / warner music — combinada com: faixa, musica, compositor, isrc, obra, cancao, track |
royalties e revenue/cost nunca coexistem na mesma fonte (validado por
query_builder.py contra o catalogo) — a separacao e estrutural, nao so
cosmetica.
Deploy em producao (Docker)
O servidor roda como container Docker expondo o transporte Streamable HTTP
(mcp_server/mcp_http.py, comando serve-http), atras de um reverse proxy
Caddy que ja atende outros servicos no mesmo host. Isso permite que varias
pessoas/clientes usem o agente sem cada um precisar de credenciais de
Postgres localmente.
Deploy rapido
scripts/deploy.sh
scripts/deploy.sh "Como foi a receita por artista nos ultimos 90 dias?" # + testa ask_royaltiesSincroniza o codigo para kern-data, reconstroi a imagem, reinicia o
container e roda smoke tests (metadados RFC 9728, token estatico, e
opcionalmente um ask_royalties real se uma pergunta for passada). Nao
toca no Caddyfile nem no restante do .env remoto — exceto
MCP_API_KEYS, que e sincronizado a partir do .env LOCAL quando
definido. Para rotacionar o token estatico: editar MCP_API_KEYS no
.env local e rodar scripts/deploy.sh normalmente.
Imagem e container
Dockerfile na raiz constroi a imagem (python:3.12-slim, instala
.[http], expoe a porta 8080). docker-compose.yml define o servico,
carrega .env via env_file, publica uma porta direta no host e conecta
o container na rede Docker externa compartilhada com o Caddy
(kern-prefect_default):
docker compose build
docker compose up -d
docker compose logs --tail=30Variaveis de ambiente (.env)
Ver .env.example para o arquivo completo. Resumo:
Postgres — DATABASE_URL ou PGHOST/PGPORT/PGDATABASE/PGUSER/
PGPASSWORD/PGSSLMODE, mais POSTGRES_SCHEMAS.
OpenAI — OPENAI_API_KEY, OPENAI_MODEL.
Autenticacao HTTP (mcp_server/oauth.py) — pelo menos uma das duas
precisa estar configurada, o processo recusa iniciar sem nenhuma:
MCP_API_KEYS: lista de tokens Bearer estaticos, separados por virgula — caminho rapido, sem chamada de rede, para clientes que aceitam um header customizado (Antigravity, scripts)OAUTH_ISSUER_URL+OAUTH_RESOURCE_URL: delegacao OAuth 2.1 para um IdP externo (Auth0 em producao) — necessario para clientes que fazem o fluxo OAuth completo (ex.: conector remoto do claude.ai). Token validado localmente como JWT (assinatura RS256 via JWKS, descoberto automaticamente por OpenID Connect Discovery;iss/aud/expconferidos).OAUTH_JWKS_URLeOAUTH_REQUIRED_SCOPESsao opcionais.
Os dois mecanismos coexistem no mesmo processo: o verificador tenta o token estatico primeiro (sem custo de rede), depois valida como JWT do IdP.
Sempre, independente do metodo de auth:
MCP_ALLOWED_HOSTS: hosts reais (dominio[:porta]) usados neste deploy, para satisfazer a protecao contra DNS rebinding do SDKmcpsem desativa-la
Reverse proxy (Caddy)
O deploy de referencia roda em kern-data, atras do Caddy que tambem
atende o Prefect nesse host (KERN-prefect/Caddyfile). Duas rotas sao
necessarias por servico:
kerndata1.ddns.net {
handle /.well-known/oauth-protected-resource/kond-royalties-mcp/* {
reverse_proxy kond-royalties-mcp:8080
}
handle_path /kond-royalties-mcp/* {
reverse_proxy kond-royalties-mcp:8080
}
handle {
reverse_proxy prefect-server:4200
}
encode gzip
}handle_path /kond-royalties-mcp/*: rota principal, com prefixo removido antes de encaminhar ao container.handle /.well-known/oauth-protected-resource/kond-royalties-mcp/*(sem remocao de prefixo): exigida pelo RFC 9728. O SDKmcpregistra o endpoint de metadados usando o caminho completo doOAUTH_RESOURCE_URL(incluindo/kond-royalties-mcp), entao a rota precisa encaminhar a URL original intacta —handle_pathquebraria isso.
Sempre validar antes de recarregar (o Caddyfile atende varios servicos, um erro de sintaxe derruba o roteamento de todos):
docker exec kern-prefect-caddy-1 caddy validate --config /etc/caddy/Caddyfile
docker exec kern-prefect-caddy-1 caddy reload --config /etc/caddy/CaddyfileMultiplos MCPs no mesmo host
kern-data hospeda varios MCPs, um por servico, cada um em uma porta
direta sequencial (alem da rota HTTPS via Caddy):
Porta | Servico |
8080 |
|
8081 |
|
8082+ | reservado para proximos MCPs |
Ao adicionar um novo MCP nesse host: escolher a proxima porta livre,
adicionar kerndata1.ddns.net:PORTA em MCP_ALLOWED_HOSTS daquele
servico, e conectar seu docker-compose.yml na rede externa
kern-prefect_default (mesmo padrao usado aqui) para que o Caddy consiga
alcanca-lo por nome de servico.
OAuth (Auth0) — configuracao do IdP
kond-royalties-mcp delega autenticacao OAuth para um tenant Auth0
dedicado. Passo a passo:
Criar um tenant Auth0 (free tier e suficiente).
Critico: em Settings → Advanced → Settings, habilitar Resource Parameter Compatibility Profile e Include Issuer in Authorization Responses (tenant-wide). Sem isso, o Auth0 ignora silenciosamente o parametro
resourceque os conectores enviam (RFCe cai no comportamento legado baseado em
audience— o sintoma e um erro de token exchange sem pista clara da causa.
Applications → APIs → Create API: Identifier =
OAUTH_RESOURCE_URLexato (ex.:https://kerndata1.ddns.net/kond-royalties-mcp/mcp), Signing Algorithm RS256. Por padrao a API exige Client Grant explicito para autorizar qualquer client (subject_type_authorizationcom policyrequire_client_grantparausereclient) — isso vale para toda aplicacao, first-party ou nao, entao o passo 5 abaixo e obrigatorio para cada client novo.Uma Application dedicada por cliente (tipo Regular Web Application, first-party), cada uma com seu proprio Allowed Callback URL fixo — nao compartilhar a mesma Application entre clientes diferentes. Ver a tabela de modalidades de conexao abaixo para o callback exato de cada um.
Para cada Application criada, autorizar contra a API do passo 3 (Applications → [App] → APIs, ou via Management API
POST /api/v2/client-grantscomsubject_type: "user"— necessario para o fluxo Authorization Code com login real de usuario, distinto dosubject_type: "client"usado em Client Credentials/M2M).Usar o Domain do tenant (com
https://na frente) comoOAUTH_ISSUER_URL, e o Client ID/Client Secret de cada Application ao configurar o respectivo cliente (ver abaixo).
Dynamic Client Registration (DCR) fica desabilitado
(Settings → Advanced → OIDC Dynamic Application Registration, ou via
Management API PATCH /api/v2/tenants/settings com
flags.enable_dynamic_client_registration: false). Clientes que suportam
DCR (ChatGPT/Codex, Antigravity) registram uma Application nova e efemera
a cada conexao — no free tier do Auth0 isso estoura rapido o limite de
apps do tenant e passa a bloquear login de novos usuarios. Com DCR
desligado, todo cliente usa uma Application predefinida (passo 4) com
credenciais coladas manualmente na configuracao do cliente.
Conectando clientes ao servidor remoto
Quatro modalidades de conexao suportadas, todas contra a mesma URL
(https://kerndata1.ddns.net/kond-royalties-mcp/mcp):
Modalidade | Cliente | Autenticacao |
Bearer estatico | scripts, curl, clientes sem suporte a OAuth | Header |
OAuth (Application dedicada) | claude.ai | Login Auth0 + consentimento |
OAuth (Application dedicada) | ChatGPT / Codex | Login Auth0 + consentimento |
OAuth (Application dedicada) | Antigravity | Login Auth0 + consentimento |
Bearer estatico
Para scripts e clientes MCP que aceitam um header customizado direto, sem
fluxo OAuth. Formato mcpServers (alguns clientes usam serverUrl,
outros url — checar a documentacao do cliente especifico):
{
"mcpServers": {
"kond_royalties": {
"serverUrl": "https://kerndata1.ddns.net/kond-royalties-mcp/mcp",
"headers": {
"Authorization": "Bearer <token de MCP_API_KEYS>"
}
}
}
}OAuth — claude.ai
Settings → Connectors → Add → Custom Connectors:
Nome: livre
Remote MCP server URL:
https://kerndata1.ddns.net/kond-royalties-mcp/mcpAdvanced settings → OAuth Client ID / OAuth Client Secret: valores da Application Auth0 "Claude" (callback
https://claude.ai/api/mcp/auth_callbackehttps://claude.com/api/mcp/auth_callback)
Ao clicar Connect, o fluxo redireciona para o login do Auth0, pede consentimento e volta para o claude.ai com o conector conectado.
OAuth — ChatGPT / Codex
Desde a fusao dos dois produtos no app desktop, o cliente que aparece na tela de consentimento do Auth0 se chama "Codex" independente de qual dos dois foi usado para iniciar a conexao.
Pre-requisito: habilitar Developer Mode em chatgpt.com (Configuracoes → Conectores → Avancado, ou Configuracoes de Workspace → Permissoes, dependendo do tipo de conta) — o app desktop sozinho nao consegue invocar tools de conectores customizados sem isso, mesmo que a conexao apareca como bem-sucedida.
Ao adicionar o conector (URL do servidor + credenciais OAuth avancadas),
usar o Client ID / Client Secret da Application Auth0 "ChatGPT-Codex"
(callback fixo https://chatgpt.com/connector_platform_oauth_redirect).
Sem uma Application dedicada, o ChatGPT tentaria DCR automaticamente — ver
nota sobre DCR desabilitado acima.
OAuth — Antigravity
Configuracao central de MCP do Antigravity
(~/.gemini/config/mcp_config.json), com clientId/clientSecret
explicitos da Application Auth0 "Antigravity" (callback fixo
https://antigravity.google/oauth-callback). Sem essas credenciais
explicitas, o Antigravity tentaria DCR automaticamente (suportado
nativamente pelo cliente) — ver nota sobre DCR desabilitado acima.
Verificacao pos-deploy
# metadados RFC 9728 (deve refletir o issuer OAuth configurado)
curl https://kerndata1.ddns.net/.well-known/oauth-protected-resource/kond-royalties-mcp/mcp
# sem token -> 401
curl -X POST https://kerndata1.ddns.net/kond-royalties-mcp/mcp -H "Content-Type: application/json" -d '{}'
# com token estatico -> 200
curl -X POST https://kerndata1.ddns.net/kond-royalties-mcp/mcp \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}'Depois, confirmar que os demais servicos no mesmo host (outros MCPs, Prefect) continuam respondendo normalmente.
Proximos passos
Investigar pendencias de qualidade de dados listadas em
TODO.mdAvaliar enriquecimento via schemas de detalhe (
universal,warner_chappell) epublic.dim_artistasImplementar geracao de relatorios em PDF
Configurar o agente customizado
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/machado000/kond-royalties-agent'
If you have feedback or need assistance with the MCP directory API, please join our Discord server