Skip to main content

Vestibule

v0.1.0 Beta — Initial release. Installation via uv from source (not yet on PyPI).

A plugin-based MCP (Model Context Protocol) server using pluggy for extensibility.

Overview

Vestibule provides a secure way to expose custom tools to AI agents while keeping sensitive information (credentials, email addresses, API keys) hidden from the agent. Plugins implement email whitelisting, calendar access, and other sensitive operations behind clean tool interfaces.

Think of it as a gateway between AI and action — the vestibule controls what passes through, ensuring only safe, validated operations proceed.

Features

  • Plugin Architecture: Discover and load plugins via entry points
  • Secrets Management: Environment-based secrets with plugin-declared prefixes
  • TOML Configuration: Multi-level config merging (CLI > project > user > defaults)
  • Pydantic Validation: Plugin configs validated against declared schemas at startup
  • Fail-Fast: Server exits with clear errors if config or secrets validation fails
  • MCP Protocol: Full support for tools, resources, and prompts
  • Dual Transport: Stdio and HTTP/SSE transports

Quick Start

Installation

Vestibule 0.1.0 is not yet published to PyPI. Install from source using uv:

# Clone the repository
git clone https://github.com/b34nst4lk/vestibule.git
cd vestibule

# Install the server and workspace plugins
uv sync

This installs:

  • vestibule — the core MCP server
  • vestibule-email — email whitelisting plugin (workspace only)
  • vestibule-example — minimal example plugin for plugin authors

Note: The vestibule-email plugin is included as a workspace package for testing. A standalone PyPI package will be available in a future release. The vestibule-example plugin demonstrates the plugin API but is not published to PyPI.

Configuration

Create .vestibule/config.toml:

[tool.vestibule]
host = "localhost"
port = 8080
transport = "stdio"

[tool.vestibule.plugins.email]
smtp_host = "smtp.gmail.com"
sender_email = "you@gmail.com"

[tool.vestibule.plugins.email.whitelist]
alice = "alice@example.com"
bob = "bob@example.com"

Set environment variables (or use .env):

EMAIL_SMTP_PASSWORD=your_app_password
EMAIL_SENDER_EMAIL=you@gmail.com
EMAIL_WHITELIST='{"alice": "alice@example.com", "bob": "bob@example.com"}'

Running

# Run with stdio transport (for MCP clients)
uv run python main.py

# Or use the CLI
vestibule serve

Available Plugins

vestibule-email (workspace only)

Email whitelisting plugin that allows sending emails only to pre-approved recipients.

Tools:

  • send_email(recipient_name, subject, body, cc_recipient_name) - Send an email
  • list_whitelist() - List all whitelisted recipients
  • add_to_whitelist(name, email) - Add a recipient to the runtime whitelist

Note: This plugin is included as a workspace package for testing. A standalone PyPI package will be available in a future release.

vestibule-example

Minimal example plugin demonstrating the Vestibule plugin API. Use this as a template for creating your own plugins.

Tools:

  • list_whitelist() - List all whitelisted recipients
  • add_to_whitelist(name, email) - Add a recipient to the runtime whitelist
  • remove_from_whitelist(name) - Remove a recipient from the runtime whitelist

Note: This plugin is included for plugin authors as a template. It is not published to PyPI — only the vestibule server is released. See packages/vestibule_example/README.md for the plugin author guide.

Plugin Development

Creating a Plugin

  1. Create a new package with entry point:
# pyproject.toml
[project.entry-points."vestibule.plugins"]
my-plugin = "vestibule_my_plugin"
  1. Implement hooks in __init__.py:
from vestibule import hooks
from pydantic import BaseModel

@hooks.hookimpl
def vestibule_register_plugin_info():
    return "my-plugin", hooks.PluginMetadata(
        name="my-plugin",
        version="1.0.0",
        description="My custom plugin"
    )

@hooks.hookimpl
def vestibule_config_schema():
    return MyPluginConfig  # Pydantic model

@hooks.hookimpl
def vestibule_register_tools(mcp_server):
    @mcp_server.tool()
    def my_tool(arg: str) -> str:
        return f"Result: {arg}"

Available Hooks

Hook Purpose First Result
vestibule_register_plugin_info Return plugin metadata Yes
vestibule_register_tools Register MCP tools No
vestibule_register_resources Register MCP resources No
vestibule_register_prompts Register MCP prompts No
vestibule_validate_secrets Validate required secrets No
vestibule_config_schema Return Pydantic config schema Yes
vestibule_init Initialize plugin with validated config No

Project Structure

vestibule/
  vestibule/                 # Core server package
    __init__.py
    hooks.py                  # Pluggy hook specifications
    plugin_manager.py         # Plugin discovery and loading
    config.py                 # Configuration loading
    cli.py                    # CLI commands
    transports/
      stdio.py                # Stdio transport
      http_sse.py             # HTTP/SSE transport
      common.py               # Shared handlers
  packages/
    vestibule_email/         # Email whitelisting plugin
      vestibule_email/
        __init__.py
      tests/
  tests/                      # Server tests
  .vestibule/
    config.toml.example       # Example configuration
  .env.example                # Example environment variables

Commands

# Run tests
uv run pytest

# Run with coverage
uv run pytest --cov=vestibule --cov=packages/vestibule_email

# Run the server
uv run python main.py

# CLI commands
vestibule serve              # Start the server
vestibule healthcheck        # Validate plugin secrets
vestibule plugins            # List loaded plugins
vestibule version            # Show version

License

MIT

Metadata

Release files for vestibule 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vestibule 0.1.0
File Size Uploaded Provenance Actions
vestibule-0.1.0.tar.gz 107.3 kB With provenance Details for vestibule-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for vestibule 0.1.0
File Interpreter ABI Platform Actions
vestibule-0.1.0-py3-none-any.whl Python 3 none any Details for vestibule-0.1.0-py3-none-any.whl

Total release size: 131.8 kB

Release files / vestibule-0.1.0.tar.gz

Download URL vestibule-0.1.0.tar.gz
Size 107.3 kB
Tags Source
SHA-256 checksum
How to use checksums
a06eb01320970207786a62f26ed34de497cbabbe3f3d61ce5235f0976069eca4
BLAKE2b-256 checksum
How to use checksums
f707fe3625af6d6a9d862649e8fb2ccda607c125120f1f5e5ba999aaaba4dc84
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

Release files / vestibule-0.1.0-py3-none-any.whl

Download URL vestibule-0.1.0-py3-none-any.whl
Size 24.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
61de30f0be6b25bd6462b70cd42b6034cfec0c1873741a0185464158daad4cf0
BLAKE2b-256 checksum
How to use checksums
f0816347a5b509cdc1f1b111a233593aaa3cd3acb8e00be4428a5d12202472fa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

Security for vestibule 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for vestibule-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 7, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page