WorkspaceGuard
Servidor MCP que encapsula a CLI do WorkspaceGuard para verificações de uso do workspace.
Documentação
WorkspaceGuard
Instalação • Início rápido • Referência da CLI • Comparação • Perguntas frequentes
Medição de uso por workspace e limites de cota com falha fechada para uma única implantação compartilhada de assistente de IA auto-hospedado (Odysseus ou um backend compatível).

Execute o Odysseus (ou um assistente auto-hospedado compatível) para sua casa ou pequena equipe e não há como ver quem enviou quantas mensagens neste mês, nem impedir que o uso de uma pessoa consuma o orçamento de API de todos. O WorkspaceGuard é um sidecar que adiciona essa camada: contagens de mensagens por workspace, um limite mensal opcional que falha fechado e um relatório via CLI (ou JSON) que um administrador ou outro agente pode ler.
npx workspaceguard-cli usage
-> alex [alex@example.com]: 812 messages this period, cap 1000 (81%)
-> jordan [jordan@example.com]: 203 messages this period, cap unlimited
Instalação
npm install -g workspaceguard-cli
Ou execute sem instalar:
npx workspaceguard-cli usage
O pacote é workspaceguard-cli; o comando que ele instala é workspaceguard. Um port genuíno e independente em Python, com a mesma superfície de CLI e as mesmas formas de --json, é publicado separadamente como workspaceguard-cli no PyPI (pip install workspaceguard-cli, veja python/).
Início rápido
# Register the workspaces sharing one deployment (identity = the header value
# your reverse proxy sets after authenticating, e.g. Cloudflare Access).
workspaceguard add-workspace alex --identity alex@example.com
workspaceguard add-workspace jordan --identity jordan@example.com
# Optional: cap alex at 1000 messages/month. Omit for unlimited (the default).
workspaceguard set-cap alex 1000
# See usage for every workspace.
workspaceguard usage
Saída real de uma instalação nova:
-> alex [alex@example.com]: 0 messages this period, cap 1000 (0%)
-> jordan [jordan@example.com]: 0 messages this period, cap unlimited

Recursos
- Contagem de mensagens por workspace. Cada requisição através do ponto de entrada
chat()do sidecar incrementa um contador por workspace e por mês (src/core/usage.ts), isolado para que o uso de um workspace nunca vaze para o de outro. - Imposição de cota com falha fechada. Um workspace no limite recebe um
QuotaExceededErrorantes que o backend seja chamado. Se o armazenamento de uso estiver corrompido ou ilegível, o WorkspaceGuard bloqueia requisições em vez de silenciosamente zerar a contagem de todos (veja CHANGELOG.md). --jsonnativo para agentes em todos os comandos.workspaceguard usage --jsonretorna saída estruturada que um orquestrador pode analisar diretamente, sem raspar a tela.- Cofre AES-256-GCM com rotação real de chaves.
workspaceguard rotate-key <id>re-criptografa os segredos de um workspace sob uma nova chave e invalida o texto cifrado antigo. - Disjuntor auto-recuperável. Chamadas ao backend abrem o circuito após 3 falhas consecutivas, depois tentam novamente por meio de uma sonda meio-aberta e fecham novamente em caso de sucesso, em vez de permanecerem desarmados para sempre.
- Um único ponto de estrangulamento, não verificações dispersas.
chat()emsrc/core/isolation-guard.tsé o único lugar por onde toda requisição passa: resolver workspace, verificar cota, chamar backend, registrar uso. - Duas distribuições independentes e testadas. O pacote TypeScript (npm) e o port Python (PyPI) implementam o mesmo design com suítes de teste separadas: 41/41 testes TypeScript e 50/50 testes Python passando no momento em que este texto foi escrito.
Referência da CLI
Todo comando aceita --json para uma saída estruturada, nativa para agentes, em vez do texto legível por humanos mostrado abaixo.
| Comando | O que faz |
|---|---|
workspaceguard init | Inicializa o diretório de dados e o cofre para esta implantação. |
workspaceguard add-workspace <id> --identity <value> | Registra um workspace, idempotente em chamadas repetidas para o mesmo id. --identity é analisado posicionalmente e deve vir imediatamente após <id>; não é uma flag independente. |
workspaceguard status [--json] | Lista os workspaces configurados. |
workspaceguard usage [--json] | Contagem de mensagens por workspace, limite e percentual usado no mês atual. |
workspaceguard set-cap <id> <count|none> | Define ou limpa o limite mensal de mensagens de um workspace. |
workspaceguard rotate-key <id> | Rotaciona a chave de criptografia do cofre de um workspace (invalida o texto cifrado antigo). |
workspaceguard scan [--json] | Varredura de configuração de isolamento (stub de andaime, herdado da construção original; sempre retorna uma lista vazia de achados hoje). |
workspaceguard -h, --help | Imprime a lista de comandos acima e sai com 0. |
workspaceguard -V, --version | Imprime a versão do pacote instalado e sai com 0. |

Opções globais
| Opção | O que faz |
|---|---|
--data-dir <path> | Diretório de dados para configuração, cofre e dados de uso. Tem precedência sobre WORKSPACEGUARD_DATA_DIR. |
--force | Somente init: regenera a chave mestra mesmo se um arquivo de chave existente no diretório de dados resolvido parecer corrompido ou truncado. |
--json | Saída estruturada, nativa para agentes, em vez de texto legível por humanos. |
[!WARNING]
--forceinvalida permanentemente qualquer coisa já criptografada sob a chave mestra antiga. Use apenas quando o arquivo de chave existente for confirmadamente irrecuperável.
Resolução do diretório de dados, em ordem: flag --data-dir, depois variável de ambiente WORKSPACEGUARD_DATA_DIR, depois ~/.workspaceguard. Isso costumava ter como padrão o diretório de trabalho atual sem substituição — executar init a partir do shell errado podia silenciosamente gravar uma chave de criptografia ativa em um diretório não relacionado. init em uma chave existente e válida é idempotente (carrega e reutiliza essa chave); init em um arquivo de chave que existe mas não decodifica para uma chave válida se recusa a sobrescrevê-lo sem --force.
$ workspaceguard usage --json
{"ok":true,"usage":[{"workspaceId":"alex","identity":"alex@example.com","monthlyMessageCap":1000,"percentUsed":81,"period":"2026-07","messageCount":812,"estimatedBytes":48213}]}
O modo --json é o que torna isso nativo para agentes, e não apenas conveniente para humanos: um orquestrador ou agente de monitoramento pode chamar workspaceguard usage --json e analisar o resultado diretamente, em vez de raspar a saída do terminal.
API da biblioteca
import { createWorkspaceGuard, MockAdapter, QuotaExceededError } from "workspaceguard-cli";
const guard = await createWorkspaceGuard({ dataDir: "./data", backend: new MockAdapter() });
await guard.addWorkspace("alex", "alex@example.com");
await guard.setCap("alex", 1000);
try {
await guard.chat("alex@example.com", "hello");
} catch (err) {
if (err instanceof QuotaExceededError) {
// alex is over their monthly cap
}
}
const report = await guard.usageReport();
O port Python expõe a mesma forma: from workspaceguard import create_workspace_guard, MockAdapter, QuotaExceededError.
Servidor MCP
A distribuição Python do WorkspaceGuard inclui um servidor Model Context Protocol, para que um agente compatível com MCP (Claude Desktop, Claude Code, um orquestrador) possa chamar o WorkspaceGuard diretamente como ferramenta, em vez de invocar a CLI e analisar texto.
pip install "workspaceguard-cli[mcp]"
Ele expõe uma ferramenta, run, um wrapper genérico de subprocesso: passe a mesma lista de argumentos que você passaria na linha de comando, e ele invoca o binário workspaceguard instalado, analisa o JSON resultante e o retorna. Todo modo de falha (binário ausente, erro de lançamento, tempo limite, saída não zero, saída não analisável) retorna como um dict {"error": ...} simples, em vez de lançar exceção, para que uma chamada ruim não derrube o servidor.
run(args=["usage", "--json"])
# -> {"ok": true, "usage": [{"workspaceId": "alex", "identity": "alex@example.com", "monthlyMessageCap": 1000, "percentUsed": 0, "period": "2026-08", "messageCount": 0, "estimatedBytes": 0}]}
Para registrá-lo com um cliente compatível com MCP, como o Claude Desktop, adicione-o à configuração de servidores do cliente:
{
"mcpServers": {
"workspaceguard": {
"command": "workspaceguard-mcp"
}
}
}
Isso pressupõe que workspaceguard-mcp já esteja em PATH (instalado via o extra mcp acima). Se você o instalou em outro lugar, substitua "command" pelo caminho completo para o script de console.
Comparação
O WorkspaceGuard é um sidecar, não um produto concorrente. Ele fica na frente de uma implantação do Odysseus (ou de um backend compatível) e adiciona a única camada que esse backend não fornece.
| Capacidade | WorkspaceGuard | Odysseus (nativo) |
|---|---|---|
| Isolamento por usuário (histórico de chat, memória, chaves de API) | Não reimplementado; tratado como já resolvido | Sim, embutido por padrão |
| Contagem de mensagens por workspace | Sim | Não |
| Limites de cota mensal, com falha fechada | Sim | Não |
Relatório de uso via CLI / --json | Sim | Não |
| Licença | MIT | AGPL-3.0 |
O que é o WorkspaceGuard e por que ele existe
Este projeto originalmente pretendia adicionar isolamento de workspace por usuário (histórico de chat separado, memória, chaves de API) a uma plataforma de chat de IA auto-hospedada. Um estudo de viabilidade descobriu que o Odysseus já impõe propriedade por usuário em histórico de chat, memória e tokens de API por padrão, então construir uma camada de isolamento concorrente teria duplicado trabalho que o Odysseus já faz corretamente.
O WorkspaceGuard, em vez disso, mantém seu motor de isolamento testado (separação de namespaces, um cofre AES-256-GCM com rotação real de chaves, resolução de identidade com falha fechada, um disjuntor auto-recuperável) como substrato de resolução de identidade, e constrói a camada que o Odysseus não fornece: medição de uso e imposição de cota por workspace.
Camada gratuita (este repositório, MIT): contagem de mensagens por workspace, imposição de limite mensal, relatório de uso via CLI/JSON. Não está neste repositório: um painel de cobrança multi-tenant hospedado é um produto separado, de código fechado, mencionado aqui apenas como item de roadmap e nunca mesclado neste código MIT.
Arquitetura
src/core/isolation-guard.ts— o único ponto de estrangulamento (chat()) por onde toda requisição passa: resolver workspace, verificar cota, chamar backend, registrar uso.src/core/usage.ts— o motor de medição de uso que este projeto adiciona: contadores por workspace e por mês com rolagem automática de período, e imposição deQuotaExceededError.src/core/vault.ts,src/core/namespace.ts,src/core/circuit-breaker.ts— o código do motor de isolamento original, mantido como substrato de identidade e fronteira de workspace do qual a camada de medição lê.src/adapters/— a interfaceBackendAdapter.MockAdapteré a única implementação hoje; um adaptador HTTP real para Odysseus ainda não foi construído.
O comportamento específico do backend nunca entra diretamente em src/core/. Tudo passa por BackendAdapter.
Limite de confiança
O WorkspaceGuard confia em um cabeçalho de identidade upstream (padrão: Cf-Access-Authenticated-User-Email) para resolver o workspace.
[!WARNING] Este serviço nunca deve ser diretamente alcançável pela rede. Execute-o apenas atrás de um proxy confiável que defina esse cabeçalho (Cloudflare Access, Tailscale, etc.). Esse limite é documentado, não imposto por código.
O que é real vs. ainda não construído
- Real e testado: medição de uso, imposição de cota, o motor de isolamento original (cofre, separação de namespaces, disjuntor) e a CLI com modo
--json, verificado por 41/41 testes TypeScript passando e 50/50 testes Python passando. - Ainda não construído: um adaptador HTTP real para Odysseus (apenas
MockAdapterexiste hoje) e um painel de cobrança multi-tenant hospedado (deliberadamente fora do escopo deste repositório MIT).
Documentação
Perguntas frequentes
P: O que o WorkspaceGuard realmente faz?
R: Ele adiciona medição de uso por workspace e imposição de cota na frente de uma única implantação compartilhada de assistente de IA auto-hospedado. Conta mensagens por workspace por mês, permite definir um limite opcional que falha fechado quando atingido, e fornece a você (ou a um agente) um relatório workspaceguard usage. Ele não adiciona histórico de chat, memória ou isolamento de chaves de API por conta própria; isso já existe por padrão na plataforma alvo (veja "O que é o WorkspaceGuard" acima), e o código de isolamento do próprio WorkspaceGuard (src/core/vault.ts, src/core/namespace.ts) é mantido apenas como substrato de resolução de identidade do qual a camada de medição lê.
P: Qual é o diferencial real do WorkspaceGuard?
R: Escopo estreito bem feito: não é uma plataforma completa de cobrança, e não é uma reimplementação de isolamento que o backend já tem. Toda requisição passa por um único ponto de estrangulamento (chat() em src/core/isolation-guard.ts), a imposição de cota falha fechada em um armazenamento de uso corrompido em vez de silenciosamente zerar o uso de todos (veja CHANGELOG.md), e todo comando suporta --json para saída nativa para agentes.
P: Como o WorkspaceGuard se compara ao Odysseus? R: Não é um produto concorrente. O WorkspaceGuard é um sidecar que fica na frente de uma implantação do Odysseus (ou de um backend compatível); ele não substitui nada que o Odysseus já faz. Veja a tabela de comparação acima para a divisão específica de capacidades.
P: Em quais plataformas o WorkspaceGuard roda?
R: O pacote npm (workspaceguard-cli) requer Node.js 20 ou mais novo (engines.node em package.json). O port Python em python/ requer Python 3.9 a 3.13 (veja os classificadores em python/pyproject.toml). Nenhuma das distribuições inclui binário específico de plataforma, então ambos rodam onde quer que seus respectivos runtimes rodem (Linux, macOS, Windows).
P: O WorkspaceGuard é uma CLI, uma biblioteca ou ambos?
R: Ambos, em ambas as distribuições. A CLI (workspaceguard <command>) cobre init, add-workspace, status, usage, set-cap, rotate-key e scan. A mesma funcionalidade pode ser importada diretamente (createWorkspaceGuard do pacote TypeScript, create_workspace_guard do pacote Python) para qualquer coisa que queira chamá-la a partir do código em vez de invocar via shell.
P: Qual é uma limitação real atual que devo conhecer antes de confiar nisso?
R: O único adaptador de backend implementado hoje é o MockAdapter, um adaptador em memória usado para testes e experimentação local. Um adaptador HTTP real do Odysseus ainda não foi construído (veja docs/integrations/backends.md), então o WorkspaceGuard ainda não encaminha tráfego de chat ao vivo para uma implantação real do Odysseus. A lógica de medição e cota é real e testada; a ponte de rede para um backend ao vivo é a parte que ainda falta.
P: O WorkspaceGuard precisa de suas próprias chaves de API ou armazena alguma das minhas credenciais de provedor de IA?
R: Não. O único adaptador de backend que existe atualmente (MockAdapter) é em memória e não chama nenhuma API externa. Todo o comportamento específico do backend é isolado atrás da interface BackendAdapter (src/adapters/), então o código do próprio WorkspaceGuard nunca precisa ver credenciais de provedor diretamente.
P: O WorkspaceGuard é gratuito para uso comercial?
R: Sim. Este repositório é totalmente licenciado sob MIT, sem licenciamento duplo e sem bloqueio de recursos. O painel de cobrança hospedado e multi-tenant mencionado acima é um produto separado, de código fechado, descrito apenas como um item de roadmap; nenhum código de painel de cobrança vive neste código MIT, nem é retido dele.
Contribuição e segurança
Veja CONTRIBUTING.md e SECURITY.md. Mudanças notáveis são rastreadas em CHANGELOG.md.
Licença
MIT.