Skeleton
БесплатноНе проверенA starter template for building an MCP server with Vault-based secret management and Postgres-backed configuration, featuring tool-level authorization and redac
Описание
A starter template for building an MCP server with Vault-based secret management and Postgres-backed configuration, featuring tool-level authorization and redacted output.
README
Node.js MCP skeleton with:
- Vault-backed secret management
- Postgres-backed configuration management
- Security and operational defaults for production-style patterns
Purpose
This repository is a starter template for building an MCP server that needs:
- Secret reads and writes through Vault
- Config reads and writes through Postgres
- Tool-level authorization for mutating operations
- Redacted tool output by default
- Basic reliability controls for external secret writes
Skeleton Architecture
Runtime flow:
- src/index.js boots the app, creates services, and connects MCP stdio transport.
- src/config/env.js loads and validates environment configuration.
- src/services/configStore.js handles Postgres persistence.
- src/services/vault.js handles Vault operations and write retry queue.
- src/services/security.js redacts sensitive fields.
- src/mcp/server.js registers MCP tools and applies auth/error wrappers.
- src/http/server.js exposes MCP over HTTP with auth, limits, and access logs.
- src/http/index.js boots the dedicated HTTP MCP process.
- src/start-both.js starts stdio and HTTP as separate child processes.
Local infrastructure:
- docker-compose.yml runs Postgres and Vault for local development.
- initdb/001_config.sql creates and seeds the app_config table.
Tool Catalog
Read-only tools:
- connection_info
- vault_connection_info
- healthcheck
- list_configs
- get_config
- list_secrets
- get_secret
- vault_agent_token_read
- token_lookup_self
- token_rotation_config
Mutating tools:
- set_config
- delete_config
- set_secret
- delete_secret
- token_renew_self
- token_create
- token_revoke
- token_revoke_self
If MCP_ADMIN_AUTH_KEY is configured, mutating tools require authorizationKey.
Security Behavior
- Sensitive fields are redacted unless MCP_ALLOW_SENSITIVE_OUTPUT=true.
- Mutating operations can be access controlled with MCP_ADMIN_AUTH_KEY.
- Vault write operations are serialized through an internal queue and retried with exponential backoff.
Environment Variables
Core:
- MCP_SERVER_NAME
- MCP_SERVER_VERSION
- MCP_ALLOW_SENSITIVE_OUTPUT
- MCP_ADMIN_AUTH_KEY
- MCP_TRANSPORT_MODE (
stdio,http, orboth) - MCP_CONFIG_DEFAULT_USER_ID
- MCP_TOKEN_ROTATION_DEFAULT_INTERVAL_MS
- MCP_TOKEN_ROTATION_USER_INTERVAL_CONFIG_KEY
- MCP_VAULT_AGENT_AUTH_MODE_CONFIG_KEY
- MCP_VAULT_AGENT_TOKEN_FILE_PATH_CONFIG_KEY
- MCP_VAULT_AGENT_LISTENER_ADDR_CONFIG_KEY
HTTP transport:
- MCP_HTTP_HOST
- MCP_HTTP_PORT
- MCP_HTTP_PATH
- MCP_HTTP_HEALTH_PATH
- MCP_HTTP_AUTH_MODE (
token,oauth2,both) - MCP_HTTP_TOKEN_SOURCE (
vault,env) - MCP_HTTP_AUTH_TOKENS (comma-separated bearer tokens)
- MCP_HTTP_TRUST_PROXY
- MCP_HTTP_ALLOWED_ORIGINS (comma-separated)
- MCP_HTTP_ALLOWED_IPS (comma-separated)
- MCP_HTTP_MAX_BODY_BYTES
- MCP_HTTP_RATE_LIMIT_WINDOW_MS
- MCP_HTTP_RATE_LIMIT_MAX_REQUESTS
- MCP_HTTP_VAULT_TOKEN_INDEX_PATH
- MCP_HTTP_VAULT_TOKEN_DEFAULT_USER_ID
- MCP_HTTP_VAULT_TOKEN_REQUIRED_SCOPES
- MCP_HTTP_VAULT_TOKEN_REQUIRED_AUDIENCE
- MCP_HTTP_VAULT_TOKEN_CACHE_TTL_MS
- MCP_HTTP_OAUTH2_INTROSPECTION_URL
- MCP_HTTP_OAUTH2_CLIENT_ID
- MCP_HTTP_OAUTH2_CLIENT_SECRET
- MCP_HTTP_OAUTH2_REQUIRED_SCOPES
- MCP_HTTP_OAUTH2_REQUIRED_AUDIENCE
- MCP_HTTP_OAUTH2_TIMEOUT_MS
- MCP_HTTP_OAUTH2_CACHE_TTL_MS
- MCP_HTTP_TLS_ENABLED
- MCP_HTTP_TLS_CERT_PATH
- MCP_HTTP_TLS_KEY_PATH
Postgres:
- POSTGRES_HOST
- POSTGRES_PORT
- POSTGRES_DB
- POSTGRES_USER
- POSTGRES_PASSWORD
Postgres config model:
- Configuration data is multi-user scoped in
app_configusing composite key(user_id, key). - MCP config tools accept optional
userId; when omitted,MCP_CONFIG_DEFAULT_USER_IDis used. - Seed records include:
default/sample.featuredefault/app.defaultsfor future default parameters.default/token.rotation.intervalMsdefault/vault.agent.auth.modedefault/vault.agent.tokenFilePathdefault/vault.agent.listener.addr
Vault:
- VAULT_ADDR
- VAULT_TOKEN
- VAULT_AGENT_ENABLED
- VAULT_AGENT_AUTH_MODE (
none,file,listener,both) - VAULT_AGENT_TOKEN_FILE_PATH
- VAULT_AGENT_LISTENER_ENABLED
- VAULT_AGENT_LISTENER_ADDR
- VAULT_UNSEAL_KEY
- VAULT_KV_MOUNT
- VAULT_WRITE_RETRY_ATTEMPTS
- VAULT_WRITE_RETRY_BASE_DELAY_MS
- VAULT_WRITE_RETRY_MAX_DELAY_MS
Reference values are in .env.example.
Quick Start
- Install dependencies.
- Copy .env.example to .env.
- Start local services with docker compose up -d.
- Resolve the managed unseal key:
npm run vault:unseal-key -- --json. - Initialize and unseal local Vault (first run):
docker exec -e VAULT_ADDR=http://127.0.0.1:8200 skeleton-mcp-vault vault operator init -key-shares=1 -key-threshold=1 -format=json
docker exec -e VAULT_ADDR=http://127.0.0.1:8200 skeleton-mcp-vault vault operator unseal <unseal_key_from_init_or_env>
- Seed a test secret in Vault.
- Start the MCP server with npm start.
- Run tests with npm test.
Test Coverage Notes
Current automation includes listener-related coverage for Vault Agent runtime resolution.
- tests/vault-agent-runtime.test.js validates:
- listener mode resolution from Postgres defaults
- both mode resolution (listener + file)
- fallback to environment values when database mode is invalid
Transport scripts:
# stdio only (default)
npm run start:stdio
# HTTP transport only
npm run start:http
# run stdio + HTTP as two processes
npm run start:both
HTTP MCP Endpoint
Default endpoint values:
- MCP URL:
http://127.0.0.1:3000/mcp - Health URL:
http://127.0.0.1:3000/healthz
HTTP transport security controls:
- Every
/mcprequest requiresAuthorization: Bearer <token>. - For
MCP_HTTP_AUTH_MODE=token, setMCP_HTTP_TOKEN_SOURCE=vaultto validate tokens from Vault. - For
MCP_HTTP_AUTH_MODE=oauth2, bearer tokens are validated by OAuth2 introspection. - For
MCP_HTTP_AUTH_MODE=both, either token strategy can authorize requests. - Mutating tools still require
authorizationKeywhenMCP_ADMIN_AUTH_KEYis set. - Request limits are enforced with:
MCP_HTTP_MAX_BODY_BYTESMCP_HTTP_RATE_LIMIT_WINDOW_MSMCP_HTTP_RATE_LIMIT_MAX_REQUESTS
- Optional network restrictions:
MCP_HTTP_ALLOWED_ORIGINSMCP_HTTP_ALLOWED_IPS
Vault Multi-User Token Model
Store HTTP bearer tokens in Vault at MCP_HTTP_VAULT_TOKEN_INDEX_PATH.
Default-user fallback behavior:
MCP_HTTP_VAULT_TOKEN_DEFAULT_USER_IDdefaults todefault.- If no non-default users exist in the token index, the default user is always used as fallback.
Supported index shape:
{
"tokens": {
"<sha256(token)>": {
"userId": "user-123",
"tokenId": "tok-123",
"active": true,
"scopes": ["mcp:invoke", "mcp:read"],
"audience": ["codex", "claude"],
"expiresAt": "2026-12-31T23:59:59Z"
}
}
}
Notes:
- Store only token hashes in Vault index data, never plaintext tokens.
MCP_HTTP_VAULT_TOKEN_REQUIRED_SCOPESandMCP_HTTP_VAULT_TOKEN_REQUIRED_AUDIENCEenforce policy checks.- This keeps secrets in Vault while configuration remains in Postgres.
Vault Token Lifecycle MCP Tools
The skeleton exposes node-vault token lifecycle methods as MCP tools:
token_lookup_self->tokenLookupSelftoken_renew_self->tokenRenewSelftoken_create->tokenCreatetoken_revoke->tokenRevoketoken_revoke_self->tokenRevokeSelf
These tools are intended for controlled operational usage and are guarded by admin authorization when MCP_ADMIN_AUTH_KEY is configured.
Vault Agent Auto-Auth and Token Renewal
Vault Agent can own token auth/renewal while this service reads the sink token file.
- Enable with
VAULT_AGENT_ENABLED=true - Choose auth mode with
VAULT_AGENT_AUTH_MODE:file: use Vault Agent token sink filelistener: use Vault Agent listener endpointboth: enable listener operations and file-based token read workflows
- Configure sink file path with
VAULT_AGENT_TOKEN_FILE_PATH - Enable listener with
VAULT_AGENT_LISTENER_ENABLED=true - Configure listener with
VAULT_AGENT_LISTENER_ADDR - Use
vault_agent_token_readwhen application workflows need token sink visibility
When Vault Agent mode is enabled:
- File mode refreshes token state from the configured token sink path.
- Listener mode routes Vault operations through the configured Vault Agent listener.
- Both mode supports listener operations and token sink read workflows.
Option 3: Postgres-Backed Non-Secret Vault Agent Settings
This skeleton supports storing non-secret Vault Agent runtime pointers/settings in Postgres while keeping token material in Vault.
- Runtime settings are read from default user config scope (
MCP_CONFIG_DEFAULT_USER_ID). - Key names are configurable with:
MCP_VAULT_AGENT_AUTH_MODE_CONFIG_KEYMCP_VAULT_AGENT_TOKEN_FILE_PATH_CONFIG_KEYMCP_VAULT_AGENT_LISTENER_ADDR_CONFIG_KEY
- Recommended values in Postgres:
vault.agent.auth.modevault.agent.tokenFilePathvault.agent.listener.addr
Rotation Time Configuration
Rotation interval supports both global defaults and user-scoped overrides:
- Global default env variable:
MCP_TOKEN_ROTATION_DEFAULT_INTERVAL_MS - User-scoped config key name:
MCP_TOKEN_ROTATION_USER_INTERVAL_CONFIG_KEY(defaulttoken.rotation.intervalMs)
Effective value resolution is:
- User-scoped Postgres config (
userId+ key) - Default user Postgres config (
default+ key) - Global env default
Use token_rotation_config tool to inspect the resolved rotation interval for a user scope.
Minimal remote call example:
curl -i http://127.0.0.1:3000/mcp \
-H "Authorization: Bearer replace-me-token" \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {},
"clientInfo": { "name": "client", "version": "1.0.0" }
}
}'
HTTPS Deployment Choice
This repository uses a reverse proxy (recommended): terminate TLS at a reverse proxy or load balancer.
- Keep this app on internal HTTP.
- Enforce HTTPS, client allowlists, and edge-level controls at the proxy/LB.
- Forward traffic to
MCP_HTTP_HOST:MCP_HTTP_PORT. - Keep
MCP_HTTP_TLS_ENABLED=falsein this process mode.
Popular patterns include Nginx, Traefik, Envoy, ALB/NLB, or Cloudflare Tunnel in front of /mcp.
Vault Production Migration (Raft)
The repository now includes a Vault production migration scaffold under vault-production:
- vault-production/config/vault.hcl: Raft-backed Vault server configuration.
- vault-production/docker-compose.vault-prod.yml: Compose definition for Vault in server mode (non-dev).
- vault-production/scripts/convert-dev-to-prod.sh: Script to export dev KV data, start Raft Vault, initialize/unseal, and import secrets.
- vault-production/scripts/bootstrap-post-conversion.sh: Script to enable audit, write policy, configure AppRole, and emit service credentials.
- scripts/vault-unseal-key.js: Script to resolve unseal key from
VAULT_UNSEAL_KEYorsrc/config/vault.unseal.key.json. - vault-production/README.md: Detailed migration notes and options.
Managed unseal key flow:
VAULT_UNSEAL_KEYis optional and can be injected at runtime.- If
VAULT_UNSEAL_KEYis not set,npm run vault:unseal-keyreadssrc/config/vault.unseal.key.json. - If the key file is missing or empty, a 24-character key is generated and saved to
src/config/vault.unseal.key.json. - Both compose stacks run a one-shot
vault-unseal-key-initservice before Vault startup to ensure key material exists.
Run the conversion:
bash vault-production/scripts/convert-dev-to-prod.sh --init-keys-out vault-production/backups/vault-init.json
Common options:
# Use a different KV mount
bash vault-production/scripts/convert-dev-to-prod.sh --mount secret
# Migrate infra only (skip data movement)
bash vault-production/scripts/convert-dev-to-prod.sh --skip-export --skip-import
# Use when Raft Vault is already initialized
bash vault-production/scripts/convert-dev-to-prod.sh --skip-init
# Explicitly set key file path used by convert script
bash vault-production/scripts/convert-dev-to-prod.sh --unseal-key-path src/config/vault.unseal.key.json
# Post-conversion hardening bootstrap (audit, policy, AppRole)
bash vault-production/scripts/bootstrap-post-conversion.sh --vault-token <root_or_admin_token>
# CI-friendly machine output
bash vault-production/scripts/bootstrap-post-conversion.sh \
--vault-token <root_or_admin_token> \
--output json
VS Code Agent Structure
This repository includes a project agent structure for adapting the skeleton to additional service-backed MCP implementations:
- agent/README.md: Overview of agent assets.
- agent/playbooks/service-onboarding.md: Step-by-step onboarding checklist.
- agent/templates/service-spec.md: Request template for describing new service integrations.
Workspace custom agent:
Use this custom agent when you want GitHub Copilot in VS Code to:
- Configure new service adapters under
src/services. - Register matching MCP tools in
src/mcp/server.js. - Update env validation in
src/config/env.js. - Preserve authorization and redaction behavior.
- Add tests and documentation updates.
Test Coverage
Integration tests in tests/server.integration.test.js cover:
- Healthcheck behavior
- Authorization on mutating tools
- Redaction behavior for secret output
HTTP transport tests in tests/http.integration.test.js cover:
- Unauthorized requests are rejected
- Authorized MCP initialization succeeds
- Internal failures return JSON-RPC-compatible error responses
- Health endpoint behavior
Vault token auth tests in tests/vault-token-auth.test.js cover:
- Multi-user token index lookup by SHA-256 hash
- Inactive token rejection
- Scope/audience-aware authorization inputs
Production migration tests in tests/vault-production.test.js cover:
- Presence of Vault production scaffold files
- Raft config expectations
- Non-dev Vault compose command validation
- Conversion/bootstrap script help and bash syntax checks
Extend The Skeleton
- Add domain services under src/services.
- Register new tools in src/mcp/server.js.
- Add corresponding tests under tests.
- Keep mutating tools behind authorization checks.
- Keep secret-bearing fields redacted by default.
Notes
- docker-compose.yml now runs Vault with Raft-backed storage for local persistence.
- The managed key script is an automation helper and not a Vault KMS/HSM auto-unseal backend.
- The migration scaffold starts with bootstrap-friendly defaults and still requires TLS, production auth methods, and credential rotation before real production use.
Установка Skeleton
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/LesterAJohn/skeleton-mcpFAQ
Skeleton MCP бесплатный?
Да, Skeleton MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Skeleton?
Нет, Skeleton работает без API-ключей и переменных окружения.
Skeleton — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Skeleton в Claude Desktop, Claude Code или Cursor?
Открой Skeleton на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
wenb1n-dev/SmartDB_MCP
A universal database MCP server supporting simultaneous connections to multiple databases. It provides tools for database operations, health analysis, SQL optim
автор: wenb1n-devPostgres Server
This server enables interaction with PostgreSQL databases through the Model Context Protocol, optimized for the AWS Bedrock AgentCore Runtime. It provides tools
автор: madhurprashPostgres
Query your database in natural language
автор: AnthropicPostgreSQL
Read-only database access with schema inspection.
автор: modelcontextprotocolCompare Skeleton with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории data
