Jaraco Website MCP Server
This directory contains the MCP (Model Context Protocol) server implementation for the Jaraco website. The server provides programmatic access to website content including blog posts, services, and categories, with read-only access and email drafting capabilities.
Features
- Read Blog Posts: Access all blog posts in multiple languages (EN, DE, FR, ES, NL)
- Read Services: Access all service descriptions and details
- Browse Categories: Explore content organized by categories
- Draft Emails: Generate service-specific email templates with appropriate default text
- Read-Only Access: All content access is read-only
- Multi-Language Support: All content available in 5 languages
Quick Start
Prerequisites
- Python 3.10 or higher (required for MCP SDK v2)
- pip package manager
Installation
- Install dependencies:
pip install -r requirements.txt
- Run the server:
python -m mcp_server.server
The server will start on localhost:8081 by default with the /mcp endpoint.
Test the Server
You can test the server using curl or any MCP client:
# List all resources
curl http://localhost:8081/mcp -X POST -H "Content-Type: application/json" -d '{"method": "list_resources"}'
# Read a specific blog post
curl http://localhost:8081/mcp -X POST -H "Content-Type: application/json" -d '{"method": "read_resource", "params": {"uri": "blog_posts/from-data-chaos-to-efficient-automation"}}'
# Or use the MCP CLI (if installed)
mcp dev mcp_server.server
Configuration
The server can be configured using environment variables. In MCP SDK v2, transport settings are passed to the run() method, but can still be configured via environment variables for convenience.
| Variable | Default | Description |
|---|---|---|
MCP_HOST |
0.0.0.0 |
Host to bind to (used by run()) |
MCP_PORT |
8081 |
Port to listen on (used by run()) |
CONTENT_ROOT |
Project root | Root directory for website content |
CACHE_ENABLED |
true |
Enable content caching |
CACHE_TTL |
300 |
Cache time-to-live in seconds |
LOG_LEVEL |
INFO |
Logging level (DEBUG, INFO, WARNING, ERROR) |
Example:
# Configure via environment variables
MCP_PORT=9090 CONTENT_ROOT=/path/to/content LOG_LEVEL=DEBUG python -m mcp_server.server
# Or use default configuration
python -m mcp_server.server
Transport Configuration
The server uses Streamable HTTP transport by default, which is the recommended transport for MCP v2. The endpoint will be available at:
http://localhost:8081/mcp
For production deployments behind a proxy, you may need to configure transport security settings.
Docker
Build the Image
docker build -t jaraco-mcp-server -f mcp_server/Dockerfile .
Run the Container
docker run -p 8081:8081 -v $(pwd):/app jaraco-mcp-server
Docker Compose
Add to your docker-compose.yml:
version: '3.8'
services:
mcp-server:
build:
context: .
dockerfile: mcp_server/Dockerfile
ports:
- "8081:8081"
volumes:
- .:/app
environment:
- MCP_PORT=8081
- CONTENT_ROOT=/app
- LOG_LEVEL=INFO
restart: unless-stopped
Usage Examples
Python Client
from mcp.client import Client
async def main():
client = Client("jaraco-website", url="http://localhost:8081")
await client.connect()
# List all resources
resources = await client.list_resources()
print(f"Found {len(resources)} resources")
# Read a blog post
post = await client.read_resource("blog_posts/from-data-chaos-to-efficient-automation")
print(post)
# Draft an email
email = await client.call_tool(
"draft_email",
{
"service_slug": "software-development",
"language": "en",
"sender_name": "John Doe",
"sender_email": "john@example.com",
"custom_text": "I need help with a custom web application."
}
)
print(email)
await client.disconnect()
# Run with asyncio
import asyncio
asyncio.run(main())
JavaScript/Node.js Client
const { Client } = require('@modelcontextprotocol/sdk');
async function main() {
const client = new Client('jaraco-website', { url: 'http://localhost:8081' });
await client.connect();
// List resources
const resources = await client.listResources();
console.log(`Found ${resources.length} resources`);
// Read a resource
const post = await client.readResource('blog_posts/from-data-chaos-to-efficient-automation');
console.log(post);
// Draft an email
const email = await client.callTool('draft_email', {
service_slug: 'software-development',
language: 'en',
sender_name: 'John Doe',
sender_email: 'john@example.com',
custom_text: 'I need help with a custom web application.'
});
console.log(email);
await client.disconnect();
}
main().catch(console.error);
API Reference
The MCP server uses the Streamable HTTP transport with the following endpoint:
- Base URL:
http://localhost:8081/mcp - Transport: Streamable HTTP (MCP v2 recommended)
MCP Protocol
This server implements the MCP (Model Context Protocol) v2 specification. Clients should use an MCP client library for their language.
list_resources
List all available resources or filter by type.
MCP Request:
{
"method": "list_resources",
"params": {
"uri": "blog_posts/"
}
}
MCP Response:
{
"resources": [
{
"uri": "blog_posts/from-data-chaos-to-efficient-automation",
"name": "From Data Chaos to Efficient Automation",
"description": "How to transform...",
"mimeType": "text/markdown"
}
]
}
read_resource
Read a specific resource by URI.
MCP Request:
{
"method": "read_resource",
"params": {
"uri": "blog_posts/from-data-chaos-to-efficient-automation"
}
}
MCP Response:
{
"contents": [
{
"type": "text",
"text": "# From Data Chaos to Efficient Automation\n\n...",
"mimeType": "text/markdown"
}
]
}
call_tool (draft_email)
Draft an email for a service.
MCP Request:
{
"method": "call_tool",
"params": {
"name": "draft_email",
"arguments": {
"service_slug": "software-development",
"language": "en",
"sender_name": "John Doe",
"sender_email": "john@example.com",
"custom_text": "I need help with..."
}
}
}
MCP Response:
{
"content": [
{
"type": "text",
"text": "{\"subject\": \"Inquiry: Software Development Services\", \"body\": \"Dear Jaraco Team...\", ...}",
"mimeType": "application/json"
}
],
"isError": false
}
Using MCP CLI
If you have the MCP CLI installed, you can test the server directly:
# Install MCP CLI
pip install "mcp[cli]>=2.2.0,<3"
# Run the server in dev mode
mcp dev mcp_server.server
# Or run and connect
mcp run mcp_server.server
The MCP CLI will automatically use the correct protocol and transport settings.
Available Services
The following services are available through the MCP server:
| Service Slug | Description |
|---|---|
software-development |
Custom software development services |
consulting |
IT consulting and advisory services |
it-architecture |
IT architecture design and review |
linux-consulting |
Linux system consulting |
code-review |
Code review and quality assessment |
technology-assessment |
Technology stack evaluation |
Available Categories
Content is organized into the following categories:
| Category Slug | Description |
|---|---|
software-engineering |
Software development and engineering |
consulting |
Consulting services |
linux |
Linux and infrastructure services |
automation |
Automation and workflow improvement |
Project Structure
mcp_server/
├── __init__.py # Package initialization
├── server.py # Main MCP server implementation
├── content_loader.py # Content loading and caching
├── email_templates.py # Email template definitions
├── config.py # Server configuration
├── requirements.txt # Python dependencies
├── Dockerfile # Docker configuration
└── README.md # This file
Development
Running Tests
# Install test dependencies
pip install pytest pytest-asyncio
# Run tests
pytest tests/test_mcp_server.py -v
Code Style
This project follows PEP 8 style guidelines. Use black and isort for formatting:
pip install black isort
black mcp_server/
isort mcp_server/
Security
- The MCP server provides read-only access to content
- No authentication is required by default (can be added if needed)
- All inputs are validated before processing
- Rate limiting is configured to prevent abuse
- The server runs as a non-root user in Docker
Troubleshooting
Common Issues
- Content not found: Ensure
CONTENT_ROOTpoints to the correct directory - Connection refused: Check that the server is running and the port is correct
- Rate limiting: Reduce request frequency if you hit rate limits
Debug Mode
Enable debug logging for troubleshooting:
LOG_LEVEL=DEBUG python -m mcp_server.server
License
This MCP server is part of the Jaraco website and is licensed under the same terms as the main project.
Support
For questions or issues:
- Email: info@jaraco.de
- Website: https://jaraco-gmbh.de
- GitHub: https://github.com/jaracogmbh/jaraco-website
Version History
- 1.0.0: Initial release with blog posts, services, categories, and email drafting
Release files for jaraco-website-mcp-server 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jaraco_website_mcp_server-1.0.1.tar.gz | 32.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jaraco_website_mcp_server-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.3 kB
Release files / jaraco_website_mcp_server-1.0.1.tar.gz
| Download URL | jaraco_website_mcp_server-1.0.1.tar.gz |
|---|---|
| Size | 32.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
afbad93ff6bc67f837f429fa3318867c154c9bd2ac6853141f387928cc821f88
|
|
BLAKE2b-256 checksum How to use checksums |
e4a844837d3400780243af2faa0e23385d0edebb65c27bc0d4a27b43d5166fff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / jaraco_website_mcp_server-1.0.1-py3-none-any.whl
| Download URL | jaraco_website_mcp_server-1.0.1-py3-none-any.whl |
|---|---|
| Size | 11.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3c2831a9eea300beff1562b78275bc1104460b37a9ae9e6ccf716ccf98366ca3
|
|
BLAKE2b-256 checksum How to use checksums |
4919ad6b01d8a293a5c08092e0ceb795337382b8f1567d500cb0ee621b4a40fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|