An open-source Model Context Protocol (MCP) server for the OpenVox Puppet ecosystem. Provides AI tools with deep knowledge of OpenVox core projects and Voxpupuli modules, with built-in AI governance, transparency, and legal protection.
"The community is what drives the ecosystem, not the platform." — Ben Ford
The Puppet ecosystem needs an open-source MCP server. Perforce Puppet has a closed-source MCP; this project provides the community-owned alternative. The OpenVox MCP Server is designed as an AAIF implementation for the Puppet/OpenVox ecosystem.
- Assists AI tools (Claude, GPT, Gemini, Mistral, and others) in working correctly with OpenVox and Voxpupuli codebases
- Enforces AI governance through a tightly coupled three-layer system (declaration, integration, enforcement)
- Protects contributors with mandatory disclosure, license compliance, and clear accountability
- Respects privacy with privacy-by-design principles and configurable data handling
- Writes provenance records (
.ai-provenance.yml), policy configuration files, and override files - Reads repository structure, metadata, commit messages, and license headers for validation
- Reports compliance findings, migration assessments, and policy information via structured JSON responses
- Generate or modify Puppet code — code generation is the domain of
future depth plugins (e.g.,
openvox-mcp-puppet), not the core server - Require an LLM — it is a governance/validation server that communicates via the MCP protocol; it has no LLM dependency and runs entirely offline
- Make network write requests — all network access is read-only against allowlisted endpoints (Puppet Forge, GitHub API, RubyGems)
- Operate as root — the stdio transport runs as your shell user; the HTTP transport runs under a dedicated unprivileged system user
- Force AI models to comply (MCP delivers policy; enforcement happens at CI/review gates)
- Replace human judgement (every contribution requires meaningful human review)
- Restrict self-hosted environments (Tier 3 is advisory, not mandatory)
openvox-puppet, openvox-server, openvoxdb, openvoxdb-cli, openbolt, container-openbolt, container-openvoxagent, container-openvoxdb, container-openvoxserver, hiera, hiera-eyaml, openvox-docs, openvox-helm-chart, openvoxserver-ca, and more.
Community-maintained Puppet modules under the Voxpupuli organization.
Single MCP server with a plugin architecture. Governance is always loaded; depth plugins are optional.
server = OpenvoxMCP.server(plugins: [:puppet, :server, :modules])
# Governance is always loaded — cannot be bypassed
# Depth plugins are loaded conditionallyBoth transports are supported from day one:
| Transport | Use Case | Entry Point | Auth | User |
|---|---|---|---|---|
| stdio | Local development | bin/openvox-mcp-stdio |
None (local pipe) | Shell user |
| HTTP (Streamable) | Shared / production | bin/openvox-mcp-server |
API key (Bearer) | openvox-mcp system user |
stdio runs as your shell user, launched by the MCP client. No special setup needed.
HTTP runs as a long-running daemon (typically via systemd) under a dedicated system user. See docs/deployment.md for the full deployment guide including system user creation, Ruby path configuration, and systemd setup.
The core governance layer provides 9 tools:
| Tool | Description |
|---|---|
validate_commit |
Validate commit message for AI policy compliance (stage-aware) |
check_disclosure |
Check AI disclosure trailers |
check_file_access |
Check if file can be accessed/modified |
get_policy |
Get AI policy information |
get_tier |
Determine tier classification for a repository |
format_trailer |
Generate properly formatted AI disclosure trailer |
validate_license |
Check license SPDX identifier |
record_provenance |
Record AI provenance information |
generate_api_key |
Generate API key for HTTP transport auth |
8 policy resources are available at openvox://policy/*:
| Resource | Description |
|---|---|
openvox://policy/summary |
AI policy summary (instructions field) |
openvox://policy/full |
Complete policy (all 9 areas) |
openvox://policy/licenses |
License allowlist |
openvox://policy/dco |
DCO v1.1 text |
openvox://policy/provenance-format |
Provenance file spec |
openvox://policy/trailers |
Trailer reference |
openvox://policy/deny-list |
Security deny-list |
openvox://policy/protected-files |
Protected files list |
Depth plugins are separate gems discovered automatically via gem naming convention (openvox-mcp-*).
Install a plugin gem and restart the server --- no code changes required.
| Plugin | Version | Status | Description |
|---|---|---|---|
openvox-mcp-puppet |
0.2.0 | Available | 15 Puppet tools, 6 resources, 4 renderers |
openvox-mcp-server |
0.1.0 | Built-in scaffold | OpenVox Server tools (4 tools, 2 resources) |
openvox-mcp-modules |
0.1.0 | Built-in scaffold | Voxpupuli module tools (4 tools, 3 resources) |
See docs/plugins.md for plugin installation, MCP client configuration, and .openvox-mcp.yml options.
Choose the method that fits your environment:
| Method | Ruby Required | Setup Effort | Best For |
|---|---|---|---|
| From source | Yes (user-managed) | Medium | Developers, contributors |
| Gem install | Yes (user-managed) | Medium | Power users, gem dependencies |
| Docker / Podman | No (in image) | Low | Quick setup, containers |
| System package | No (embedded) | Lowest | Production servers |
# 1. Clone and install
git clone https://github.com/OpenVoxProject/openvox-mcp.git
cd openvox-mcp
bundle install
# 2. Generate an API key (HTTP mode)
bin/openvox-mcp-server --generate-key --name my-first-client
# Save the printed key — it cannot be recovered.
# 3. Start the server
bin/openvox-mcp-serverAdd to your project's .mcp.json (Claude Code):
{
"mcpServers": {
"openvox-mcp": {
"type": "http",
"url": "http://localhost:9393",
"headers": {
"Authorization": "Bearer ovmcp_your_key_here"
}
}
}
}Or use stdio mode (no auth needed, for local development):
{
"mcpServers": {
"openvox-mcp": {
"command": "/absolute/path/to/openvox-mcp/bin/openvox-mcp-stdio",
"args": ["--plugin", "puppet"]
}
}
}See the installation guides for detailed step-by-step instructions for each method.
The HTTP transport includes a comprehensive security middleware stack:
| Feature | Default | Description |
|---|---|---|
| Authentication | API key (Bearer) | Per-client keyfile or single env var |
| TLS | Disabled | Built-in Puma TLS via --tls-cert/--tls-key |
| Origin validation | Localhost only | Allowlist-based, wildcard port matching |
| Rate limiting | 60/300 rpm | Token bucket, tiered (unauth/auth) |
| Request size | 1 MB | Returns 413 when exceeded |
| Content-Type | Required JSON | POST must be application/json |
| CORS | Disabled | Configurable origins/methods/headers |
| Host binding | Localhost only | --allow-remote required for 0.0.0.0 |
The server supports two key management modes:
Each client gets its own key with distinct identity, independent rotation, and per-client audit trails. Keys are stored as SHA-256 salted hashes in openvox-mcp-keys.yml.
Initial setup:
# 1. Generate your first key (creates keyfile if missing)
bin/openvox-mcp-server --generate-key --name claude-code
# Output: ovmcp_aBcDeFgHiJkLmNoPqRsTuVwXyZ...
# Save this key — it cannot be recovered.
# 2. Start the server
bin/openvox-mcp-server
# 3. Give the plaintext key to your AI tool
# Claude Code, Cursor, etc. use: Authorization: Bearer ovmcp_...Managing keys:
# List all keys (metadata only, hashes are never shown)
bin/openvox-mcp-server --list-keys
# Revoke a compromised key
bin/openvox-mcp-server --revoke-key --name old-client
# Rotate a key (revokes old, generates new)
bin/openvox-mcp-server --rotate-key --name claude-code
# Reload keys without restarting (Unix only)
kill -HUP $(pgrep -f openvox-mcp-server)Keyfile security:
- Keyfile permissions must be
0400(owner read-only). The server refuses to start if permissions are wider. - Keys are hashed with SHA-256 + per-key random salt. Plaintext keys never touch disk.
- Each key entry supports a configurable
algo:field for gradual algorithm migration. - Soft limit: warning at 50 keys (suggests OAuth 2.1 for larger deployments).
- Keys with an
expires_atfield are checked on every request. Expiring keys (within 7 days) trigger a startup warning.
Keyfile format (openvox-mcp-keys.yml):
version: "1.0"
keys:
- name: claude-code
algo: sha256_salt
key_hash: "a1b2c3...$d4e5f6..."
created_at: "2026-03-07"
expires_at: null
enabled: true
- name: ci-pipeline
algo: sha256_salt
key_hash: "f6e5d4...$c3b2a1..."
created_at: "2026-03-07"
enabled: false # revokedFor local development or simple deployments with one client:
# Generate a key (not written to keyfile)
ruby -rsecurerandom -e 'puts "ovmcp_#{SecureRandom.urlsafe_base64(32)}"'
# Set and start
export OPENVOX_MCP_API_KEY=ovmcp_your_key_here
bin/openvox-mcp-serverAll clients share the same key. Client identity is logged as api_key (no per-client distinction).
# Start with built-in Puma TLS
bin/openvox-mcp-server --tls-cert cert.pem --tls-key key.pem
# Allow non-localhost binding (required for remote access)
bin/openvox-mcp-server --host 0.0.0.0 --allow-remote --tls-cert cert.pem --tls-key key.pemAll HTTP security settings are configurable via .openvox-mcp.yml:
http:
authentication:
type: api_key # api_key | mtls | none
key_source: keyfile # keyfile (recommended) | env
keyfile_path: openvox-mcp-keys.yml # path to keyfile
api_key_env: OPENVOX_MCP_API_KEY # env var (when key_source: env)
tls:
enabled: true
cert_path: /path/to/cert.pem
key_path: /path/to/key.pem
origin:
allowed_origins:
- "https://myapp.example.com"
strict_mode: false
rate_limiting:
enabled: true
unauthenticated_rpm: 60
authenticated_rpm: 300
cors:
enabled: false
security_logging:
output: color # color | json | text
level: failures # failures | all | auditThe MCP server is configurable via .openvox-mcp.yml in your project root. See docs/architecture.md for full configuration reference.
See docs/plugins.md for MCP client configuration examples (Claude Code, VS Code, Cursor, Windsurf) for both stdio and HTTP transports with authentication headers.
Repositories can tighten or opt out of AI policy via .ai-policy-override.yml:
# Tighten: require additional review for AI contributions
ai_pr_threshold: 3 # stricter than default 5
# Opt out: disable AI modifications entirely
ai_modification: disabledOverrides can only tighten policy or opt out — never weaken existing protections.
This project implements a comprehensive AI governance framework. See AI_POLICY.md for the full policy covering:
- Attribution & Disclosure (Area A) — mandatory, no exceptions
- License Compliance (Area B) — DCO + SPDX + LicenseFinder CI
- Coding Standards (Area C) — linting, testing, dependency gates
- Security Boundaries (Area D) — deny-lists, network restrictions
- Scope Limitations (Area E) — protected files, remote access controls
- Accountability (Area F) — asymmetric shared responsibility
- Data Handling & Privacy (Area G) — vetted providers, privacy by design
- Community Consent & Opt-out (Area H) — tighten or opt out, never weaken
- Contribution Quality (Area I) — same bar minimum, higher preferred
Delegating responsibility to an AI tool is equivalent to saying "my hammer broke the window" — the person who swung the hammer is accountable.
| Document | Description |
|---|---|
| docs/getting-started.md | Zero to working MCP — choose your path |
| docs/operations.md | Day-to-day service management, key ops, TLS, backups |
| Document | Description |
|---|---|
| docs/install-package.md | System package (.deb/.rpm) — recommended for production |
| docs/install-from-source.md | From source — for developers |
| docs/install-gem.md | Via gem — for Ruby power users |
| docs/install-docker.md | Docker/Podman — for containers |
| Document | Description |
|---|---|
| docs/architecture.md | Technical architecture |
| docs/deployment.md | Deployment guide (systemd, user setup, TLS) |
| docs/plugins.md | Plugin usage, MCP client configuration, and development |
| docs/packaging-guide.md | Build, test & verify packages from source |
| docs/commit-trailers.md | Commit trailer reference and templates |
| Document | Description |
|---|---|
| AI_POLICY.md | Full AI governance policy |
| CONTRIBUTING.md | Contribution guide (human and AI workflows) |
| GOVERNANCE.md | Project governance and decision-making |
| SECURITY.md | Security policy and vulnerability reporting |
| DCO | Developer Certificate of Origin v1.1 |
| docs/ai-providers.md | Vetted AI provider list |
| docs/deny-list.md | Security deny-list reference |
| docs/incident-response.md | Incident response process |
| docs/meaningful-review.md | Meaningful review definition |
| docs/license-finder-setup.md | LicenseFinder CI setup guide |
| docs/voxbox-setup.md | Voxbox container setup guide |
The complete design was conducted as a structured dialog session. Every decision was discussed, challenged, and explicitly confirmed. See:
- design/session.md — full design session with all decisions
- design/decisions.md — decision log with rationale and Mermaid diagrams
- design/history.md — conversation history and design principles
- design/issues/ — 15 community issues created during design
This project is licensed under the GNU General Public License v3.0 only (GPL-3.0-only).
See LICENSE.md for the full license text.
Contributors may license their work under any GPL-3.0-compatible license. See CONTRIBUTING.md for details.
See AUTHORS for project authors and contributors.