A wrapper library for MCP (Model Context Protocol) + Starlette
Project description
viyv_mcp
viyv_mcp is a production-ready Python wrapper around FastMCP and Starlette that simplifies creating MCP (Model Context Protocol) servers with minimal boilerplate.
๐ Quick Start
# Install the package
pip install viyv_mcp
# Create a new MCP server project
create-viyv-mcp new my_mcp_server
# Navigate to the project and install dependencies
cd my_mcp_server
uv sync
# Run the server
uv run python main.py
Your MCP server is now running at http://localhost:8000 ๐
โจ Key Features
๐ ๏ธ Simple Tool Creation
from viyv_mcp import tool
@tool(description="Add two numbers")
def add(a: int, b: int) -> int:
return a + b
๐ External MCP Server Bridge
// app/mcp_server_configs/filesystem.json
{
"command": "npx",
"args": ["@modelcontextprotocol/server-filesystem", "/workspace"],
"env": {
"API_KEY": "$API_KEY" // Environment variable interpolation
},
"cwd": "/path/to/working/dir", // Optional
"tags": ["filesystem", "io"] // Optional: for filtering
}
๐ Production-Ready Multi-Worker Support (New in v0.1.10)
# Enable stateless HTTP mode for multi-worker deployments
STATELESS_HTTP=true uv run python main.py
# Deploy with Gunicorn (recommended for production)
uv pip install gunicorn
STATELESS_HTTP=true uv run gunicorn main:app \
-w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
๐ JWT Authentication & Access Control
# Tools with security metadata
@tool(
description="Query salary",
namespace="hr", # Visible only to hr agents
security_level="confidential", # Requires confidential+ clearance
)
def query_salary(employee_id: str) -> str:
return f"Salary: $100,000"
# Generate JWT for an agent
python -m viyv_mcp generate-jwt \
--sub hr-agent --clearance confidential --namespace hr \
--trust common --expires 24h --secret "$SECRET"
- Namespace: Controls tool visibility (
tools/listfiltering) - Security Level: Controls tool executability (
tools/callclearance check) - Modes: bypass (dev), authenticated (JWT), deny_all (default safe)
- Both transports: Works for stdio (
.mcp.json) and HTTP
๐ Built-in Integrations
- Custom FastAPI Endpoints: Mount additional APIs with
@entry
๐ฆ Installation
# Basic installation
pip install viyv_mcp
# With optional security config (YAML support)
pip install "viyv_mcp[security]"
๐ Project Structure
When you create a new project with create-viyv-mcp new my_project:
my_project/
โโโ main.py # Server entry point
โโโ pyproject.toml # Dependencies (managed by uv)
โโโ Dockerfile # Production-ready container
โโโ .env # Environment variables
โโโ app/
โโโ config.py # Configuration management
โโโ tools/ # MCP tools (@tool decorator)
โโโ resources/ # MCP resources (@resource decorator)
โโโ prompts/ # MCP prompts (@prompt decorator)
โโโ agents/ # AI agents (@agent decorator)
โโโ entries/ # Custom HTTP endpoints (@entry decorator)
โโโ mcp_server_configs/ # External MCP server configurations
๐ป Advanced Usage Examples
Creating Resources with URI Templates
from viyv_mcp import resource
def register(mcp):
@resource("database://{table}/{id}")
def get_record(table: str, id: str) -> dict:
"""Fetch a database record by table and ID"""
# Your database logic here
return {"table": table, "id": id, "data": "..."}
Prompts with Parameters
from viyv_mcp import prompt
from typing import Annotated
from pydantic import Field
def register(mcp):
@prompt("code_review")
def code_review_prompt(
language: Annotated[str, Field(description="Programming language")],
code: Annotated[str, Field(description="Code to review")]
) -> str:
return f"""
Please review this {language} code:
```{language}
{code}
```
Focus on: performance, security, and best practices.
"""
๐ Tool Grouping (New in v0.1.13)
Organize tools into groups for better discoverability and UI presentation:
from viyv_mcp import tool
def register(mcp):
@tool(
description="Add two numbers",
group="่จ็ฎใใผใซ", # Group name
title="ๅ ็ฎ" # UI display name (optional)
)
def add(a: int, b: int) -> int:
return a + b
@tool(
description="Subtract two numbers",
group="่จ็ฎใใผใซ" # Same group
)
def subtract(a: int, b: int) -> int:
return a - b
@tool(
description="Delete a file",
group="ใใกใคใซใทในใใ ",
destructive=True # Destructive operation hint
)
def delete_file(path: str) -> bool:
import os
os.remove(path)
return True
External MCP Server Grouping:
// app/mcp_server_configs/filesystem.json
{
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"],
"group": "ใใกใคใซใทในใใ ", // Apply to all tools
"group_map": { // Override per tool (optional)
"read_file": "ใใกใคใซๆไฝ/่ชญใฟ่พผใฟ",
"write_file": "ใใกใคใซๆไฝ/ๆธใ่พผใฟ"
}
}
How it works:
- Group information is stored in
_meta.viyv.group(vendor namespace) - MCP clients can use groups for organized display
- Backward compatible: tools without groups work normally
๐ง Configuration
Environment Variables
# Server Configuration
HOST=0.0.0.0 # Server host (default: 127.0.0.1)
PORT=8000 # Server port (default: 8000)
STATELESS_HTTP=true # Enable stateless mode for multi-worker
# Directory Configuration
BRIDGE_CONFIG_DIR=app/mcp_server_configs # External MCP configs
STATIC_DIR=static/images # Static file serving
Configuration Class
# app/config.py
from viyv_mcp.app.config import Config
class MyConfig(Config):
# Inherit base configuration
@staticmethod
def get_stateless_http():
"""Get stateless HTTP setting from environment"""
env_val = os.getenv("STATELESS_HTTP", "").lower()
if env_val in ("true", "1", "yes", "on"):
return True
elif env_val in ("false", "0", "no", "off"):
return False
return None # Use FastMCP default
๐๏ธ Architecture & Advanced Features
ASGI-Level Routing (SSE Streaming Fix)
viyv_mcp implements custom ASGI routing to fix SSE streaming issues:
- Direct
/mcppath routing bypasses Starlette middleware - Ensures proper Server-Sent Events handling
- Compatible with FastMCP's streaming protocol
Dynamic Tool Injection
- Tools are refreshed on every request
- Agents always have access to the latest tools
- Supports runtime tool filtering with tags
External MCP Server Management
- Child process management with stdio communication
- Automatic tool/resource/prompt registration
- Environment variable interpolation in configs
- Tag-based filtering for selective tool inclusion
Production Deployment Features
Stateless HTTP Mode
- No session ID requirements
- Perfect for load-balanced environments
- Enable with
STATELESS_HTTP=true
Multi-Worker Deployment
# test_app.py - Create a module for Gunicorn
from viyv_mcp import ViyvMCP
from app.config import Config
stateless_http = Config.get_stateless_http()
app = ViyvMCP("Production Server", stateless_http=stateless_http).get_app()
# Run with Gunicorn
gunicorn test_app:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
Docker Deployment
FROM python:3.10-slim
WORKDIR /app
COPY . .
RUN pip install uv && uv sync
CMD ["uv", "run", "gunicorn", "main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "-b", "0.0.0.0:8000"]
๐ Performance Optimization
Caching Strategies
- Tools are cached per request
- External MCP connections are persistent
- Static file serving with efficient caching headers
Resource Management
- Automatic cleanup of external MCP processes
- Connection pooling for external services
- Graceful shutdown handling
Monitoring & Debugging
# Enable debug logging
LOG_LEVEL=DEBUG uv run python main.py
# Health check endpoint
curl http://localhost:8000/health
๐ Troubleshooting
Common Issues
SSE Streaming Not Working
- Ensure no middleware interferes with
/mcppath - Check ASGI routing configuration
- Verify FastMCP version >= 2.12.3
Multi-Worker Startup Failures
- Enable
STATELESS_HTTP=truefor multi-worker mode - Use Gunicorn instead of uvicorn's
--workersflag - Check for asyncio event loop conflicts
External MCP Server Issues
# Check external server logs
tail -f logs/external_mcp.log
# Verify command exists
which npx
# Test configuration
cat app/mcp_server_configs/test.json | jq .
Protocol Compatibility
- Use MCP protocol version 2024-11-05
- Pydantic v2 compatibility is patched automatically
- Check
mcp_initialize_fix.pyfor validation patches
๐ Examples
Complete working examples in the example/ directory:
claude_code_mcp: Claude Code CLI integrationtest: Comprehensive example with all features- External MCP servers
- Custom endpoints
๐ค Contributing
We welcome contributions! Please see our Contributing Guide.
Development Setup
# Clone the repository
git clone https://github.com/BrainFiber/viyv_mcp
cd viyv_mcp
# Install in development mode
pip install -e .
# Run tests
pytest
# Build package
python -m build
# Run example project
cd example/test
uv sync
STATELESS_HTTP=true uv run python main.py
Testing Guidelines
- Add sample implementations in
test/directory - Test with both session and stateless modes
- Check external MCP server bridging
๐ License
MIT License - see the LICENSE file for details.
๐ฅ Authors
- Hiroki Takezawa - BrainFiber
๐ Acknowledgments
- Built on FastMCP by jlowin
- Powered by Starlette ASGI framework
- Implements Model Context Protocol specification
๐ฎ Support
- ๐ง Email: hiroki.takezawa@brainfiber.net
- ๐ Issues: GitHub Issues
- ๐ฌ Discussions: GitHub Discussions
- ๐ Documentation: Wiki
๐ฆ Roadmap
- WebSocket support for real-time communication
- Built-in authentication/authorization
- Tool versioning and migration support
- Performance profiling dashboard
- Plugin system for custom integrations
- GraphQL endpoint support
๐ Changelog
v0.1.14 (Latest - 2025-10-13)
- ๐ Implementation Examples: Added comprehensive tool grouping examples in
example/test- 9 internal tools with group organization (Math, Statistics, Web Search, Image Tools)
- Real-world Playwright MCP server configuration (20 browser automation tools)
- ๐ Enhanced Documentation:
GROUPING_IMPLEMENTATION.md- detailed implementation reportapp/mcp_server_configs/README.md- external MCP server grouping guide- Sample configuration files for learning
- โ Verified Implementation: All examples tested and working with MCP Inspector
- ๐ฏ Makes tool grouping feature (v0.1.13) immediately usable with practical examples
v0.1.13
- ๐ Tool Grouping: Organize tools with
groupparameter in@tooland@agentdecorators - ๐ท๏ธ Vendor Namespace: Uses
_meta.viyv.groupfor MCP spec compliance - ๐ External MCP Grouping: Support
groupandgroup_mapinmcp_server_configs/*.json - โจ Optional Parameters: Added
titleanddestructivehints - ๐ Backward Compatible: Tools without groups work normally
- ๐ Enhanced templates and documentation with grouping examples
v0.1.10
- โจ Added stateless HTTP support for multi-worker deployments
- ๐ง Improved ASGI-level routing for SSE streaming
- ๐ฆ Updated FastMCP to 2.12.3 for better compatibility
- ๐ Fixed Pydantic v2 validation issues
- ๐ Enhanced documentation and examples
v0.1.9
- ๐ External MCP server bridging with tags and filtering
- ๐ Dynamic tool refresh on every request
Made with โค๏ธ by the viyv_mcp community
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file viyv_mcp-2.0.1.tar.gz.
File metadata
- Download URL: viyv_mcp-2.0.1.tar.gz
- Upload date:
- Size: 61.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a43a26135ecf06ec950e8df821f4cf5d04471ed222bdff1e6ba2e6372a856ec9
|
|
| MD5 |
9c02896586352ac36798bc5f6624c13b
|
|
| BLAKE2b-256 |
bc841630231a4d4196c45e20ee0177174f36ad6c5ff6d176cb970131e4ce1226
|
File details
Details for the file viyv_mcp-2.0.1-py3-none-any.whl.
File metadata
- Download URL: viyv_mcp-2.0.1-py3-none-any.whl
- Upload date:
- Size: 61.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a16416d0b1fd0d71efbc3a15b909eafbd31edf29bde104fd17f4450598778b7f
|
|
| MD5 |
969ca8d1ec53d81a6d356ef97b0844bc
|
|
| BLAKE2b-256 |
1e001f9a470ba16befee2bfdfa4b05989528611e6e098725fa16f4a84f1f9446
|