Local KMS MCP

Servidor MCP ligero y local para gestión de claves por agente.

Documentación

local-kms-mcp-server

npm version License: MIT

Servidor MCP ligero y local-first para gestión de claves por agente.

Dale a cada agente su propia identidad de firma, sin depender de un KMS externo ni exponer claves privadas.

local-kms-mcp-server genera, almacena, rota y utiliza pares de claves de firma completamente en la máquina local. Las claves nunca salen del proceso, nunca tocan la red y permanecen bajo control.

Está diseñado para clientes MCP y entornos de ejecución de agentes que necesitan identidades aisladas y componibles para tareas como flujos DID/SSI, handshakes de autenticación, firma de desafíos y cualquier flujo de trabajo donde los agentes deban demostrar algo criptográficamente.

Qué Hace

  • Genera pares de claves de firma asociados a un keyId (una identidad por agente o tarea)
  • Almacena claves localmente usando un keystore simple basado en archivos
  • Firma payloads en base64 sin exponer nunca el material de la clave privada
  • Rota claves de forma segura preservando la consistencia del algoritmo
  • Elimina claves con borrado seguro opcional (sobrescritura con datos aleatorios)
  • Lista algoritmos de firma y claves disponibles
  • Opcionalmente cifra las claves en reposo usando AES-256-GCM
  • Se ejecuta sobre MCP vía stdio (por defecto) o HTTP cuando sea necesario

Algoritmos Soportados

AlgoritmoValor de herramientaNotas
Ed25519ed25519Buen default para firma general y casos de uso tipo DID
ECDSA secp256k1ecdsa-secp256k1Común para Ethereum, Bitcoin y otros flujos Web3
ECDSA P-256ecdsa-prime256v1ES256, WebAuthn y compatibilidad con KMS en la nube común
ECDSA P-384ecdsa-secp384r1Entornos NIST P-384 de mayor seguridad

Requisitos

  • Node.js >=24.0.0
  • Un cliente MCP que soporte servidores MCP por stdio o HTTP

Inicio Rápido

Transporte stdio

Usa stdio cuando ejecutes desde Claude Desktop, Cursor u otro 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

Usa HTTP solo cuando quieras explícitamente un endpoint de red local.

TRANSPORT=http PORT=8080 npx local-kms-mcp-server

Endpoint:

POST http://localhost:8080/mcp

Instalación

Ejecuta directamente con npx:

npx -y local-kms-mcp-server

O instala globalmente:

npm install -g local-kms-mcp-server
local-kms-mcp-server

Configuración

Variable de entornoDefaultDescripción
STORE_PATH./keysDirectorio usado para archivos de claves persistidos
TRANSPORTstdioTransporte MCP: stdio o http
PORT8080Puerto HTTP usado solo cuando TRANSPORT=http
ENCRYPT_STOREfalseEstablecer a true o 1 para cifrar archivos de claves en reposo
STORE_ENCRYPTION_KEYnoneClave de 32 bytes codificada en base64 requerida cuando el cifrado está habilitado

Para desarrollo local hay un archivo de ejemplo en .env.example, pero para uso real con clientes MCP es mejor pasar los valores a través de la configuración env del cliente para que el arranque sea determinista.

Genera una clave de cifrado:

node -e "console.log(require('node:crypto').randomBytes(32).toString('base64'))"

Referencia de Herramientas

Todas las entradas de herramientas se validan con Zod. Las claves públicas y firmas se devuelven como cadenas base64.

HerramientaPropósitoEntradaSalida
check_keypairVerificar si una clave existe{ "keyId": "agent-1" }{ "exists": true }
list_keysListar todos los IDs de claves almacenados{}{ "keys": ["agent-1", "agent-2"] }
list_algorithmsListar todos los algoritmos de firma soportados{}{ "algorithms": ["ed25519", ...] }
generate_keyCrear y persistir un nuevo par de claves{ "keyId": "agent-1", "algo": "ed25519" }{ "publicKey": "..." }
get_key_infoDevolver la clave pública almacenada para un ID{ "keyId": "agent-1" }{ "publicKey": "..." }
rotate_keyRotar un par de claves existente usando su algoritmo almacenado{ "keyId": "agent-1" }{ "newPublicKey": "..." }
delete_keyEliminar un par de claves con borrado seguro opcional{ "keyId": "agent-1", "secureWipe": true }{ "success": true }
sign_messageFirmar un payload codificado en base64{ "keyId": "agent-1", "message": "aGVsbG8=" }{ "signature": "..." }

Notas:

  • generate_key falla si el keyId ya existe
  • rotate_key incrementa el version almacenado
  • delete_key con secureWipe: true sobrescribe el archivo de clave con datos aleatorios antes de la eliminación
  • sign_message espera que message ya esté codificado en base64
  • sign_message acepta una anulación opcional de algo, pero en uso normal el algoritmo almacenado suele ser lo que quieres

Flujo de Uso Típico

  1. Llama a list_algorithms para ver los algoritmos de firma disponibles
  2. Llama a generate_key para un nuevo keyId
  3. Llama a get_key_info para recuperar la clave pública para registro o distribución
  4. Llama a sign_message cuando el agente necesite firmar un desafío o payload
  5. Llama a rotate_key cuando necesites nuevo material de clave para el mismo keyId
  6. Llama a delete_key para eliminar de forma segura un par de claves cuando ya no sea necesario
  7. Llama a check_keypair o list_keys para inventario y comprobaciones de existencia

Ejemplo de payload sign_message:

{
  "keyId": "key-1",
  "message": "eyJub25jZSI6IjEyMyJ9"
}

Modelo de Almacenamiento

Las claves sin cifrar se almacenan como un archivo por clave bajo ${STORE_PATH}:

${STORE_PATH}/${keyId}.json

Los registros almacenados contienen:

{
  "keyId": "key-1",
  "algo": "ed25519",
  "publicKey": "...",
  "privateKey": "...",
  "version": 1,
  "createdAt": "2026-04-18T12:34:56.000Z"
}

Cuando ENCRYPT_STORE=true, el contenido del archivo se cifra y se persiste como texto cifrado en base64 en lugar de JSON en texto plano.

Notas de Seguridad

  • Las claves privadas nunca salen del servidor a través de respuestas MCP
  • Los archivos de clave se escriben con permisos 0600
  • El cifrado en reposo es opcional pero recomendado para cualquier cosa más allá de desarrollo local desechable
  • El modo HTTP no añade autenticación ni TLS por sí mismo; mantenlo detrás de un límite local de confianza o tu propio proxy inverso
  • Los valores de keyId se convierten en nombres de archivo, así que usa IDs estables y seguros para sistemas de archivos

Desarrollo

pnpm install
pnpm build
pnpm test
pnpm lint
pnpm format:check

Ejecuta localmente después de compilar:

pnpm start

Observa la salida compilada durante el desarrollo:

pnpm start:dev

Extensión con Nuevos Algoritmos

  1. Implementa un nuevo adaptador extendiendo KeyAlgorithmAdapter
  2. Regístralo en src/keystore/index.ts
  3. Expón el nombre del adaptador a través del esquema de herramienta relevante si los usuarios deberían poder seleccionarlo
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();
  }
}

Estructura del Proyecto

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

Licencia

MIT