elo-skills-mcp 1.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,78 @@
1
+ # Licença de Uso — Time ELO (`elo-skills-mcp`)
2
+
3
+ Copyright © 2026 Ramonnielly Silva Morais. Todos os direitos reservados.
4
+
5
+ Este é um software comercial. O pacote `elo-skills-mcp` e o Método ELO Criativo
6
+ que ele acessa são propriedade de Ramonnielly Silva Morais e estão protegidos
7
+ pela Lei nº 9.610/1998 (Direitos Autorais) e pela Lei nº 9.609/1998 (Programa
8
+ de Computador).
9
+
10
+ Adquira uma licença em https://www.elosense.com.br/tools
11
+
12
+ ---
13
+
14
+ ## 1. Concessão
15
+
16
+ Mediante aquisição de uma chave de licença válida (`ELO_LICENSE_KEY`), a titular
17
+ concede a você uma licença **pessoal, intransferível, não exclusiva e revogável**
18
+ para instalar e executar este pacote, e para usar os resultados por ele gerados,
19
+ inclusive para fins comerciais próprios ou de seus clientes.
20
+
21
+ A licença vigora enquanto a chave estiver ativa e dentro do limite de
22
+ dispositivos contratado.
23
+
24
+ ## 2. Restrições
25
+
26
+ Sem autorização prévia e por escrito da titular, você **não pode**:
27
+
28
+ - redistribuir, revender, sublicenciar, alugar, emprestar ou disponibilizar o
29
+ pacote a terceiros, no todo ou em parte;
30
+ - compartilhar, publicar ou transferir sua chave de licença;
31
+ - copiar, extrair, armazenar ou republicar os prompts, templates, rubricas e
32
+ demais conteúdos do Método ELO Criativo servidos pela API;
33
+ - contornar, desabilitar ou interferir na validação de licença, no controle de
34
+ dispositivos ou em qualquer mecanismo técnico de proteção;
35
+ - descompilar, desmontar ou fazer engenharia reversa do pacote ou da API, salvo
36
+ na medida expressamente autorizada por lei;
37
+ - usar o pacote para treinar, ajustar ou avaliar modelos de aprendizado de
38
+ máquina, ou para construir produto ou serviço concorrente;
39
+ - remover ou alterar avisos de autoria, marca ou licença.
40
+
41
+ ## 3. Propriedade
42
+
43
+ O software é licenciado, não vendido. Todos os direitos não concedidos
44
+ expressamente permanecem com a titular. O Método ELO Criativo, o C.R.I.A., o
45
+ Efeito-Vórtice e demais denominações e frameworks autorais são de titularidade
46
+ exclusiva de Ramonnielly Silva Morais.
47
+
48
+ O conteúdo que **você** produz com o auxílio das ferramentas é seu.
49
+
50
+ ## 4. Dados e funcionamento
51
+
52
+ O pacote valida a licença a cada chamada e registra uso para fins de segurança,
53
+ suporte e controle de dispositivos. Os templates do método não são gravados em
54
+ disco: ficam em memória durante a sessão. Sem validação bem-sucedida em até 72
55
+ horas, a execução é bloqueada.
56
+
57
+ ## 5. Vigência e rescisão
58
+
59
+ Esta licença termina automaticamente em caso de descumprimento de qualquer
60
+ cláusula, sem prejuízo das medidas cabíveis. Encerrada a licença, cesse o uso e
61
+ desinstale o pacote.
62
+
63
+ ## 6. Garantias e responsabilidade
64
+
65
+ O software é fornecido "no estado em que se encontra", sem garantias de
66
+ adequação a uma finalidade específica ou de operação ininterrupta. Na máxima
67
+ extensão permitida em lei, a responsabilidade da titular fica limitada ao valor
68
+ efetivamente pago pela licença nos 12 meses anteriores ao evento.
69
+
70
+ ## 7. Foro
71
+
72
+ Aplica-se a legislação brasileira. Fica eleito o foro da comarca de João
73
+ Pessoa/PB para dirimir controvérsias.
74
+
75
+ ---
76
+
77
+ Dúvidas sobre licenciamento, uso em equipe ou condições especiais:
78
+ **contato@ramonniellymorais.com.br**
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # Time ELO — `elo-skills-mcp`
2
+
3
+ **O Método ELO Criativo dentro do seu Claude.** 14 agentes de estratégia de conteúdo — essência, branding, posicionamento, público, ideias, hooks, post, reels, carrossel, stories, legenda, storytelling, formatos, anúncios e análise de performance — escrevendo na sua voz, em português do Brasil.
4
+
5
+ Criado por [Ramonnielly Morais](https://ramonniellymorais.com.br), estrategista de conteúdo e criadora do Método ELO Criativo (Essência · Ligação · Originalidade).
6
+
7
+ > Produto de acesso pago. Requer uma **chave de licença** (`ELO_LICENSE_KEY`).
8
+ > Adquira em **[elosense.com.br/tools](https://www.elosense.com.br/tools)** — R$ 447/ano.
9
+
10
+ ## Como usar (após a compra)
11
+
12
+ Você recebe sua chave por e-mail com o passo a passo completo. Em resumo:
13
+
14
+ ```bash
15
+ npm install -g elo-skills-mcp
16
+ claude mcp add elo-skills --env ELO_LICENSE_KEY=SUA-CHAVE -- elo-skills-mcp
17
+ ```
18
+
19
+ Reinicie o Claude Code e rode `elo_setup` para ensinar a sua marca aos agentes. Esse setup alimenta todos os outros — é o que faz a saída sair com a sua cara, e não com cara de IA genérica.
20
+
21
+ Depois é só chamar o agente que resolve o seu problema do momento: `elo_post`, `elo_carrossel`, `elo_reels`, `elo_essencia`, `elo_analise`, e assim por diante.
22
+
23
+ ## Os 14 agentes
24
+
25
+ | Frente | Agentes |
26
+ |---|---|
27
+ | **Marca** | essência · branding · posicionamento · público |
28
+ | **Estratégia** | ideias · hooks · análise de performance |
29
+ | **Peça** | post · reels · carrossel · stories · legenda |
30
+ | **Estrutura** | storytelling · formatos |
31
+
32
+ Mais o **Elo do Setup**, que aprende a sua marca e alimenta os 14, e as ferramentas de orquestração (`elo_criar` e `elo_gate`), que produzem em loop fechado e reprovam o que sai genérico.
33
+
34
+ ## Requisitos
35
+
36
+ - [Claude Code](https://claude.ai/download)
37
+ - [Node.js](https://nodejs.org) 18+
38
+ - Conexão com a internet (os agentes validam a licença a cada uso)
39
+
40
+ ## Como funciona a proteção
41
+
42
+ Este pacote é uma casca fina: traz apenas os metadados das ferramentas. O método
43
+ não viaja no npm — cada agente busca o próprio template numa API autenticada, que
44
+ valida a licença a cada chamada. O conteúdo fica em memória durante a sessão e
45
+ nunca é gravado em disco.
46
+
47
+ ## Licença
48
+
49
+ Software comercial. Uso pessoal mediante chave de licença válida. Redistribuição,
50
+ revenda e engenharia reversa não autorizadas. Ver [LICENSE.md](./LICENSE.md).
51
+
52
+ ## Suporte
53
+
54
+ Dúvida ou erro? **contato@ramonniellymorais.com.br**
55
+
56
+ ---
57
+
58
+ © 2026 Ramonnielly Silva Morais — Método ELO Criativo.
package/package.json CHANGED
@@ -1,12 +1,18 @@
1
1
  {
2
2
  "name": "elo-skills-mcp",
3
- "version": "1.0.0",
4
- "description": "Método ELO Criativo — Skills de Estratégia de Conteúdo para Claude",
3
+ "version": "2.0.1",
4
+ "description": "Time ELO — 14 agentes de estratégia de conteúdo do Método ELO Criativo, dentro do Claude. Escrevem na sua voz, em português do Brasil.",
5
5
  "main": "index.js",
6
6
  "type": "module",
7
7
  "bin": {
8
8
  "elo-skills-mcp": "index.js"
9
9
  },
10
+ "files": [
11
+ "index.js",
12
+ "src/",
13
+ "README.md",
14
+ "LICENSE.md"
15
+ ],
10
16
  "scripts": {
11
17
  "start": "node index.js",
12
18
  "dev": "node --watch index.js"
@@ -16,13 +22,44 @@
16
22
  },
17
23
  "keywords": [
18
24
  "mcp",
25
+ "model-context-protocol",
19
26
  "claude",
27
+ "claude-code",
28
+ "time-elo",
29
+ "elo",
30
+ "metodo-elo-criativo",
31
+ "agentes",
32
+ "agents",
33
+ "ia",
34
+ "ai",
35
+ "marketing",
36
+ "content-strategy",
37
+ "estrategia-de-conteudo",
20
38
  "conteudo",
21
- "estrategia",
22
- "elo"
39
+ "copywriting",
40
+ "brand-voice",
41
+ "voz-de-marca",
42
+ "storytelling",
43
+ "instagram",
44
+ "portugues",
45
+ "pt-br",
46
+ "brasil"
23
47
  ],
24
- "author": "Ramonnielly Silva Morais",
25
- "license": "UNLICENSED",
48
+ "author": {
49
+ "name": "Ramonnielly Silva Morais",
50
+ "email": "contato@ramonniellymorais.com.br",
51
+ "url": "https://ramonniellymorais.com.br"
52
+ },
53
+ "license": "SEE LICENSE IN LICENSE.md",
54
+ "homepage": "https://www.elosense.com.br/tools",
55
+ "repository": {
56
+ "type": "git",
57
+ "url": "git+https://github.com/ramonniellymorais/elo-skills-mcp.git"
58
+ },
59
+ "bugs": {
60
+ "url": "https://github.com/ramonniellymorais/elo-skills-mcp/issues",
61
+ "email": "contato@ramonniellymorais.com.br"
62
+ },
26
63
  "engines": {
27
64
  "node": ">=18.0.0"
28
65
  }
@@ -0,0 +1,90 @@
1
+ // Cliente da API de prompts do Método ELO.
2
+ // O método NÃO viaja no pacote npm: cada tool busca seu template aqui,
3
+ // numa API autenticada que valida a licença server-side.
4
+ //
5
+ // Cache só em memória (some ao fechar o Claude) — nunca grava o método em disco.
6
+ // Fallback offline limitado: usa cache em RAM por até HARD_OFFLINE_LIMIT desde a
7
+ // última validação online bem-sucedida; passado esse limite, bloqueia mesmo offline.
8
+
9
+ import { getDeviceHash, getDeviceLabel } from './device.js'
10
+
11
+ const API_URL = process.env.ELO_API_URL || 'https://elo-skills-mcp.vercel.app'
12
+ const TEMPLATE_TTL = 1000 * 60 * 20 // 20 min de cache em RAM por tool
13
+ const HARD_OFFLINE_LIMIT = 1000 * 60 * 60 * 72 // 72h sem validação online → bloqueia
14
+
15
+ const PURCHASE_URL = 'elosense.com.br/tools'
16
+ const SUPPORT_EMAIL = 'contato@ramonniellymorais.com.br'
17
+
18
+ const templateCache = new Map() // toolName -> { template, ts }
19
+ let lastOnlineOk = 0
20
+
21
+ export async function fetchTemplate(toolName) {
22
+ const key = process.env.ELO_LICENSE_KEY
23
+ if (!key) throw new Error(missingKeyMessage())
24
+
25
+ const now = Date.now()
26
+ const cached = templateCache.get(toolName)
27
+ if (cached && now - cached.ts < TEMPLATE_TTL) return cached.template
28
+
29
+ try {
30
+ const res = await fetch(`${API_URL}/api/tool`, {
31
+ method: 'POST',
32
+ headers: {
33
+ 'Content-Type': 'application/json',
34
+ 'Authorization': `Bearer ${key}`
35
+ },
36
+ body: JSON.stringify({
37
+ tool: toolName,
38
+ device_hash: getDeviceHash(key),
39
+ device_label: getDeviceLabel()
40
+ })
41
+ })
42
+
43
+ if (res.status === 401 || res.status === 403) {
44
+ const { reason } = await safeJson(res)
45
+ throw new Error(licenseError(reason))
46
+ }
47
+ if (res.status === 429) {
48
+ throw new Error('❌ Muitas requisições em pouco tempo. Aguarde alguns minutos e tente de novo.')
49
+ }
50
+ if (!res.ok) throw new Error(`Erro ${res.status} ao buscar a skill.`)
51
+
52
+ const data = await safeJson(res)
53
+ if (!data.template) throw new Error('Resposta inválida do servidor.')
54
+
55
+ templateCache.set(toolName, { template: data.template, ts: now })
56
+ lastOnlineOk = now
57
+ return data.template
58
+
59
+ } catch (err) {
60
+ if (err.message?.startsWith('❌')) throw err
61
+ // Falha de rede: usa cache em RAM se ainda dentro da janela offline
62
+ if (cached && now - lastOnlineOk < HARD_OFFLINE_LIMIT) return cached.template
63
+ throw new Error('❌ Sem conexão com o servidor das skills ELO. Verifique sua internet e tente de novo.')
64
+ }
65
+ }
66
+
67
+ function missingKeyMessage() {
68
+ return (
69
+ '❌ Licença não encontrada.\n\n' +
70
+ 'Adicione sua chave de licença no arquivo de configuração do Claude Code:\n\n' +
71
+ '"ELO_LICENSE_KEY": "SUA-CHAVE-AQUI"\n\n' +
72
+ `Adquira sua licença em: ${PURCHASE_URL}`
73
+ )
74
+ }
75
+
76
+ function licenseError(reason) {
77
+ switch (reason) {
78
+ case 'not_found': return `❌ Chave de licença inválida. Verifique a chave ou adquira em ${PURCHASE_URL}`
79
+ case 'revoked': return `❌ Sua licença foi revogada. Entre em contato: ${SUPPORT_EMAIL}`
80
+ case 'refunded': return '❌ Esta licença foi reembolsada e está inativa.'
81
+ case 'expired': return `❌ Sua licença expirou. Renove em ${PURCHASE_URL}`
82
+ case 'suspended': return `❌ Sua licença está suspensa. Entre em contato: ${SUPPORT_EMAIL}`
83
+ case 'too_many_devices': return `❌ Limite de dispositivos atingido para esta licença. Entre em contato: ${SUPPORT_EMAIL}`
84
+ default: return `❌ Não foi possível validar sua licença. Adquira ou renove em ${PURCHASE_URL}`
85
+ }
86
+ }
87
+
88
+ async function safeJson(res) {
89
+ try { return await res.json() } catch { return {} }
90
+ }
package/src/device.js ADDED
@@ -0,0 +1,35 @@
1
+ // Identidade de dispositivo para binding de licença.
2
+ // Gera um id estável por máquina (guardado em ~/.elo/device.json) e
3
+ // só envia ao servidor o HASH combinado com a chave — nunca o id cru.
4
+
5
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs'
6
+ import { homedir, hostname } from 'os'
7
+ import { join } from 'path'
8
+ import { createHash, randomUUID } from 'crypto'
9
+
10
+ const ELO_DIR = join(homedir(), '.elo')
11
+ const DEVICE_PATH = join(ELO_DIR, 'device.json')
12
+
13
+ function getDeviceId() {
14
+ if (!existsSync(ELO_DIR)) mkdirSync(ELO_DIR, { recursive: true })
15
+ if (existsSync(DEVICE_PATH)) {
16
+ try {
17
+ const saved = JSON.parse(readFileSync(DEVICE_PATH, 'utf-8'))
18
+ if (saved.id) return saved.id
19
+ } catch { /* recria abaixo */ }
20
+ }
21
+ const id = randomUUID()
22
+ writeFileSync(DEVICE_PATH, JSON.stringify({ id, created_at: new Date().toISOString() }, null, 2))
23
+ return id
24
+ }
25
+
26
+ // Hash estável do dispositivo combinado com a chave. O servidor limita
27
+ // quantos hashes distintos uma licença pode ter (max_activations).
28
+ export function getDeviceHash(licenseKey) {
29
+ return createHash('sha256').update(`${getDeviceId()}:${licenseKey}`).digest('hex')
30
+ }
31
+
32
+ // Rótulo amigável só para suporte ("MacBook da Ramon"). Não identifica de forma única.
33
+ export function getDeviceLabel() {
34
+ try { return hostname() } catch { return 'unknown' }
35
+ }
package/src/license.js CHANGED
@@ -1,66 +1,18 @@
1
- // Validação de licença via Supabase
2
- // Tabela: licenses (key TEXT, active BOOLEAN, expires_at TIMESTAMPTZ, owner_name TEXT)
1
+ // Checagem local mínima: só confirma que a chave está presente.
2
+ // A validação REAL (ativa / expirada / revogada / dispositivos) acontece
3
+ // server-side, na API de prompts, a cada chamada de tool. Nenhuma URL ou
4
+ // chave de Supabase vive mais no pacote.
3
5
 
4
- const SUPABASE_URL = 'https://dzicopswqijljhrimtee.supabase.co'
5
- const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImR6aWNvcHN3cWlqbGpocmltdGVlIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzU2NzExNjUsImV4cCI6MjA5MTI0NzE2NX0.JgL9jhJIxqQLm8aeKNLKh8HOS2idGqUOslwAqJUMoaY'
6
+ const PURCHASE_URL = 'elosense.com.br/tools'
6
7
 
7
- let cache = null
8
- let cacheTime = 0
9
- const CACHE_TTL = 1000 * 60 * 60 // 1 hora
10
-
11
- export async function validateLicense() {
8
+ export function assertLicensePresent() {
12
9
  const key = process.env.ELO_LICENSE_KEY
13
-
14
10
  if (!key) {
15
11
  throw new Error(
16
12
  '❌ Licença não encontrada.\n\n' +
17
13
  'Adicione sua chave de licença no arquivo de configuração do Claude Code:\n\n' +
18
14
  '"ELO_LICENSE_KEY": "SUA-CHAVE-AQUI"\n\n' +
19
- 'Adquira sua licença em: ramonniellymorais.com.br/elo-skills'
15
+ `Adquira sua licença em: ${PURCHASE_URL}`
20
16
  )
21
17
  }
22
-
23
- // Cache válido — não bate no Supabase a cada chamada
24
- const now = Date.now()
25
- if (cache && now - cacheTime < CACHE_TTL) return cache
26
-
27
- try {
28
- const res = await fetch(
29
- `${SUPABASE_URL}/rest/v1/licenses?key=eq.${encodeURIComponent(key)}&select=active,expires_at,owner_name`,
30
- {
31
- headers: {
32
- 'apikey': SUPABASE_ANON_KEY,
33
- 'Authorization': `Bearer ${SUPABASE_ANON_KEY}`
34
- }
35
- }
36
- )
37
-
38
- if (!res.ok) throw new Error('Erro ao verificar licença.')
39
-
40
- const data = await res.json()
41
-
42
- if (!data.length) {
43
- throw new Error('❌ Chave de licença inválida. Verifique a chave ou adquira em ramonniellymorais.com.br/elo-skills')
44
- }
45
-
46
- const license = data[0]
47
-
48
- if (!license.active) {
49
- throw new Error('❌ Sua licença está desativada. Entre em contato: contato@ramonniellymorais.com.br')
50
- }
51
-
52
- if (license.expires_at && new Date(license.expires_at) < new Date()) {
53
- throw new Error('❌ Sua licença expirou. Renove em ramonniellymorais.com.br/elo-skills')
54
- }
55
-
56
- cache = license
57
- cacheTime = now
58
- return license
59
-
60
- } catch (err) {
61
- if (err.message.startsWith('❌')) throw err
62
- // Fallback offline: se Supabase estiver fora, usa cache anterior
63
- if (cache) return cache
64
- throw new Error('❌ Não foi possível verificar a licença. Verifique sua conexão.')
65
- }
66
18
  }
@@ -0,0 +1,32 @@
1
+ // Fábrica de tools "finas". Os metadados (name/description/inputSchema) ficam
2
+ // locais e públicos — o MCP precisa deles para listar. O TEMPLATE do método é
3
+ // buscado na API autenticada em runtime e renderizado em memória com o contexto
4
+ // de marca local (que nunca vai ao servidor).
5
+
6
+ import { getBrandConfig, formatBrandContext } from './brand.js'
7
+ import { fetchTemplate } from './api-client.js'
8
+ import { renderTemplate } from './render.js'
9
+
10
+ function resolveContext(marca) {
11
+ const config = getBrandConfig(marca || 'minha-marca')
12
+ if (!config) {
13
+ return `⚠️ Marca "${marca || 'minha-marca'}" não configurada. Use elo_setup primeiro.`
14
+ }
15
+ return formatBrandContext(config)
16
+ }
17
+
18
+ export function makeTool({ name, description, inputSchema, prepare }) {
19
+ return {
20
+ name,
21
+ description,
22
+ inputSchema,
23
+ handler: async (args = {}) => {
24
+ const { marca, ...params } = args
25
+ const ctx = resolveContext(marca)
26
+ const data = prepare ? prepare(params) : params
27
+ const template = await fetchTemplate(name) // valida licença server-side; lança erro amigável
28
+ const body = renderTemplate(template, data)
29
+ return { content: [{ type: 'text', text: `${ctx}\n\n---\n\n${body}` }] }
30
+ }
31
+ }
32
+ }
package/src/render.js ADDED
@@ -0,0 +1,32 @@
1
+ // Renderizador leve estilo mustache para os templates do método.
2
+ // Suporta:
3
+ // {{var}} → substitui pelo valor (vazio se ausente)
4
+ // {{#var}}...{{/var}} → inclui o bloco só se var for "verdadeiro"
5
+ // {{^var}}...{{/var}} → inclui o bloco só se var for "falso" (else)
6
+ //
7
+ // Os templates vêm da API autenticada; o cliente injeta os params aqui,
8
+ // em memória, e nunca grava o método em disco.
9
+
10
+ function isTruthy(v) {
11
+ if (Array.isArray(v)) return v.length > 0
12
+ return v !== undefined && v !== null && v !== '' && v !== false && v !== 0
13
+ }
14
+
15
+ export function renderTemplate(template, data = {}) {
16
+ // Seções (normais e invertidas) — resolvidas primeiro
17
+ let out = template.replace(
18
+ /\{\{([#^])(\w+)\}\}([\s\S]*?)\{\{\/\2\}\}/g,
19
+ (_, kind, key, inner) => {
20
+ const show = kind === '#' ? isTruthy(data[key]) : !isTruthy(data[key])
21
+ return show ? inner : ''
22
+ }
23
+ )
24
+
25
+ // Variáveis simples
26
+ out = out.replace(/\{\{(\w+)\}\}/g, (_, key) => {
27
+ const v = data[key]
28
+ return v === undefined || v === null ? '' : String(v)
29
+ })
30
+
31
+ return out
32
+ }
package/src/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Server } from '@modelcontextprotocol/sdk/server/index.js'
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
3
3
  import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'
4
- import { validateLicense } from './license.js'
4
+ import { assertLicensePresent } from './license.js'
5
5
  import * as tools from './tools/index.js'
6
6
 
7
7
  // Lista de todas as ferramentas registradas
@@ -9,7 +9,7 @@ const ALL_TOOLS = Object.values(tools)
9
9
 
10
10
  export async function createServer() {
11
11
  const server = new Server(
12
- { name: 'elo-skills-mcp', version: '1.0.0' },
12
+ { name: 'elo-skills-mcp', version: '2.0.0' },
13
13
  { capabilities: { tools: {} } }
14
14
  )
15
15
 
@@ -26,12 +26,13 @@ export async function createServer() {
26
26
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
27
27
  const { name, arguments: args } = request.params
28
28
 
29
- // Valida licença antes de qualquer execução
30
- // Setup é liberado sem licença para facilitar o onboarding
29
+ // Checagem local de presença da chave antes de qualquer execução.
30
+ // A validação real (ativa/expirada/revogada) é server-side, na API de prompts.
31
+ // Setup é liberado sem licença para facilitar o onboarding.
31
32
  const FREE_TOOLS = ['elo_setup']
32
33
  if (!FREE_TOOLS.includes(name)) {
33
34
  try {
34
- await validateLicense()
35
+ assertLicensePresent()
35
36
  } catch (err) {
36
37
  return {
37
38
  content: [{ type: 'text', text: err.message }],