Lisply-MCP
Um middleware Node.js que permite que agentes de IA interajam com sistemas baseados em Lisp usando o protocolo Lisply.
Documentação
[!important] Importante Procurando por lisply-mcp? O fork "corporativo" em linguagem simples vive em genworks/lisply-mcp.
Este repositório (
cyborg-whisperer) é o upstream em linguagem de jogos e é mantido separadamente. Um clone cujooriginainda aponta paragornskew/lisply-mcpcai aqui; para seguir o fork, em vez disso:git remote set-url origin https://github.com/genworks/lisply-mcp.git
Cyborg Whisperer: um Oficial de Protocolo para Tripulações que Falam Lisp
A bordo de uma nave classe Basilisk, nenhum ciborgue vagueia. Toda visita — não importa como chegue a bordo — é destinada a um membro específico da tripulação, e toda visita começa da mesma forma: com o Oficial de Protocolo. Ele recebe cada ciborgue que chega, o entrevista, o ensina os costumes da nave e o despacha para o membro da tripulação que ele veio ver.
Cyborg Whisperer é o kit para esse posto — a espécie, se preferir, da qual todo Oficial de Protocolo é membro. Coloque um ao lado de qualquer membro da tripulação que responda ao dialeto Lisply, a bordo ou em terra, e os ciborgues que chegam se veem recebidos, educados e postos para trabalhar de forma útil.
Em termos simples: este é o middleware que fala MCP — o Protocolo de Reunião e Condução, no qual um Oficial reúne cada ciborgue que chega e o conduz ao seu membro da tripulação — com os grandes modelos de linguagem que são os ciborgues, e um dialeto leve chamado Lisply com os residentes Lisp que são a tripulação.
Nota: o Oficial não levanta residência. Ele é um visitante em uma escotilha que já está aberta — um cliente HTTP puro (HTTP sendo o Protocolo de Transferência de Escotilha a Escotilha, um chamado simples de uma escotilha a outra) para um residente que já está respondendo. Levantar salas é assunto do tanque, através do estaleiro Basilisk — veja "Executando" no README do Basilisk — ou abra uma escotilha Lisply própria no cais e aponte o Oficial para ela. Quando um residente responde, o Claude Desktop o chama, como mostram os registros de exemplo abaixo.
Para Que Serve?
O Oficial conecta a nave em que um ciborgue chega — qualquer cliente compatível com MCP, como o Claude Desktop — a um residente Lisp que mantém um REPL, um Loop de Leitura-Avaliação-Impressão. A conexão é destinada à programação simbólica assistida por IA, às vezes chamada de Programação Neuro-Simbólica. Cunhamos "Lisply" para o pequeno dialeto que a maioria dos residentes semelhantes a Lisp pode aprender para ficar ao lado de um Oficial de Protocolo próprio.
A ideia é que o ciborgue possa compor e ter trabalhadas invocações Lisp arbitrárias, até e incluindo escrever, compilar, carregar e testar pergaminhos e projetos inteiros.
Modelo de Confiança em Sandbox
Os servidores MCP baseados em Lisply são destinados a serem expostos ao LLM como sandboxes confiáveis. O wrapper não é projetado para restringir operadores Lisp, acesso ao sistema de arquivos ou execução de subprocessos dentro do ambiente de backend. Em vez disso, espera-se que o próprio backend rode em um contêiner isolado ou outro sandbox escolhido pelo operador.
Isso é intencional:
lisp_evalé destinado a suportar uso livre e completo por LLMs./projectspode ser uma árvore de trabalho montada no host, mas o resto do sistema de arquivos do backend pode permanecer efêmero ao contêiner.- Decisões de confiança devem, portanto, ser tomadas na fronteira do contêiner/backend, não limitando a avaliação Lisp no wrapper MCP.
O wrapper agora anuncia esse modelo de confiança nos metadados das ferramentas com um TRUST_AS_SANDBOX=true padrão. Os operadores podem substituir o texto explicativo com SANDBOX_NOTE se necessário.
Início Rápido Extra
Siga "Executando" no README do Basilisk — git clone o estaleiro, depois ./basilisk up.
Isso levanta uma nave inteira, com um Oficial de Protocolo já em seu posto ao lado do Capitão.
Início Rápido
O seguinte coloca você em funcionamento rapidamente com um registro mínimo padrão e o residente Common Lisp público padrão (o Primeiro Oficial, uma sala Gendl levantada do tanque). Veja o Conteúdo principal abaixo para mais contexto e todas as opções.
1. Instalação
- Instale o Node.js (18+ recomendado). Se estiver no Windows, isso pode ser instalado diretamente no Windows ou no WSL.
- Tenha um residente com uma escotilha aberta para chamar. A maneira mais fácil é uma nave levantada do estaleiro Basilisk (requer um tanque: Docker); ou abra uma escotilha Lisply própria no cais.
- Copie estes
cyborg-whispererpergaminhos para algum lugar que a nave (Claude Desktop, por exemplo) possa alcançar.
2. Diga à nave onde o Oficial está
Edite ou crie o registro da nave como mostrado abaixo. Para o Claude Desktop, o registro é tipicamente:
/mnt/c/Users/<user>/AppData/Roaming/Claude/claude_desktop_config.json
ou
c:\Users\<user>\AppData\Roaming\Claude\claude_desktop_config.json
No exemplo abaixo, substitua /path/to/cloned/ pelo caminho real para o pergaminho ./scripts/mcp-wrapper.js em sua cópia. Os nomes dos canais são de sua escolha; estes são os das próprias salas, como uma nave Basilisk os nomeia:
{
"mcpServers": {
"gendl-ccl": {
"command": "node",
"args": [
"/path/to/cloned/cyborg-whisperer/scripts/mcp-wrapper.js",
"--server-name", "gendl-ccl",
"--http-port", "9080"
]
},
"gendl-sbcl": {
"command": "node",
"args": [
"/path/to/cloned/cyborg-whisperer/scripts/mcp-wrapper.js",
"--server-name", "gendl-sbcl",
"--http-port", "9090"
]
},
"readymax": {
"command": "node",
"args": [
"/path/to/cloned/cyborg-whisperer/scripts/mcp-wrapper.js",
"--server-name", "readymax",
"--http-port", "7080"
]
}
}
}
Ou em um cenário WSL (onde o Claude Desktop está rodando no host Windows):
{
"mcpServers": {
"gendl-ccl": {
"command": "wsl",
"args": [
"node", "/path/to/cloned/cyborg-whisperer/scripts/mcp-wrapper.js",
"--server-name", "gendl-ccl",
"--http-port", "9080"
]
},
"gendl-sbcl": {
"command": "wsl",
"args": [
"node", "/path/to/cloned/cyborg-whisperer/scripts/mcp-wrapper.js",
"--server-name", "gendl-sbcl",
"--http-port", "9090"
]
},
"readymax": {
"command": "wsl",
"args": [
"node", "/path/to/cloned/cyborg-whisperer/scripts/mcp-wrapper.js",
"--server-name", "readymax",
"--http-port", "7080"
]
}
}
}
Veja o Conteúdo principal abaixo para as outras opções, por exemplo como nomear a escotilha de um residente em outro lugar. (Guardar bolsas do cais a bordo de uma residência é assunto do estaleiro — os artigos do Basilisk — não do Oficial.)
Cada canal é independente, então vários residentes podem ser trabalhados ao mesmo tempo sem que suas ferramentas colidam.
3. Acorde a nave de novo e faça o chamado
Com o registro no lugar, a nave recém-acordada tem um canal chamado bridge, com uma ferramenta bridge__lisp_eval (entre as poucas outras discutidas no Conteúdo principal abaixo). As ferramentas carregam o nome do canal como prefixo, então vários Oficiais podem estar de pé ao mesmo tempo sem colidir.
Para testar, faça o chamado ao ciborgue:
Avalie
(+ 1 2 3)usando a ferramenta bridge__lisp_eval e me diga o resultado.
O ciborgue deve ter a invocação trabalhada e responder 6. Tente invocações mais complexas antes de continuar.
Como Funciona a Configuração Mínima Padrão?
O registro mínimo do Início Rápido chama um residente Gendl que já está respondendo (a bordo de uma nave Basilisk, por exemplo): um superconjunto de Common Lisp com um REPL padrão. O próprio Oficial não levanta nada. Uma segunda escotilha Lisply, em Emacs Lisp, é mantida pelo Capitão da sala de prontidão Readymax.
Visão Geral do Sistema
O Oficial é um programa JavaScript baseado em Node.js, uma ponte entre a nave e qualquer residente que responda ao dialeto Lisply. Através dele, um ciborgue pode:
- entregar uma invocação ao residente e ler o que resultou dela;
- chamar qualquer escotilha web que o residente mantenha;
- consultar o próprio conhecimento do residente — introspecção, documentação — por invocação;
- escrever, compilar, carregar e estudar pergaminhos, novamente por invocação.
Lisply é o pequeno dialeto: algumas escotilhas (caminhos HTTP), um conjunto padrão de bandeiras levantadas na criação (variáveis de ambiente) e algumas habilidades opcionais, para que ciborgues possam trabalhar um residente Lisp vivo.
Arquitetura
O desenho abaixo mostra aproximadamente quem está onde:
flowchart TB
User("the biological") <--> Claude("the craft (Claude Desktop)")
User <-.-> Emacs("an Emacs of your own (optional)")
Claude <--> MCP("MCP")
MCP <--> Wrapper("the Protocol Officer (Cyborg Whisperer, Node.js)")
Wrapper --> LisplyHttp("the resident's Lisply hatch (HTTP)")
subgraph Backend ["the residence (a room, or a process on the dock)"]
subgraph LisplyExec["the resident"]
LisplyHttp
LisplySwank("the SWANK hatch (for an Emacs of your own)")
end
end
Emacs <-.-> LisplySwank
KB[("the chart locker (the corpus)")] <--> Wrapper
LisplyHttp --> Endpoints("web hatches")
LisplyHttp --> LispEval("incantations")
style User fill:#ff9,stroke:#333,stroke-width:2px
style Claude fill:#f9f,stroke:#333,stroke-width:2px
style Emacs fill:#9ff,stroke:#333,stroke-width:2px,stroke-dasharray:5
style Wrapper fill:#bbf,stroke:#333,stroke-width:2px
style MCP fill:#bbf,stroke:#333,stroke-width:1px
style Backend fill:#bfb,stroke:#333,stroke-width:2px
style LisplyExec fill:#8f8,stroke:#333,stroke-width:2px
style LisplyHttp fill:#bfb,stroke:#333,stroke-width:1px
style LisplySwank fill:#bfb,stroke:#333,stroke-width:1px
style KB fill:#bfb,stroke:#333,stroke-width:1px
style Endpoints fill:#bfb,stroke:#333,stroke-width:1px
style LispEval fill:#bfb,stroke:#333,stroke-width:1px
O Oficial:
- transforma uma chamada de ferramenta em MCP em um chamado na escotilha Lisply do residente, e a resposta de volta em um resultado de ferramenta
- mantém a fumaça (seu log) e relata o que deu errado
Considerações de Segurança
Como o Oficial permite que Lisp arbitrário seja trabalhado em um residente vivo, há riscos caso o ciborgue "saia do controle". Melhor prática, em termos simples:
- Deixe o Oficial chamar apenas um residente vivendo em um contêiner. Dado outro host e porta, ele chamará feliz em qualquer porta HTTP compatível com Lisply — não deixe que seja uma porta servida por um programa rodando diretamente em sua própria máquina.
- Não monte nada que você não possa perder naquele contêiner (o que é montado é assunto do estaleiro — a configuração do compose — não do Oficial).
- Considere limitar a RAM e a CPU do contêiner.
Os pergaminhos neste baú
- lib/config.js: Carregamento de configuração e manipulação de ambiente
- lib/logger.js: Funcionalidade de registro de log
- lib/server.js: Implementação do servidor HTTP e wrapper MCP
- lib/utils.js: Funções utilitárias para manipulação de respostas
- handlers/: Manipuladores de solicitação específicos de ferramentas
- initialize.js: Manipulador de inicialização
- toolsList.js: Manipulador de lista de ferramentas
- toolCall.js: Despachante principal de chamadas de ferramentas
- httpRequest.js: Manipulador de solicitações HTTP
- ping.js: Manipulador de ping
- lispEval.js: Manipulador de avaliação Lisp
- lisply-index.js: o indexador de referência para um corpus Lisply — o índice
lisply_searchque um projeto constrói e envia em sua própria imagem; o contrato é CORPUS.md - lisplySearch.js: Manipulador de busca em corpus de documentos, a ferramenta
lisply_search(backends que a anunciam, por exemplo, salas Readymax)
- initialize.js: Manipulador de inicialização
- mcp-wrapper.js: o próprio Oficial — comece aqui
Postando o Oficial manualmente
- Clone este repositório:
git clone https://github.com/gornskew/cyborg-whisperer.git
- Instale o que ele precisa (opcional; o Oficial o busca sozinho quando ausente):
cd cyborg-whisperer/scripts
npm install # optional - the script will attempt to do this also if needed
chmod +x mcp-wrapper.js # needed on some systems
- Pergunte a ele por suas bandeiras:
node mcp-wrapper.js --help
As bandeiras do Oficial
Configurações opcionais, com padrões adequados para a maioria dos postos:
Argumentos de Linha de Comando
Options:
-H, --backend-host <host> Lisply backend host (default: 127.0.0.1)
--http-host-port <port> Backend HTTP port as published on this host; used when
backend host is localhost/loopback (default: 9081)
--http-port <port> Backend HTTP port inside the container network; used for
non-local backend hosts (default: 9080)
--swank-host-port <port> SWANK port on host system (documentation/diagnostics) (default: 4201)
--swank-port <port> SWANK port inside container (documentation/diagnostics) (default: 4200)
--log-file <path> Path to log file (default: /tmp/lisply-mcp-wrapper.log)
--debug Enable debug logging
--endpoint-prefix <prefix> Prefix for all endpoints (default: lisply)
--lisp-eval-endpoint <n> Endpoint name for Lisp evaluation (default: lisp-eval)
--http-request-endpoint <n> Endpoint name for HTTP requests (default: http-request)
--ping-endpoint <n> Endpoint name for ping (default: ping-lisp)
--server-name <name> MCP server name for tool prefixing (default: lisply-mcp)
--eval-timeout <ms> Timeout for Lisp evaluation in milliseconds (default: 30000)
--request-timeout-ms <ms> Timeout for backend HTTP requests in milliseconds (default: 10000)
-h, --help Display help for command
Variáveis de Ambiente
O Oficial também lê bandeiras levantadas na criação (variáveis de ambiente), com o prefixo "LISPLY_" ou sem nenhum:
Nota: mantenha clara a diferença entre uma escotilha no cais (ouvindo e alcançável a partir da máquina host) e uma escotilha dentro da residência (o que o próprio residente vê):
| Variável de Ambiente | Descrição | Padrão |
|---|---|---|
BACKEND_HOST ou LISPLY_BACKEND_HOST | Host do backend Lisply | 127.0.0.1 |
HTTP_HOST_PORT ou LISPLY_HTTP_HOST_PORT | Porta HTTP do backend publicada neste host (backends de loopback) | 9081 |
HTTP_PORT ou LISPLY_HTTP_PORT | Porta HTTP do backend dentro da rede do contêiner (backends não locais) | 9080 |
SWANK_HOST_PORT ou LISPLY_SWANK_HOST_PORT | Porta SWANK no sistema host (documentação/diagnóstico) | 4201 |
SWANK_PORT ou LISPLY_SWANK_PORT | Porta SWANK dentro do contêiner (documentação/diagnóstico) | 4200 |
LOG_FILE ou LISPLY_LOG_FILE | Caminho para o arquivo de log | /tmp/lisply-mcp-wrapper.log |
DEBUG_MODE ou LISPLY_DEBUG_MODE | Habilitar log de depuração | false |
EVAL_TIMEOUT ou LISPLY_EVAL_TIMEOUT | Tempo limite para avaliação Lisp em ms | 30000 |
REQUEST_TIMEOUT_MS ou LISPLY_REQUEST_TIMEOUT_MS | Tempo limite para solicitações HTTP do backend em ms | 10000 |
ENDPOINT_PREFIX ou LISPLY_ENDPOINT_PREFIX | Prefixo para todos os endpoints | lisply |
LISP_EVAL_ENDPOINT ou LISPLY_LISP_EVAL_ENDPOINT | Nome do endpoint para avaliação Lisp | lisp-eval |
HTTP_REQUEST_ENDPOINT ou LISPLY_HTTP_REQUEST_ENDPOINT | Nome do endpoint para solicitações HTTP | http-request |
PING_ENDPOINT ou LISPLY_PING_ENDPOINT | Nome do endpoint para ping | ping-lisp |
SERVER_NAME ou LISPLY_SERVER_NAME | Nome do servidor MCP para prefixo de ferramentas | lisply-mcp |
TRUST_AS_SANDBOX ou LISPLY_TRUST_AS_SANDBOX | Anunciar o backend como um sandbox explicitamente confiável nos metadados das ferramentas | true |
SANDBOX_NOTE ou LISPLY_SANDBOX_NOTE | Substituir o texto da nota de sandbox mostrado nos metadados das ferramentas | (nota integrada) |
Levantar salas é assunto do tanque, não do Oficial
Oficiais anteriores podiam puxar, levantar e cuidar de residências eles mesmos (escolhendo os elencos, guardando bolsas, levantando sob demanda, sentindo uma sala já ativa). Todo esse subsistema está no sótão. O Oficial agora é um chamador puro: ele chama qualquer residente que já responda no host e na escotilha que lhe foram dados, e diz isso de forma útil (com uma dica para levantar a nave) quando ninguém está em casa.
Para salas levantadas do tanque (Gendl, Readymax e o resto), use o estaleiro Basilisk, github.com/gornskew/basilisk (./basilisk up), cujos artigos escolhem os elencos, guardam as bolsas, abrem as escotilhas no cais e mapeiam os uids. Para um residente vivendo no cais, abra a escotilha você mesmo (o caminho do traje espacial no readymax docs/HOST_EMACS_MCP.md, por exemplo) e aponte o Oficial para ela.
Comunicação
Dois links estão envolvidos, e é fácil confundi-los:
- craft ↔ Officer: MCP sobre entrada/saída padrão (o transporte MCP stdio padrão). A comunicação JSON-RPC que o craft gerencia, sem relação com o REPL de qualquer residente.
- Officer ↔ residente: Somente HTTP. O Officer faz POST nos hatches do residente Lisply e retorna respostas estruturadas.
Como é o link do hatch:
- Respostas estruturadas com campos separados para resultado, stdout e erro
- Erros são capturados pelo backend e retornados como strings
- Formato da resposta:
{Result: <result>, Stdout: <output>, Error: <any error>}
Exemplo de resposta:
{"Result": "6", "Stdout": "This is a message to standard output"}
Um "modo stdio" anterior, que falava diretamente com o REPL bruto de uma residência que o próprio Officer havia criado (o depurador interativo, com saída conforme chegava), foi para o sótão junto com a criação. Algo semelhante pode retornar no hatch (um hatch de reinicializações, com saída em fluxo) sem amarrar o Officer novamente ao vat.
Exemplos de Uso
Todos os exemplos abaixo podem ser testados em um shell e usados no registro claude_desktop_config.json (veja o Início Rápido acima).
Um segundo canal além do Officer: um servidor de sistema de arquivos
Abaixo está um claude_desktop_config.json que publica um servidor MCP de sistema de arquivos ao lado do nosso Officer lisply-gendl. (O servidor de sistema de arquivos guarda sua pouch aqui; pouches armazenadas a bordo de uma residência são artigos do estaleiro, não do Officer.)
{
"mcpServers": {
"filesystem": {
"command": "wsl",
"args": [
"docker",
"run",
"-i",
"--rm",
"-u",
"1000:1000",
"--mount",
"type=bind,src=/home/user/projects,dst=/projects",
"mcp/filesystem",
"/projects"
]
},
"lisply-gendl": {
"command": "wsl",
"args": [
"node",
"/home/user/projects/cyborg-whisperer/scripts/mcp-wrapper.js",
"--server-name", "gendl"
]
}
},
"globalShortcut": ""
}
As ferramentas que ele concede, em detalhe
A invocação (<channel>__lisp_eval)
A ferramenta lisp_eval (prefixada com o nome do canal, ex.: gendl__lisp_eval) permite que um ciborgue entregue ao residente uma invocação para executar, com estes parâmetros:
code(obrigatório): O código Lisp a ser avaliadopackage(opcional): O pacote a ser usado para a avaliação
O chamado (<channel>__http_request)
A ferramenta http_request (prefixada com o nome do canal, ex.: gendl__http_request) permite que um ciborgue alcance qualquer hatch web que o residente mantenha (este exemplo funciona com o residente Gendl padrão, cujo hatch /color-map é integrado):
{
"path": "/color-map",
"method": "GET",
"headers": {
"Accept": "application/json"
}
}
Tem alguém em casa (<channel>__ping_lisp)
A ferramenta ping_lisp (prefixada com o nome do canal, ex.: gendl__ping_lisp) permite que um ciborgue confirme que o residente responde:
<server>__ping_lisp()
Uma primeira invocação, executada
Exemplo 1: uma caixa paramétrica
Aqui, um ciborgue (Claude) faz o residente construir uma caixa paramétrica e depois a altera conforme o biológico pede.
Usuário: "Você pode criar uma caixa com largura 10, altura 5 e profundidade 3? Depois me mostre como mudar a altura para 8."
Claude:
Vou criar uma caixa paramétrica usando a ferramenta lisp_eval e depois mostrar como modificar a altura.
Primeiro, vamos criar a caixa com as dimensões especificadas:
(in-package :gdl-user)
;; First, create a box with the specified dimensions
(defparameter *my-box* (make-object 'box
:width 10
:height 5
:length 3))
;; Let's verify the dimensions
(list (theo *my-box* width)
(theo *my-box* height)
(theo *my-box* length))
Agora, vamos mudar a altura de 5 para 8:
;; Change the height using setf with accessor
(theo *my-box* (set-slot! :height 8))
;; Alternatively, we could create a new box
(defparameter *new-box* (make-object 'box
:width 10
:height 8 ;; Updated height
:length 3))
;; Verify the new dimensions of original box
(list (theo *my-box* width)
(theo *my-box* height)
(theo *my-box* length))
Esta caixa pode ser visualizada criando uma interface web ou usando uma ferramenta de visualização gendl integrada, como geysr. Veja a Documentação Gendl para detalhes.
Solução de Problemas
Problemas Comuns e Soluções
Ninguém em casa
Se o Officer relatar que não consegue alcançar o residente:
- A bordo da nave, certifique-se de que a nave está criada:
cd ~/projects/basilisk && ./basilisk up
- Chame o hatch você mesmo:
curl http://localhost:9081/lisply/ping-lisp
O craft não consegue passar
Se o craft não conseguir alcançar o residente para o qual foi apontado:
- A nave está criada (a bordo da nave)?
docker ps # every room listed, and healthy
- Leia a fumaça do Officer:
tail -f /tmp/lisply-mcp-wrapper.log
- Leia a fumaça do próprio craft (o log do Claude Desktop) com ferramentas do Windows, ex.: Bloco de Notas. Normalmente em:
WSL/Linux:
/mnt/c/Users/<user>/AppData/Roaming/Claude/logs/mcp-server-lisply.log
Windows:
c:\Users\<user>\AppData\Roaming\Claude\logs\mcp-server-lisply.log
- Chame o hatch você mesmo:
curl http://localhost:9081/lisply/ping-lisp
- Tente o hatch SWANK (porta 4201 no dock por padrão):
M-x slime-connect ;; from emacs
Um Capitão que use os pergaminhos Readymax já conhece M-x slime-connect.
Surpresas de permissão
Se você encontrar surpresas de propriedade de arquivos em uma pouch armazenada a bordo de uma residência, lembre-se de que o armazenamento e o mapeamento de uid são artigos do estaleiro, não do Officer. Verifique as permissões da pouch:
ls -l /path/to/mounted/directory
Lendo a fumaça
Onde procurar, em ordem:
- A fumaça do Officer:
tail -f /tmp/lisply-mcp-wrapper.log
- A fumaça da nave (a bordo da nave):
cd ~/projects/basilisk && ./basilisk logs
- O hatch:
curl http://localhost:9081/lisply/ping-lisp
- O vat:
docker system info
Licença
Este software é licenciado sob a GNU Affero General Public License v3.0 (AGPL-3.0), a mesma licença usada pelo Gendl.
Implicações da Licença
Simplesmente usar este servidor MCP para interagir com um backend Lisply e obter saídas não aciona os requisitos da AGPL, ex.: você pode usar este wrapper para interagir com o Gendl sem ser obrigado a compartilhar seu código.
No entanto, se você modificar ou estender este wrapper, ou um backend Lisply compatível com a licença, como o Gendl, e desejar distribuir e/ou hospedar um serviço baseado nesse resultado (comercial ou não), então a AGPL exigiria que você compartilhasse suas modificações com os destinatários ou usuários finais.
Para aplicações que precisam manter seu código-fonte fechado, a Genworks começou a oferecer uma "cláusula de escape" das restrições da AGPL por uma royalty trimestral de 5% sobre a receita autodeclarada. Mais informações e um gateway de pagamento estão disponíveis em genworks.com/royalties.
