Skip to main content

mcpd-plugins: Python SDK for Building mcpd Plugins

License Python Version

A Python SDK for building plugins for the mcpd plugin system. This SDK provides a simple, async-first API for creating gRPC-based plugins that can intercept and transform HTTP requests and responses.

Features

  • Simple API: Extend BasePlugin and override only the methods you need
  • Async/Await: Full async support using Python's asyncio
  • Type Hints: Complete type annotations for better IDE support
  • gRPC-based: Built on grpcio with protocol buffers
  • Minimal Dependencies: Only requires grpcio and protobuf
  • Comprehensive Examples: Five example plugins demonstrating common patterns

Installation

# Using uv (recommended)
uv add mcpd-plugins

# Using pip
pip install mcpd-plugins

Quick Start

Here's a minimal plugin that adds a custom header to HTTP requests:

import asyncio
import sys
from mcpd_plugins import BasePlugin, serve
from mcpd_plugins.v1.plugins.plugin_pb2 import (
    FLOW_REQUEST,
    Capabilities,
    HTTPRequest,
    HTTPResponse,
    Metadata,
)
from google.protobuf.empty_pb2 import Empty


class MyPlugin(BasePlugin):
    async def GetMetadata(self, request: Empty, context) -> Metadata:
        return Metadata(
            name="my-plugin",
            version="1.0.0",
            description="Adds a custom header to requests"
        )

    async def GetCapabilities(self, request: Empty, context) -> Capabilities:
        return Capabilities(flows=[FLOW_REQUEST])

    async def HandleRequest(self, request: HTTPRequest, context) -> HTTPResponse:
        response = HTTPResponse(**{"continue": True})
        response.modified_request.CopyFrom(request)
        response.modified_request.headers["X-My-Plugin"] = "processed"
        return response


if __name__ == "__main__":
    # Pass sys.argv for mcpd compatibility (handles --address and --network flags)
    asyncio.run(serve(MyPlugin(), sys.argv))

Run your plugin:

# For mcpd (with --address and --network arguments)
python my_plugin.py --address /tmp/my-plugin.sock --network unix

# For standalone testing (defaults to TCP port 50051)
python my_plugin.py

When running under mcpd, the --address and --network flags are required and automatically passed by mcpd. For standalone testing without arguments, the plugin defaults to TCP on port 50051.

Core Concepts

BasePlugin

The BasePlugin class provides default implementations for all plugin methods:

  • Configure() - Initialize plugin with configuration
  • Stop() - Clean up resources on shutdown
  • GetMetadata() - Return plugin name, version, and description
  • GetCapabilities() - Declare which flows the plugin supports
  • CheckHealth() - Health check endpoint
  • CheckReady() - Readiness check endpoint
  • HandleRequest() - Process incoming HTTP requests
  • HandleResponse() - Process outgoing HTTP responses

Override only the methods your plugin needs.

Flows

Plugins can process two types of flows:

  • FLOW_REQUEST: Intercept and modify incoming HTTP requests
  • FLOW_RESPONSE: Intercept and modify outgoing HTTP responses

Declare your supported flows in GetCapabilities().

Request/Response Handling

When handling requests or responses, you can:

  1. Pass through unchanged: Return HTTPResponse(**{"continue": True})
  2. Modify and continue: Set **{"continue": True} and modify fields
  3. Reject: Set **{"continue": False} with a status code and body

Examples

The SDK includes five example plugins demonstrating common patterns:

1. Simple Plugin

Adds a custom header to all requests.

cd examples/simple_plugin
uv run python main.py

2. Auth Plugin

Validates Bearer token authentication and rejects unauthorized requests.

export AUTH_TOKEN="your-secret-token"
cd examples/auth_plugin
uv run python main.py

3. Logging Plugin

Logs HTTP request and response details for observability.

cd examples/logging_plugin
uv run python main.py

4. Rate Limit Plugin

Implements token bucket rate limiting per client IP.

cd examples/rate_limit_plugin
uv run python main.py

5. Transform Plugin

Transforms JSON request bodies by adding metadata fields.

cd examples/transform_plugin
uv run python main.py

Development

Setup

# Clone the repository
git clone https://github.com/mozilla-ai/mcpd-plugins-sdk-python.git
cd mcpd-plugins-sdk-python

# Setup development environment
make setup

Running Tests

# Run all tests
make test

# Run with verbose output
uv run pytest -v

# Run specific test file
uv run pytest tests/unit/test_base_plugin.py

Linting

# Run all pre-commit hooks
make lint

# Run ruff directly
uv run ruff check src/ tests/
uv run ruff format src/ tests/

Generating Protocol Buffers

The proto files are automatically generated from the mcpd-proto repository and committed to this repo. To regenerate:

make generate-protos

API Reference

BasePlugin

class BasePlugin(PluginServicer):
    async def Configure(self, request: PluginConfig, context) -> Empty
    async def Stop(self, request: Empty, context) -> Empty
    async def GetMetadata(self, request: Empty, context) -> Metadata
    async def GetCapabilities(self, request: Empty, context) -> Capabilities
    async def CheckHealth(self, request: Empty, context) -> Empty
    async def CheckReady(self, request: Empty, context) -> Empty
    async def HandleRequest(self, request: HTTPRequest, context) -> HTTPResponse
    async def HandleResponse(self, response: HTTPResponse, context) -> HTTPResponse

serve()

async def serve(
    plugin: BasePlugin,
    args: Optional[list[str]] = None,  # Command-line arguments (typically sys.argv)
    grace_period: float = 5.0,
) -> None

Parameters:

  • plugin: The plugin instance to serve
  • args: Command-line arguments. When provided (e.g., sys.argv), enables mcpd compatibility by parsing --address and --network flags. When None, runs in standalone mode on TCP port 50051.
  • grace_period: Seconds to wait during graceful shutdown

Command-line flags (when args is provided):

  • --address: gRPC address (socket path for unix, host:port for tcp) - required
  • --network: Network type (unix or tcp) - defaults to unix

Exceptions

  • PluginError - Base exception for all plugin errors
  • ConfigurationError - Configuration-related errors
  • ServerError - Server startup/shutdown errors

Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Security

For security issues, please see SECURITY.md.

License

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

Metadata

Release files for mcpd-plugins 0.0.1

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

Source distribution (sdist)

Source distribution for mcpd-plugins 0.0.1
File Size Uploaded Provenance
mcpd_plugins-0.0.1.tar.gz 76.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for mcpd-plugins 0.0.1
File Interpreter ABI Platform
mcpd_plugins-0.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 93.9 kB

Release files / mcpd_plugins-0.0.1.tar.gz

Download URL mcpd_plugins-0.0.1.tar.gz
Size 76.2 kB
Tags Source
SHA-256 checksum
How to use checksums
7a65c3b157fd103ffe693c008837f423d840372a4459580793470cf5b4346fa3
BLAKE2b-256 checksum
How to use checksums
af2976216a0221b5a389a7f85863824594c8becddee2e8a6e30403a93fde84a3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Nov 4, 2025.

Transparency log

Release files / mcpd_plugins-0.0.1-py3-none-any.whl

Download URL mcpd_plugins-0.0.1-py3-none-any.whl
Size 17.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9712e64ee5bf9ae9369cb90909653d82c51628b51277504a115aa1b6d9cb57a3
BLAKE2b-256 checksum
How to use checksums
488ac4e6b7b4956cc56b64e2b5e58865a8cb9de67f89619e0781cbf875bc2835
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

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 Nov 4, 2025.

Transparency log

Security for mcpd-plugins 0.0.1

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

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for mcpd_plugins-0.0.1.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 Nov 4, 2025.

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.0.1 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