Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ COPY --from=builder --chown=app:app /home/app/.local/share/cartopy ${CARTOPY_DAT
RUN mkdir -p /tmp/matplotlib && chown app:app /tmp/matplotlib
ENV MPLCONFIGDIR=/tmp/matplotlib

# Set the host for the MCP server
ENV MCP_HOST="0.0.0.0"

# Switch to non-root user
USER app

Expand Down
98 changes: 69 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Plotting MCP Server
# 📊 Plotting MCP Server

An MCP (Model Context Protocol) server that generates plots from CSV data, optimized for LibreChat integration.
A MCP (Model Context Protocol) server that transforms CSV data into beautiful visualizations. Built with Python and optimized for seamless integration with AI assistants and chat applications.

## Features
## Features

- Generate plots from CSV data strings
- Support for multiple plot types: line, bar, pie
- Returns base64-encoded PNG images compatible with LibreChat
- **📈 Multiple Plot Types**: Create line charts, bar graphs, pie charts, and world maps
- **🌍 Geographic Visualization**: Built-in support for plotting coordinate data on world maps using Cartopy
- **🔧 Flexible Parameters**: Fine-tune your plots with JSON-based configuration options
- **📱 Chat-Ready Output**: Returns base64-encoded PNG images perfect for AI chat interfaces
- **⚡ Fast Processing**: Efficient CSV parsing and plot generation with pandas and matplotlib

## Installation

Expand Down Expand Up @@ -35,26 +37,57 @@ The server runs on port 9090 by default.
### Tools

#### `generate_plot`
Generate a plot from CSV data.
Transform your CSV data into stunning visualizations.

**Parameters:**
- `csv_data` (str): CSV data as a string
- `plot_type` (str): Type of plot (line, bar, pie)
- `**kwargs`: Additional plotting parameters.

**Returns:** Base64 PNG image with data URL prefix

## LibreChat Integration
- `plot_type` (str): Plot type - `line`, `bar`, `pie`, or `worldmap`
- `json_kwargs` (str): JSON string with plotting parameters for customization

**Plotting Options:**
- **Line/Bar Charts**: Use Seaborn parameters (`x`, `y`, `hue` for data mapping)
- **World Maps**: Automatic coordinate detection (`lat`/`latitude`/`y` and `lon`/`longitude`/`x`)
- Customize with `s` (size), `c` (color), `alpha` (transparency), `marker` (style)
- **Pie Charts**: Supports single column (value counts) or two columns (labels + values)

**Returns:** Base64-encoded PNG image ready for display

## 🤖 AI Assistant Integration

Perfect for enhancing AI conversations with data visualization capabilities. The server returns plots as base64-encoded PNG images that display seamlessly in:

- **LibreChat**: Direct integration for chat-based data analysis
- **Claude Desktop**: Through `mcp-remote` command to transform from HTTP transport to stdio
```json
{
"mcpServers": {
"math": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:9090/mcp"
]
}
}
}
```
- **Custom AI Applications**: Easy integration via MCP protocol
- **Development Tools**: Compatible with any MCP-enabled environment

This MCP server is designed to work with LibreChat. The generated images are returned as base64 PNG data that LibreChat can display directly.
**Image Format**: High-quality PNG with configurable DPI and sizing

Supported image format: PNG
## 🚀 ToolHive Deployment

## ToolHive
Deploy and manage your plotting server effortlessly with ToolHive - a platform that provides containerized, secure environments for MCP servers across UI, CLI, and Kubernetes modes.

ToolHive is a platform that simplifies the deployment and management of Model Context Protocol (MCP) servers by providing containerized, secure environments across UI, CLI, and Kubernetes modes. It offers streamlined deployment with comprehensive security controls and integration with popular development tools.
**Benefits:**
- 🔒 **Secure Containerization**: Isolated environments with comprehensive security controls
- ⚙️ **Multiple Deployment Options**: UI, CLI, and Kubernetes support
- 🔧 **Developer-Friendly**: Seamless integration with popular development tools

For more information, see the [ToolHive documentation](https://docs.stacklok.com/toolhive/). To get started with the CLI, check out the [ToolHive CLI Quickstart](https://docs.stacklok.com/toolhive/tutorials/quickstart-cli).
📚 **Resources:**
- [ToolHive Documentation](https://docs.stacklok.com/toolhive/)
- [CLI Quickstart Guide](https://docs.stacklok.com/toolhive/tutorials/quickstart-cli)

### Build the Docker image

Expand All @@ -77,7 +110,7 @@ thv run --name plotting-mcp --transport streamable-http plotting-mcp:latest
kubectl apply -f toolhive-pvc.yaml
```

2. Deploy the MCP server in K8s
2. Deploy the MCP server in K8s. In the `toolhive-deployment.yaml`, you can customize the `image` field to point to your image registry.
```bash
kubectl apply -f toolhive-deployment.yaml
```
Expand All @@ -87,21 +120,28 @@ kubectl apply -f toolhive-deployment.yaml
kubectl port-forward svc/mcp-plotting-mcp-proxy 9090:9090
```

## Development
## 🛠️ Development

### Code Formatting
Built with modern Python tooling for a great developer experience.

```bash
make format
# or
uv run ruff format .
uv run ruff check --fix .
```
**Tech Stack:**
- 🐍 **Python 3.13+**: Latest Python features
- 📊 **Seaborn & Matplotlib**: Professional-grade plotting
- 🌍 **Cartopy**: Advanced geospatial visualization
- ⚡ **FastMCP**: High-performance MCP server framework
- 🔧 **UV**: Fast Python package management

### Typechecking
### Code Quality

```bash
# Format code and fix linting issues
make format

# Type checking
make typecheck
# or

# Or use uv directly
uv run ruff format .
uv run ruff check --fix .
uv run ty check
```
1 change: 0 additions & 1 deletion src/plotting_mcp/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@

# Constants for server configuration
MCP_PORT = os.getenv("MCP_PORT", 9090)
MCP_HOST = os.getenv("MCP_HOST", "127.0.0.1")
4 changes: 2 additions & 2 deletions src/plotting_mcp/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
from starlette.responses import JSONResponse, Response

from plotting_mcp.configure_logging import configure_logging
from plotting_mcp.constants import MCP_HOST, MCP_PORT
from plotting_mcp.constants import MCP_PORT
from plotting_mcp.plot import plot_to_bytes
from plotting_mcp.utils import sizeof_fmt

logger = structlog.get_logger(__name__)

mcp = FastMCP(name="plotting-mcp", host=MCP_HOST, port=MCP_PORT)
mcp = FastMCP(name="plotting-mcp", host="0.0.0.0", port=MCP_PORT)


@mcp.tool()
Expand Down