This project implements a basic MCP (Model Context Protocol) server for a conversational AI "waifu" character. It uses the mcp library for Python to handle the protocol details and FastMCP for easy server setup.
uvClone the repository:
bash
git clone <repository_url>
cd mcp-waifu-chat
Install uv (if not installed)
With curl:
bash
curl -LsSf https://astral.sh/uv/install.sh | sh
Or with powershell:
powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Create the virtual environment and ensure tooling inside:
bash
python -m uv venv .venv
.venv/Scripts/python.exe -m ensurepip
.venv/Scripts/python.exe -m pip install uv
Install dependencies:
bash
.venv/Scripts/python.exe -m uv pip install -e .[test]
The server uses a combination of a file for the API key and environment variables (or a .env file) for other configurations.
API Key:
OpenRouter (default):
- Preferred via environment variable: OPENROUTER_API_KEY
- Fallback: single-line key file ~/.api-openrouter
- Model resolution precedence:
1) OPENROUTER_MODEL_NAME
2) ~/.model-openrouter
3) openrouter/free
You can obtain a key from OpenRouter.
Other Configuration (.env file or environment variables):
An example .env.example file is provided for other settings:
DATABASE_FILE=dialogs.db
DEFAULT_RESPONSE="I'm sorry, I'm having trouble connecting to the AI model."
DEFAULT_GENRE="Fantasy"
FLASK_PORT=5000
OPENROUTER_MODEL_NAME=openrouter/free
DATABASE_FILE: Path to the SQLite database file (default: dialogs.db).DEFAULT_RESPONSE: The default response to send when the AI model is unavailable (default: "The AI model is currently unavailable. Please try again later.").DEFAULT_GENRE: The default conversation genre (default: "Romance").FLASK_PORT: The port the server will listen on (default: 5000).OPENROUTER_MODEL_NAME: The specific OpenRouter model to use (default: openrouter/free).Copy .env.example to .env and customize the values as needed (except for the API key, which is read from ~/.api-openrouter).
Ensure your ~/.api-openrouter file is set up correctly. Then, to run the server, use:
uv run mcp-waifu-chat
This runs the mcp_waifu_chat/api.py file (since that's where the FastMCP instance is defined) and starts up the server.
To run the unit tests:
uv run pytest
This will execute all tests in the tests/ directory using pytest. The tests include database tests and API endpoint tests.
The server provides the following MCP-compliant endpoints (using FastMCP's automatic routing):
/v1/server/status (GET): Checks the server status. Returns {"status": "ok"}. This is a standard MCP endpoint.These are implemented as MCP tools.
create_user (user_id: str): Creates a new user.check_user (user_id: str): Checks if a user exists. Returns {"user_id": str, "exists": bool}.delete_user (user_id: str): Deletes a user.user_count: returns the number of users in the database for the current user.reset_dialog (user_id: str)/v1/user/dialog/json/{user_id}: Dynamic resource to return dialogs as JSON./v1/user/dialog/str/{user_id}: Dynamic resource to return dialogs as a stringchat (message: str, user_id: str): Sends a chat message and gets a response generated by OpenRouter.The dispatcher in mcp_waifu_chat/ai.py selects the provider and generates responses.
Provider: openrouter
Model resolution precedence:
- OpenRouter model name: OPENROUTER_MODEL_NAME env; else ~/.model-openrouter; else openrouter/free.
Credentials:
- OpenRouter: OPENROUTER_API_KEY env; else ~/.api-openrouter.
Call pattern: - OpenRouter: HTTPS POST to https://openrouter.ai/api/v1/chat/completions with a single user message.
The path includes defensive parsing and error handling, returning config.default_response when unavailable.
For a production deployment, you should:
Use a production-ready WSGI/ASGI server: Gunicorn is recommended and included in the pyproject.toml. Example command:
bash
gunicorn --workers 4 --bind 0.0.0.0:8000 mcp_waifu_chat.api:app -k uvicorn.workers.UvicornWorker
This runs the app object (our FastMCP instance) from mcp_waifu_chat/api.py using 4 Uvicorn workers managed by Gunicorn, listening on port 8000. Adjust the number of workers and the port as needed.
Use a robust database: Consider PostgreSQL or MySQL instead of SQLite for higher concurrency and scalability.
Implement proper logging: Configure logging to write to files, a centralized logging service, or a monitoring system.
Secure your server: Use HTTPS, implement authentication/authorization, and follow security best practices for web applications.
Consider a reverse proxy: Use a reverse proxy like Nginx or Apache to handle TLS termination, load balancing, and static file serving.
Containerize Use Docker to simplify deployment.
mcp_waifu_chat/ (Main Package):__init__.py: Makes the directory a Python package.api.py: The core FastMCP application, tool/resource definitions, and request handling logic.config.py: Handles loading and validating configuration settings.db.py: All database interaction logic (creating tables, querying, updating).models.py: Pydantic models for request/response data validation and serialization.utils.py: Helper functions, like dialog_to_json and json_to_dialog.ai.py: This module is responsible for interacting with the OpenRouter API.tests/ (Test Suite):conftest.py: pytest configuration, including fixtures for the test database and test client.test_db.py: Unit tests for the db.py module.test_api.py: Unit tests for the API endpoints in api.py.run.py:: Simple file to run the server (Note: uv run mcp-waifu-chat is preferred).This structure promotes modularity, testability, and maintainability. Each module has a specific responsibility, making it easier to understand, modify, and extend the codebase.
GitHub repository