Local KMS MCP
Servidor MCP leve e local-first para gerenciamento de chaves por agente.
Documentação
local-kms-mcp-server
Servidor MCP leve e local-first para gerenciamento de chaves por agente.
Dê a cada agente sua própria identidade de assinatura — sem depender de KMS externo ou expor chaves privadas.
local-kms-mcp-server gera, armazena, rotaciona e usa pares de chaves de assinatura inteiramente na máquina local. As chaves nunca
saem do processo, nunca tocam a rede e permanecem sob controle.
Ele é construído para clientes MCP e runtimes de agentes que precisam de identidades isoladas e compostíveis para tarefas como fluxos DID/SSI, handshakes de autenticação, assinatura de desafios e qualquer fluxo de trabalho onde agentes precisam provar algo criptograficamente.
O Que Ele Faz
- Gera pares de chaves de assinatura vinculados a um keyId (uma identidade por agente ou tarefa)
- Armazena chaves localmente usando um keystore simples baseado em arquivos
- Assina payloads base64 sem nunca expor o material da chave privada
- Rotaciona chaves com segurança, preservando a consistência do algoritmo
- Exclui chaves com limpeza segura opcional (sobrescreve com dados aleatórios)
- Lista algoritmos de assinatura e chaves disponíveis
- Opcionalmente criptografa chaves em repouso usando AES-256-GCM
- Executa via MCP usando stdio (padrão) ou HTTP quando necessário
Algoritmos Suportados
| Algoritmo | Valor da ferramenta | Observações |
|---|---|---|
| Ed25519 | ed25519 | Boa opção padrão para assinatura geral e casos de uso estilo DID |
| ECDSA secp256k1 | ecdsa-secp256k1 | Comum para Ethereum, Bitcoin e outros fluxos Web3 |
| ECDSA P-256 | ecdsa-prime256v1 | ES256, WebAuthn e compatibilidade com KMS em nuvem comum |
| ECDSA P-384 | ecdsa-secp384r1 | Ambientes NIST P-384 de maior segurança |
Requisitos
- Node.js
>=24.0.0 - Um cliente MCP que suporte servidores MCP via stdio ou HTTP
Início Rápido
Transporte stdio
Use stdio ao executar a partir do Claude Desktop, Cursor ou outro cliente MCP local.
{
"mcpServers": {
"local-kms": {
"command": "npx",
"args": ["-y", "local-kms-mcp-server"],
"env": {
"STORE_PATH": "/Users/yourname/.local-kms",
"ENCRYPT_STORE": "true",
"STORE_ENCRYPTION_KEY": "<base64-32-byte-key>"
}
}
}
}
Transporte HTTP
Use HTTP apenas quando você explicitamente quiser um endpoint de rede local.
TRANSPORT=http PORT=8080 npx local-kms-mcp-server
Endpoint:
POST http://localhost:8080/mcp
Instalação
Execute diretamente com npx:
npx -y local-kms-mcp-server
Ou instale globalmente:
npm install -g local-kms-mcp-server
local-kms-mcp-server
Configuração
| Variável de ambiente | Padrão | Descrição |
|---|---|---|
STORE_PATH | ./keys | Diretório usado para arquivos de chave persistidos |
TRANSPORT | stdio | Transporte MCP: stdio ou http |
PORT | 8080 | Porta HTTP usada apenas quando TRANSPORT=http |
ENCRYPT_STORE | false | Defina como true ou 1 para criptografar arquivos de chave em repouso |
STORE_ENCRYPTION_KEY | nenhum | Chave de 32 bytes codificada em base64, necessária quando a criptografia está habilitada |
Para desenvolvimento local, há um arquivo de exemplo em .env.example, mas para uso real com clientes MCP é melhor passar
os valores pela configuração env do cliente para que a inicialização seja determinística.
Gere uma chave de criptografia:
node -e "console.log(require('node:crypto').randomBytes(32).toString('base64'))"
Referência de Ferramentas
Todas as entradas das ferramentas são validadas com Zod. Chaves públicas e assinaturas são retornadas como strings base64.
| Ferramenta | Propósito | Entrada | Saída |
|---|---|---|---|
check_keypair | Verificar se uma chave existe | { "keyId": "agent-1" } | { "exists": true } |
list_keys | Listar todos os IDs de chave armazenados | {} | { "keys": ["agent-1", "agent-2"] } |
list_algorithms | Listar todos os algoritmos de assinatura suportados | {} | { "algorithms": ["ed25519", ...] } |
generate_key | Criar e persistir um novo par de chaves | { "keyId": "agent-1", "algo": "ed25519" } | { "publicKey": "..." } |
get_key_info | Retornar a chave pública armazenada para um ID de chave | { "keyId": "agent-1" } | { "publicKey": "..." } |
rotate_key | Rotacionar um par de chaves existente usando seu algoritmo armazenado | { "keyId": "agent-1" } | { "newPublicKey": "..." } |
delete_key | Excluir um par de chaves com limpeza segura opcional | { "keyId": "agent-1", "secureWipe": true } | { "success": true } |
sign_message | Assinar um payload codificado em base64 | { "keyId": "agent-1", "message": "aGVsbG8=" } | { "signature": "..." } |
Observações:
generate_keyfalha se okeyIdjá existirrotate_keyincrementa oversionarmazenadodelete_keycomsecureWipe: truesobrescreve o arquivo de chave com dados aleatórios antes da exclusãosign_messageespera que omessagejá esteja codificado em base64sign_messageaceita uma substituição opcional dealgo, mas no uso normal o algoritmo armazenado geralmente é o que você deseja
Fluxo de Uso Típico
- Chame
list_algorithmspara ver os algoritmos de assinatura disponíveis - Chame
generate_keypara um novokeyId - Chame
get_key_infopara recuperar a chave pública para registro ou distribuição - Chame
sign_messagesempre que o agente precisar assinar um desafio ou payload - Chame
rotate_keyquando precisar de novo material de chave para o mesmokeyId - Chame
delete_keypara remover com segurança um par de chaves quando não for mais necessário - Chame
check_keypairoulist_keyspara verificações de inventário e existência
Exemplo de payload sign_message:
{
"keyId": "key-1",
"message": "eyJub25jZSI6IjEyMyJ9"
}
Modelo de Armazenamento
Chaves não criptografadas são armazenadas como um arquivo por chave em ${STORE_PATH}:
${STORE_PATH}/${keyId}.json
Os registros armazenados contêm:
{
"keyId": "key-1",
"algo": "ed25519",
"publicKey": "...",
"privateKey": "...",
"version": 1,
"createdAt": "2026-04-18T12:34:56.000Z"
}
Quando ENCRYPT_STORE=true, o conteúdo do arquivo é criptografado e persistido como texto cifrado base64 em vez de JSON em texto puro.
Notas de Segurança
- Chaves privadas nunca saem do servidor por meio de respostas MCP
- Arquivos de chave são gravados com permissões
0600 - Criptografia em repouso é opcional, mas recomendada para qualquer coisa além de desenvolvimento local descartável
- O modo HTTP não adiciona autenticação ou TLS por si só; mantenha-o atrás de um limite local confiável ou seu próprio proxy reverso
- Valores de
keyIdse tornam nomes de arquivo, então use IDs estáveis e seguros para sistemas de arquivos
Desenvolvimento
pnpm install
pnpm build
pnpm test
pnpm lint
pnpm format:check
Execute localmente após a compilação:
pnpm start
Observe a saída compilada durante o desenvolvimento:
pnpm start:dev
Estendendo com Novos Algoritmos
- Implemente um novo adaptador estendendo
KeyAlgorithmAdapter - Registre-o em
src/keystore/index.ts - Exponha o nome do adaptador no esquema da ferramenta relevante se os usuários devem poder selecioná-lo
import { KeyAlgorithmAdapter } from '../adapter.js';
import type { KeyPair } from '../types.js';
export class MyAdapter extends KeyAlgorithmAdapter {
readonly name = 'my-algo';
generate(): KeyPair {
/* ... */
}
sign(privateKey: string, data: Buffer): string {
/* ... */
}
verify(publicKey: string, data: Buffer, signature: string): boolean {
/* ... */
}
rotate(_currentKeyPair: KeyPair): KeyPair {
return this.generate();
}
}
Estrutura do Projeto
src/
config/ environment parsing and validation
keystore/ adapters, registry, and file-based storage
tools/ MCP tool registration and handlers
utils/ crypto helpers, errors, serializers
server.ts MCP server construction
main.ts stdio and HTTP entry point
test/ unit tests
Licença
MIT