| Name | viyv-mcp JSON |
| Version |
0.1.14
JSON |
| download |
| home_page | None |
| Summary | A simple wrapper library for FastMCP + Starlette |
| upload_time | 2025-10-11 09:14:05 |
| maintainer | None |
| docs_url | None |
| author | None |
| requires_python | >=3.10 |
| license | MIT |
| keywords |
mcp
fastmcp
starlette
uvicorn
|
| VCS |
 |
| bugtrack_url |
|
| requirements |
No requirements were recorded.
|
| Travis-CI |
No Travis.
|
| coveralls test coverage |
No coveralls.
|
# viyv_mcp
**viyv_mcp** is a production-ready Python wrapper around [FastMCP](https://github.com/jlowin/fastmcp) and [Starlette](https://www.starlette.io/) that simplifies creating MCP (Model Context Protocol) servers with minimal boilerplate.
[](https://badge.fury.io/py/viyv_mcp)
[](https://www.python.org/downloads/)
[](https://opensource.org/licenses/MIT)
[](https://pypi.org/project/viyv_mcp/)
## ๐ Quick Start
```bash
# 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
```python
from viyv_mcp import tool
@tool(description="Add two numbers")
def add(a: int, b: int) -> int:
return a + b
```
### ๐ค Agent Support with OpenAI Integration
```python
from viyv_mcp import agent
from viyv_mcp.openai_bridge import build_function_tools
@agent(name="calculator", use_tools=["add", "subtract"])
async def calculator_agent(query: str) -> str:
tools = build_function_tools(use_tools=["add", "subtract"])
# Agent implementation using OpenAI SDK
return f"Result: {result}"
```
### ๐ External MCP Server Bridge
```json
// 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)
```bash
# 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
```
### ๐ Built-in Integrations
- **Slack**: Full event handling, file management, thread context
- **OpenAI Agents SDK**: Seamless function calling bridge
- **ChatGPT**: Compatible with required `search`/`fetch` tools
- **Custom FastAPI Endpoints**: Mount additional APIs with `@entry`
## ๐ฆ Installation
```bash
# Basic installation
pip install viyv_mcp
# With all optional dependencies
pip install "viyv_mcp[slack,openai]"
```
## ๐ 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
### Tools with Runtime Context (Slack Integration)
```python
from viyv_mcp import tool
from viyv_mcp.run_context import RunContext
from agents import RunContextWrapper
def register(mcp):
@tool(description="Get user info from context")
def get_user_info(
wrapper: RunContextWrapper[RunContext],
user_id: str
) -> dict:
"""Get user information from Slack context"""
context = wrapper.context
if context and hasattr(context, 'slack_event'):
# Access Slack event data
return {"user": context.slack_event.get("user"), "channel": context.channel}
return {"user": user_id, "source": "direct"}
```
### Creating Resources with URI Templates
```python
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
```python
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.
"""
```
### Slack Bot with File Handling
```python
from viyv_mcp import entry
from viyv_mcp.app.adapters.slack_adapter import SlackAdapter
from viyv_mcp.run_context import RunContext
@entry("/slack")
def create_slack_app():
adapter = SlackAdapter(
bot_token=os.getenv("SLACK_BOT_TOKEN"),
signing_secret=os.getenv("SLACK_SIGNING_SECRET"),
context_cls=RunContext,
handle_files=True, # Enable file upload/download
build_thread_history=True, # Include thread context
)
return adapter.as_fastapi_app()
```
### ChatGPT-Compatible Tools
```python
from viyv_mcp import tool
def register(mcp):
# Required for ChatGPT integration
@tool(description="Search for information")
def search(query: str) -> list:
"""Search tool required by ChatGPT"""
results = perform_search(query)
return [{"resource_link": f"resource://{r.id}", "title": r.title} for r in results]
@tool(description="Fetch resource by ID")
def fetch(id: str) -> dict:
"""Fetch tool required by ChatGPT (note: 'id' not 'uri')"""
return get_resource_by_id(id)
```
### ๐ Tool Grouping (New in v0.1.13)
Organize tools into groups for better discoverability and UI presentation:
```python
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:**
```json
// 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
```bash
# 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
# Integration Keys (optional)
SLACK_BOT_TOKEN=xoxb-... # Slack bot token
SLACK_SIGNING_SECRET=... # Slack signing secret
OPENAI_API_KEY=sk-... # OpenAI API key
```
### Configuration Class
```python
# 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 `/mcp` path 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
### RunContextWrapper Pattern
- Signature manipulation for dual compatibility
- Works with both FastMCP and OpenAI Agents SDK
- Provides access to runtime context (Slack events, user info)
### 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
```python
# 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()
```
```bash
# Run with Gunicorn
gunicorn test_app:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
```
#### Docker Deployment
```dockerfile
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
```bash
# 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 `/mcp` path
- Check ASGI routing configuration
- Verify FastMCP version >= 2.12.3
#### Multi-Worker Startup Failures
- Enable `STATELESS_HTTP=true` for multi-worker mode
- Use Gunicorn instead of uvicorn's `--workers` flag
- Check for asyncio event loop conflicts
#### External MCP Server Issues
```bash
# 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.py` for validation patches
## ๐ Examples
Complete working examples in the `example/` directory:
- **`claude_code_mcp`**: Claude Code CLI integration
- **`test`**: Comprehensive example with all features
- Slack integration
- OpenAI Agents
- External MCP servers
- Custom endpoints
## ๐ค Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md).
### Development Setup
```bash
# 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
- Verify Slack and OpenAI integrations
- Check external MCP server bridging
## ๐ License
MIT License - see the [LICENSE](LICENSE) file for details.
## ๐ฅ Authors
- **Hiroki Takezawa** - [BrainFiber](https://github.com/BrainFiber)
## ๐ Acknowledgments
- Built on [FastMCP](https://github.com/jlowin/fastmcp) by jlowin
- Powered by [Starlette](https://www.starlette.io/) ASGI framework
- Implements [Model Context Protocol](https://modelcontextprotocol.io/) specification
- Slack integration via [Slack Bolt](https://slack.dev/bolt-python/)
- OpenAI integration via [OpenAI Agents SDK](https://github.com/openai/agents-sdk)
## ๐ฎ Support
- ๐ง Email: hiroki.takezawa@brainfiber.net
- ๐ Issues: [GitHub Issues](https://github.com/BrainFiber/viyv_mcp/issues)
- ๐ฌ Discussions: [GitHub Discussions](https://github.com/BrainFiber/viyv_mcp/discussions)
- ๐ Documentation: [Wiki](https://github.com/BrainFiber/viyv_mcp/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.13 (Latest)
- ๐ **Tool Grouping**: Organize tools with `group` parameter in `@tool` and `@agent` decorators
- ๐ท๏ธ **Vendor Namespace**: Uses `_meta.viyv.group` for MCP spec compliance
- ๐ **External MCP Grouping**: Support `group` and `group_map` in `mcp_server_configs/*.json`
- โจ **Optional Parameters**: Added `title` and `destructive` hints
- ๐ **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
- ๐ RunContextWrapper pattern for dual compatibility
### v0.1.8
- ๐ค OpenAI Agents SDK integration
- ๐ฌ Slack adapter with file handling
- ๐ฏ ChatGPT-compatible tool requirements
---
Made with โค๏ธ by the viyv_mcp community
Raw data
{
"_id": null,
"home_page": null,
"name": "viyv-mcp",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "mcp, fastmcp, starlette, uvicorn",
"author": null,
"author_email": "hiroki takezawa <hiroki.takezawa@brainfiber.net>",
"download_url": "https://files.pythonhosted.org/packages/3a/e7/85bde5d3a40953cc9d9e92b3f421d8a376afa34acef0dd38a7e1aa73c070/viyv_mcp-0.1.14.tar.gz",
"platform": null,
"description": "# viyv_mcp\n\n**viyv_mcp** is a production-ready Python wrapper around [FastMCP](https://github.com/jlowin/fastmcp) and [Starlette](https://www.starlette.io/) that simplifies creating MCP (Model Context Protocol) servers with minimal boilerplate.\n\n[](https://badge.fury.io/py/viyv_mcp)\n[](https://www.python.org/downloads/)\n[](https://opensource.org/licenses/MIT)\n[](https://pypi.org/project/viyv_mcp/)\n\n## \ud83d\ude80 Quick Start\n\n```bash\n# Install the package\npip install viyv_mcp\n\n# Create a new MCP server project\ncreate-viyv-mcp new my_mcp_server\n\n# Navigate to the project and install dependencies\ncd my_mcp_server\nuv sync\n\n# Run the server\nuv run python main.py\n```\n\nYour MCP server is now running at `http://localhost:8000` \ud83c\udf89\n\n## \u2728 Key Features\n\n### \ud83d\udee0\ufe0f Simple Tool Creation\n```python\nfrom viyv_mcp import tool\n\n@tool(description=\"Add two numbers\")\ndef add(a: int, b: int) -> int:\n return a + b\n```\n\n### \ud83e\udd16 Agent Support with OpenAI Integration\n```python\nfrom viyv_mcp import agent\nfrom viyv_mcp.openai_bridge import build_function_tools\n\n@agent(name=\"calculator\", use_tools=[\"add\", \"subtract\"])\nasync def calculator_agent(query: str) -> str:\n tools = build_function_tools(use_tools=[\"add\", \"subtract\"])\n # Agent implementation using OpenAI SDK\n return f\"Result: {result}\"\n```\n\n### \ud83c\udf09 External MCP Server Bridge\n```json\n// app/mcp_server_configs/filesystem.json\n{\n \"command\": \"npx\",\n \"args\": [\"@modelcontextprotocol/server-filesystem\", \"/workspace\"],\n \"env\": {\n \"API_KEY\": \"$API_KEY\" // Environment variable interpolation\n },\n \"cwd\": \"/path/to/working/dir\", // Optional\n \"tags\": [\"filesystem\", \"io\"] // Optional: for filtering\n}\n```\n\n### \ud83d\ude80 Production-Ready Multi-Worker Support (New in v0.1.10)\n```bash\n# Enable stateless HTTP mode for multi-worker deployments\nSTATELESS_HTTP=true uv run python main.py\n\n# Deploy with Gunicorn (recommended for production)\nuv pip install gunicorn\nSTATELESS_HTTP=true uv run gunicorn main:app \\\n -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000\n```\n\n### \ud83d\udd17 Built-in Integrations\n- **Slack**: Full event handling, file management, thread context\n- **OpenAI Agents SDK**: Seamless function calling bridge\n- **ChatGPT**: Compatible with required `search`/`fetch` tools\n- **Custom FastAPI Endpoints**: Mount additional APIs with `@entry`\n\n## \ud83d\udce6 Installation\n\n```bash\n# Basic installation\npip install viyv_mcp\n\n# With all optional dependencies\npip install \"viyv_mcp[slack,openai]\"\n```\n\n## \ud83d\udcc1 Project Structure\n\nWhen you create a new project with `create-viyv-mcp new my_project`:\n\n```\nmy_project/\n\u251c\u2500\u2500 main.py # Server entry point\n\u251c\u2500\u2500 pyproject.toml # Dependencies (managed by uv)\n\u251c\u2500\u2500 Dockerfile # Production-ready container\n\u251c\u2500\u2500 .env # Environment variables\n\u2514\u2500\u2500 app/\n \u251c\u2500\u2500 config.py # Configuration management\n \u251c\u2500\u2500 tools/ # MCP tools (@tool decorator)\n \u251c\u2500\u2500 resources/ # MCP resources (@resource decorator)\n \u251c\u2500\u2500 prompts/ # MCP prompts (@prompt decorator)\n \u251c\u2500\u2500 agents/ # AI agents (@agent decorator)\n \u251c\u2500\u2500 entries/ # Custom HTTP endpoints (@entry decorator)\n \u2514\u2500\u2500 mcp_server_configs/ # External MCP server configurations\n```\n\n## \ud83d\udcbb Advanced Usage Examples\n\n### Tools with Runtime Context (Slack Integration)\n\n```python\nfrom viyv_mcp import tool\nfrom viyv_mcp.run_context import RunContext\nfrom agents import RunContextWrapper\n\ndef register(mcp):\n @tool(description=\"Get user info from context\")\n def get_user_info(\n wrapper: RunContextWrapper[RunContext],\n user_id: str\n ) -> dict:\n \"\"\"Get user information from Slack context\"\"\"\n context = wrapper.context\n if context and hasattr(context, 'slack_event'):\n # Access Slack event data\n return {\"user\": context.slack_event.get(\"user\"), \"channel\": context.channel}\n return {\"user\": user_id, \"source\": \"direct\"}\n```\n\n### Creating Resources with URI Templates\n\n```python\nfrom viyv_mcp import resource\n\ndef register(mcp):\n @resource(\"database://{table}/{id}\")\n def get_record(table: str, id: str) -> dict:\n \"\"\"Fetch a database record by table and ID\"\"\"\n # Your database logic here\n return {\"table\": table, \"id\": id, \"data\": \"...\"}\n```\n\n### Prompts with Parameters\n\n```python\nfrom viyv_mcp import prompt\nfrom typing import Annotated\nfrom pydantic import Field\n\ndef register(mcp):\n @prompt(\"code_review\")\n def code_review_prompt(\n language: Annotated[str, Field(description=\"Programming language\")],\n code: Annotated[str, Field(description=\"Code to review\")]\n ) -> str:\n return f\"\"\"\n Please review this {language} code:\n ```{language}\n {code}\n ```\n Focus on: performance, security, and best practices.\n \"\"\"\n```\n\n### Slack Bot with File Handling\n\n```python\nfrom viyv_mcp import entry\nfrom viyv_mcp.app.adapters.slack_adapter import SlackAdapter\nfrom viyv_mcp.run_context import RunContext\n\n@entry(\"/slack\")\ndef create_slack_app():\n adapter = SlackAdapter(\n bot_token=os.getenv(\"SLACK_BOT_TOKEN\"),\n signing_secret=os.getenv(\"SLACK_SIGNING_SECRET\"),\n context_cls=RunContext,\n handle_files=True, # Enable file upload/download\n build_thread_history=True, # Include thread context\n )\n return adapter.as_fastapi_app()\n```\n\n### ChatGPT-Compatible Tools\n\n```python\nfrom viyv_mcp import tool\n\ndef register(mcp):\n # Required for ChatGPT integration\n @tool(description=\"Search for information\")\n def search(query: str) -> list:\n \"\"\"Search tool required by ChatGPT\"\"\"\n results = perform_search(query)\n return [{\"resource_link\": f\"resource://{r.id}\", \"title\": r.title} for r in results]\n\n @tool(description=\"Fetch resource by ID\")\n def fetch(id: str) -> dict:\n \"\"\"Fetch tool required by ChatGPT (note: 'id' not 'uri')\"\"\"\n return get_resource_by_id(id)\n```\n\n### \ud83d\udcc2 Tool Grouping (New in v0.1.13)\n\nOrganize tools into groups for better discoverability and UI presentation:\n\n```python\nfrom viyv_mcp import tool\n\ndef register(mcp):\n @tool(\n description=\"Add two numbers\",\n group=\"\u8a08\u7b97\u30c4\u30fc\u30eb\", # Group name\n title=\"\u52a0\u7b97\" # UI display name (optional)\n )\n def add(a: int, b: int) -> int:\n return a + b\n\n @tool(\n description=\"Subtract two numbers\",\n group=\"\u8a08\u7b97\u30c4\u30fc\u30eb\" # Same group\n )\n def subtract(a: int, b: int) -> int:\n return a - b\n\n @tool(\n description=\"Delete a file\",\n group=\"\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\",\n destructive=True # Destructive operation hint\n )\n def delete_file(path: str) -> bool:\n import os\n os.remove(path)\n return True\n```\n\n**External MCP Server Grouping:**\n\n```json\n// app/mcp_server_configs/filesystem.json\n{\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@modelcontextprotocol/server-filesystem\", \"/workspace\"],\n \"group\": \"\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\", // Apply to all tools\n \"group_map\": { // Override per tool (optional)\n \"read_file\": \"\u30d5\u30a1\u30a4\u30eb\u64cd\u4f5c/\u8aad\u307f\u8fbc\u307f\",\n \"write_file\": \"\u30d5\u30a1\u30a4\u30eb\u64cd\u4f5c/\u66f8\u304d\u8fbc\u307f\"\n }\n}\n```\n\n**How it works:**\n- Group information is stored in `_meta.viyv.group` (vendor namespace)\n- MCP clients can use groups for organized display\n- Backward compatible: tools without groups work normally\n\n## \ud83d\udd27 Configuration\n\n### Environment Variables\n\n```bash\n# Server Configuration\nHOST=0.0.0.0 # Server host (default: 127.0.0.1)\nPORT=8000 # Server port (default: 8000)\nSTATELESS_HTTP=true # Enable stateless mode for multi-worker\n\n# Directory Configuration\nBRIDGE_CONFIG_DIR=app/mcp_server_configs # External MCP configs\nSTATIC_DIR=static/images # Static file serving\n\n# Integration Keys (optional)\nSLACK_BOT_TOKEN=xoxb-... # Slack bot token\nSLACK_SIGNING_SECRET=... # Slack signing secret\nOPENAI_API_KEY=sk-... # OpenAI API key\n```\n\n### Configuration Class\n\n```python\n# app/config.py\nfrom viyv_mcp.app.config import Config\n\nclass MyConfig(Config):\n # Inherit base configuration\n\n @staticmethod\n def get_stateless_http():\n \"\"\"Get stateless HTTP setting from environment\"\"\"\n env_val = os.getenv(\"STATELESS_HTTP\", \"\").lower()\n if env_val in (\"true\", \"1\", \"yes\", \"on\"):\n return True\n elif env_val in (\"false\", \"0\", \"no\", \"off\"):\n return False\n return None # Use FastMCP default\n```\n\n## \ud83c\udfd7\ufe0f Architecture & Advanced Features\n\n### ASGI-Level Routing (SSE Streaming Fix)\nviyv_mcp implements custom ASGI routing to fix SSE streaming issues:\n- Direct `/mcp` path routing bypasses Starlette middleware\n- Ensures proper Server-Sent Events handling\n- Compatible with FastMCP's streaming protocol\n\n### Dynamic Tool Injection\n- Tools are refreshed on every request\n- Agents always have access to the latest tools\n- Supports runtime tool filtering with tags\n\n### RunContextWrapper Pattern\n- Signature manipulation for dual compatibility\n- Works with both FastMCP and OpenAI Agents SDK\n- Provides access to runtime context (Slack events, user info)\n\n### External MCP Server Management\n- Child process management with stdio communication\n- Automatic tool/resource/prompt registration\n- Environment variable interpolation in configs\n- Tag-based filtering for selective tool inclusion\n\n### Production Deployment Features\n\n#### Stateless HTTP Mode\n- No session ID requirements\n- Perfect for load-balanced environments\n- Enable with `STATELESS_HTTP=true`\n\n#### Multi-Worker Deployment\n```python\n# test_app.py - Create a module for Gunicorn\nfrom viyv_mcp import ViyvMCP\nfrom app.config import Config\n\nstateless_http = Config.get_stateless_http()\napp = ViyvMCP(\"Production Server\", stateless_http=stateless_http).get_app()\n```\n\n```bash\n# Run with Gunicorn\ngunicorn test_app:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000\n```\n\n#### Docker Deployment\n```dockerfile\nFROM python:3.10-slim\nWORKDIR /app\nCOPY . .\nRUN pip install uv && uv sync\nCMD [\"uv\", \"run\", \"gunicorn\", \"main:app\", \"-w\", \"4\", \"-k\", \"uvicorn.workers.UvicornWorker\", \"-b\", \"0.0.0.0:8000\"]\n```\n\n## \ud83d\udcca Performance Optimization\n\n### Caching Strategies\n- Tools are cached per request\n- External MCP connections are persistent\n- Static file serving with efficient caching headers\n\n### Resource Management\n- Automatic cleanup of external MCP processes\n- Connection pooling for external services\n- Graceful shutdown handling\n\n### Monitoring & Debugging\n```bash\n# Enable debug logging\nLOG_LEVEL=DEBUG uv run python main.py\n\n# Health check endpoint\ncurl http://localhost:8000/health\n```\n\n## \ud83d\udd0d Troubleshooting\n\n### Common Issues\n\n#### SSE Streaming Not Working\n- Ensure no middleware interferes with `/mcp` path\n- Check ASGI routing configuration\n- Verify FastMCP version >= 2.12.3\n\n#### Multi-Worker Startup Failures\n- Enable `STATELESS_HTTP=true` for multi-worker mode\n- Use Gunicorn instead of uvicorn's `--workers` flag\n- Check for asyncio event loop conflicts\n\n#### External MCP Server Issues\n```bash\n# Check external server logs\ntail -f logs/external_mcp.log\n\n# Verify command exists\nwhich npx\n\n# Test configuration\ncat app/mcp_server_configs/test.json | jq .\n```\n\n#### Protocol Compatibility\n- Use MCP protocol version 2024-11-05\n- Pydantic v2 compatibility is patched automatically\n- Check `mcp_initialize_fix.py` for validation patches\n\n## \ud83d\udcda Examples\n\nComplete working examples in the `example/` directory:\n\n- **`claude_code_mcp`**: Claude Code CLI integration\n- **`test`**: Comprehensive example with all features\n - Slack integration\n - OpenAI Agents\n - External MCP servers\n - Custom endpoints\n\n## \ud83e\udd1d Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md).\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/BrainFiber/viyv_mcp\ncd viyv_mcp\n\n# Install in development mode\npip install -e .\n\n# Run tests\npytest\n\n# Build package\npython -m build\n\n# Run example project\ncd example/test\nuv sync\nSTATELESS_HTTP=true uv run python main.py\n```\n\n### Testing Guidelines\n- Add sample implementations in `test/` directory\n- Test with both session and stateless modes\n- Verify Slack and OpenAI integrations\n- Check external MCP server bridging\n\n## \ud83d\udcc4 License\n\nMIT License - see the [LICENSE](LICENSE) file for details.\n\n## \ud83d\udc65 Authors\n\n- **Hiroki Takezawa** - [BrainFiber](https://github.com/BrainFiber)\n\n## \ud83d\ude4f Acknowledgments\n\n- Built on [FastMCP](https://github.com/jlowin/fastmcp) by jlowin\n- Powered by [Starlette](https://www.starlette.io/) ASGI framework\n- Implements [Model Context Protocol](https://modelcontextprotocol.io/) specification\n- Slack integration via [Slack Bolt](https://slack.dev/bolt-python/)\n- OpenAI integration via [OpenAI Agents SDK](https://github.com/openai/agents-sdk)\n\n## \ud83d\udcee Support\n\n- \ud83d\udce7 Email: hiroki.takezawa@brainfiber.net\n- \ud83d\udc1b Issues: [GitHub Issues](https://github.com/BrainFiber/viyv_mcp/issues)\n- \ud83d\udcac Discussions: [GitHub Discussions](https://github.com/BrainFiber/viyv_mcp/discussions)\n- \ud83d\udcd6 Documentation: [Wiki](https://github.com/BrainFiber/viyv_mcp/wiki)\n\n## \ud83d\udea6 Roadmap\n\n- [ ] WebSocket support for real-time communication\n- [ ] Built-in authentication/authorization\n- [ ] Tool versioning and migration support\n- [ ] Performance profiling dashboard\n- [ ] Plugin system for custom integrations\n- [ ] GraphQL endpoint support\n\n## \ud83d\udcc8 Changelog\n\n### v0.1.13 (Latest)\n- \ud83d\udcc2 **Tool Grouping**: Organize tools with `group` parameter in `@tool` and `@agent` decorators\n- \ud83c\udff7\ufe0f **Vendor Namespace**: Uses `_meta.viyv.group` for MCP spec compliance\n- \ud83c\udf09 **External MCP Grouping**: Support `group` and `group_map` in `mcp_server_configs/*.json`\n- \u2728 **Optional Parameters**: Added `title` and `destructive` hints\n- \ud83d\udd04 **Backward Compatible**: Tools without groups work normally\n- \ud83d\udcda Enhanced templates and documentation with grouping examples\n\n### v0.1.10\n- \u2728 Added stateless HTTP support for multi-worker deployments\n- \ud83d\udd27 Improved ASGI-level routing for SSE streaming\n- \ud83d\udce6 Updated FastMCP to 2.12.3 for better compatibility\n- \ud83d\udc1b Fixed Pydantic v2 validation issues\n- \ud83d\udcda Enhanced documentation and examples\n\n### v0.1.9\n- \ud83c\udf09 External MCP server bridging with tags and filtering\n- \ud83d\udd04 Dynamic tool refresh on every request\n- \ud83d\udcdd RunContextWrapper pattern for dual compatibility\n\n### v0.1.8\n- \ud83e\udd16 OpenAI Agents SDK integration\n- \ud83d\udcac Slack adapter with file handling\n- \ud83c\udfaf ChatGPT-compatible tool requirements\n\n---\n\nMade with \u2764\ufe0f by the viyv_mcp community\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A simple wrapper library for FastMCP + Starlette",
"version": "0.1.14",
"project_urls": {
"Homepage": "https://github.com/BrainFiber/viyv_mcp",
"Repository": "https://github.com/BrainFiber/viyv_mcp"
},
"split_keywords": [
"mcp",
" fastmcp",
" starlette",
" uvicorn"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "1af84333620ff6c0b51c4fdaa8d521ec734c71898f750d844ced1cd712c39c1b",
"md5": "3375b8474c1d1fbf1ade20beafe67b64",
"sha256": "88cfd05fa63eccc12cd244ae659a30f8ddc6d605c32a9cfb25ea6e6dabc74b4f"
},
"downloads": -1,
"filename": "viyv_mcp-0.1.14-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3375b8474c1d1fbf1ade20beafe67b64",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 53396,
"upload_time": "2025-10-11T09:14:03",
"upload_time_iso_8601": "2025-10-11T09:14:03.709174Z",
"url": "https://files.pythonhosted.org/packages/1a/f8/4333620ff6c0b51c4fdaa8d521ec734c71898f750d844ced1cd712c39c1b/viyv_mcp-0.1.14-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "3ae785bde5d3a40953cc9d9e92b3f421d8a376afa34acef0dd38a7e1aa73c070",
"md5": "0a888be3b98790471269262538867a0c",
"sha256": "1a7245073ec1ad9586eebacd3cb564486d43df0366c80cf77bb166963d679185"
},
"downloads": -1,
"filename": "viyv_mcp-0.1.14.tar.gz",
"has_sig": false,
"md5_digest": "0a888be3b98790471269262538867a0c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 47216,
"upload_time": "2025-10-11T09:14:05",
"upload_time_iso_8601": "2025-10-11T09:14:05.199500Z",
"url": "https://files.pythonhosted.org/packages/3a/e7/85bde5d3a40953cc9d9e92b3f421d8a376afa34acef0dd38a7e1aa73c070/viyv_mcp-0.1.14.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-11 09:14:05",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "BrainFiber",
"github_project": "viyv_mcp",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "viyv-mcp"
}