Skip to content

Repository files navigation

Vault MCP Server

GitHub Actions License: MIT Python 3.10+ Code style: black MCP Compatible

A production-ready HashiCorp Vault Model Context Protocol (MCP) server built with Python and FastMCP. This server provides a comprehensive interface to Vault's KV secrets engine and policy management through the MCP protocol, enabling AI assistants to securely interact with Vault.

✨ Features

Core Capabilities

  • πŸ” Full Secret Management - Create, read, update, delete, and list secrets
  • πŸ“œ Policy Management - Create, read, delete, and list Vault policies
  • πŸ”„ KV v1 and v2 Support - Automatic version detection and appropriate API usage
  • 🏒 Enterprise Support - Namespace support for Vault Enterprise deployments
  • 🎯 Custom Mount Points - Works with any KV mount point (not hardcoded to secret/)

Technical Excellence

  • πŸ›‘οΈ Thread-Safe - Proper Vault client management for concurrent operations
  • πŸ” Comprehensive Error Handling - Detailed error messages for debugging
  • πŸ“Š MCP-Safe Logging - All logs to stderr, preserving stdout for MCP protocol
  • πŸ§ͺ Health Checks - Built-in connection and authentication verification
  • πŸ”§ Flexible Configuration - Environment-based configuration for easy deployment

πŸš€ Quick Start

Prerequisites

  • Python 3.10 or higher
  • HashiCorp Vault server (1.14.0+)
  • Valid Vault token with appropriate permissions

Installation

  1. Clone the repository:
git clone https://github.com/democratize-technology/vault-mcp.git
cd vault-mcp
  1. Run the setup script (creates virtual environment and installs dependencies):
./run_server.sh

Configuration

Set the required environment variables:

# Required
export VAULT_ADDR=https://your-vault-server:8200
export VAULT_TOKEN=hvs.your-vault-token

# Optional - Core Settings
export VAULT_KV_MOUNT=secret      # KV mount point (default: kvv2)
export VAULT_KV_VERSION=2         # KV version 1 or 2 (default: 2)
export VAULT_NAMESPACE=           # Vault Enterprise namespace
export DEBUG=1                    # Enable debug logging

# Optional - Security Settings
export VAULT_MCP_ENABLE_PERMISSION_CHECKS=true  # Enable path/policy restrictions
export VAULT_MCP_ALLOWED_PATHS=apps/,users/     # Comma-separated allowed paths
export VAULT_MCP_READONLY=true                  # Enable read-only mode
export VAULT_MCP_ALLOW_POLICY_MGMT=true         # Allow policy operations

# Optional - Rate Limiting
export VAULT_MCP_RATE_LIMIT_MAX=200             # Max requests per window (default: 100)
export VAULT_MCP_RATE_LIMIT_WINDOW=120          # Window in seconds (default: 60)

Usage with Claude Desktop

Add to your Claude Desktop configuration (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "vault": {
      "command": "/path/to/vault-mcp/run_server.sh",
      "env": {
        "VAULT_ADDR": "https://your-vault-server:8200",
        "VAULT_TOKEN": "hvs.your-vault-token",
        "VAULT_KV_MOUNT": "secret"
      }
    }
  }
}

🎯 Understanding Vault Paths vs Keys

Important: Vault secrets have a two-level structure that often causes confusion:

Path = Secret Location

The path parameter specifies WHERE the secret is stored:

  • "apps/myapp/database" - A secret containing database credentials
  • "users/alice/personal" - Alice's personal secret store
  • "certificates/web-server" - Web server certificate data

Keys = Fields Within the Secret

Keys are the individual data fields INSIDE each secret:

  • A secret at path "apps/myapp/database" might contain keys: username, password, host
  • A secret at path "certificates/web-server" might contain keys: cert, private_key, ca_bundle

Key Points ⚠️

  • βœ… Correct: read_secret(path="apps/myapp/database") returns the entire secret
  • ❌ Wrong: read_secret(path="apps/myapp/database/username") will fail
  • πŸ’‘ Access keys from response: response.data.data["username"]

πŸ“š MCP Tools Reference

Secret Operations

create_secret

Create or update a secret in Vault.

# Create secret at path "apps/myapp/config" with multiple keys
create_secret(
    path="apps/myapp/config",  # ← This is the secret PATH
    data={
        "api_key": "secret123",   # ← These are KEYS within the secret
        "db_pass": "secure456",
        "service_url": "https://api.example.com"
    }
)

read_secret

Read a secret from Vault.

# Read entire secret at path "apps/myapp/config"
read_secret(path="apps/myapp/config")

# This returns ALL keys within the secret:
# {
#   "data": {
#     "data": {
#       "api_key": "secret123",
#       "db_pass": "secure456"
#     }
#   }
# }

# To access a specific key, extract from response:
# response.data.data["api_key"]

# ❌ WRONG: Cannot access individual keys via path
# read_secret(path="apps/myapp/config/api_key")  # This will fail!

delete_secret

Delete a secret (soft delete for KV v2).

delete_secret(path="apps/myapp/config")

list_secrets

List secrets at a given path.

list_secrets(path="apps/")

read_secret_metadata

Read metadata for a KV v2 secret.

read_secret_metadata(path="apps/myapp/config")

Policy Operations

create_policy

Create or update a Vault policy.

create_policy(
    name="app-readonly",
    policy='path "secret/data/apps/*" {\n  capabilities = ["read", "list"]\n}'
)

read_policy

Read an existing policy.

read_policy(name="app-readonly")

delete_policy

Delete a policy.

delete_policy(name="app-readonly")

list_policies

List all policies in Vault.

list_policies()

Utility Operations

generate_policy

Generate a properly formatted policy string.

generate_policy(path="secret/data/apps/*", capabilities=["read", "list"])

get_mount_info

Get information about the current KV mount configuration.

get_mount_info()

health_check

Check Vault connection and authentication status.

health_check()

🎯 Example Prompts for AI Assistants

  • "Create a secret at apps/production with database credentials"
  • "Read the API keys from apps/myapp/config"
  • "List all secrets under the apps/ path"
  • "Create a read-only policy for the apps/production/* path"
  • "Check if Vault is accessible and properly configured"
  • "Generate a policy that allows read and list on apps/*"

πŸ”§ Development

Setting Up Development Environment

# Create and activate virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install development dependencies
pip install -r requirements.txt
pip install -r requirements-dev.txt

# Run unit tests
pytest

# Run tests with coverage
make test-cov

# Run integration tests (requires Docker)
make test-integration

# Run linting and formatting
make lint format

# Run type checking
make typecheck

# Run security audit
make audit

# Run all quality checks
make quality-full

πŸ› Troubleshooting

Enable Debug Logging

export DEBUG=1

Common Issues

  1. JSON Protocol Errors: Ensure all logging goes to stderr, not stdout
  2. Authentication Failed: Verify VAULT_TOKEN is valid and has appropriate permissions
  3. Mount Not Found: Check VAULT_KV_MOUNT matches your Vault configuration
  4. Connection Refused: Verify VAULT_ADDR is correct and Vault is running

Minimum Required Vault Policy

For basic operation, the token needs these permissions:

# KV v2 operations
path "kvv2/data/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

path "kvv2/metadata/*" {
  capabilities = ["read", "list", "delete"]
}

# Policy management
path "sys/policies/acl/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

# Health checks
path "sys/health" {
  capabilities = ["read"]
}

🀝 Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ”’ Security

For security issues, please see our Security Policy.

πŸ™ Acknowledgments

  • Built with FastMCP - The fast, Pythonic way to build MCP servers
  • Powered by hvac - HashiCorp Vault API client for Python
  • Part of the Model Context Protocol ecosystem

πŸ“ž Support


Made with ❀️ by Democratize Technology

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages