Skip to content
Open
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
21 changes: 6 additions & 15 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ uvx rdl-mcp

The codebase follows a modular design with the main MCP server delegating to specialized modules:

- **`rdl_mcp_server.py`** - Entry point with logging setup, imports `MCPServer` from package
- **`rdl_mcp/server.py`** - Core `MCPServer` class handling JSON-RPC protocol, tool registration, and request routing
- **`rdl_mcp_server.py`** - Entry point; calls `mcp.run()` to start the fastmcp server
- **`rdl_mcp/server.py`** - fastmcp `mcp` instance with `@mcp.tool` decorators for all tools; also exports `MCPServer` (a thin wrapper used by tests)
- **`rdl_mcp/reader.py`** - Read-only operations: `describe_rdl_report`, `get_rdl_datasets`, `get_rdl_parameters`, `get_rdl_columns`
- **`rdl_mcp/columns.py`** - Column modifications: add/remove/update header/width/format
- **`rdl_mcp/datasets.py`** - Dataset operations: add/remove fields, update stored procedures
Expand All @@ -43,28 +43,19 @@ The codebase follows a modular design with the main MCP server delegating to spe

## Key Constraints

- **Python standard library only** - No external dependencies beyond pytest for testing
- **Python 3.8+ compatibility** required
- **fastmcp** - MCP transport is provided by the `fastmcp` library (declared in `pyproject.toml`)
- **Python 3.10+ compatibility** required
- **Tablix controls only** - Currently supports table-based reports, not Matrix or Chart controls
- **RDL 2016 namespace** - Uses `http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition`

## MCP Protocol

The server uses JSON-RPC 2.0 over stdin/stdout. Key methods:
- `initialize` - Returns server capabilities
- `tools/list` - Returns available tools with JSON schemas
- `tools/call` - Executes a tool with arguments
The server uses fastmcp for the MCP transport (stdio by default). Tool registration is done via `@mcp.tool` decorators in `rdl_mcp/server.py`. fastmcp automatically handles protocol negotiation, tool listing, and tool dispatch.

## Testing

Tests use pytest with fixtures that create temporary RDL files. The `_create_sample_report()` function in tests generates valid minimal RDL documents for testing.
Tests use pytest with fixtures that create temporary RDL files. The `_create_sample_report()` function in tests generates valid minimal RDL documents for testing. `TestFastMCPServer` verifies that all tools are correctly registered with the fastmcp instance.

**Requirements:**
- Write tests before implementing any changes
- All tests must pass after making changes (`python3 -m pytest tests/ -v`)

## Logging

Configure via environment variables:
- `RDL_MCP_LOG_LEVEL`: DEBUG, INFO, WARNING, ERROR
- `RDL_MCP_LOG_FILE`: Path to log file
19 changes: 6 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mcp-name: io.github.bethmaloney/rdl-mcp

[![PyPI](https://img.shields.io/pypi/v/rdl-mcp.svg)](https://pypi.org/project/rdl-mcp/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![MCP](https://img.shields.io/badge/MCP-Compatible-green.svg)](https://modelcontextprotocol.io)

Edit SSRS reports using AI assistants instead of wrestling with 2000+ lines of XML. This [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server gives Claude, Copilot, and other AI tools simple commands to read and modify RDL files.
Expand All @@ -21,6 +21,7 @@ Edit SSRS reports using AI assistants instead of wrestling with 2000+ lines of X
- `update_column_header` / `update_column_width` - Change columns
- `add_column` / `remove_column` - Add or remove columns
- `update_column_format` - Change number/date formatting
- `update_column_colors` - Change the colors for the column header and the data rows
- `update_stored_procedure` - Swap stored procedures
- `add_dataset_field` / `remove_dataset_field` - Manage dataset fields
- `add_parameter` / `update_parameter` - Manage parameters
Expand All @@ -30,12 +31,12 @@ Edit SSRS reports using AI assistants instead of wrestling with 2000+ lines of X
- AI sees clean JSON instead of verbose XML namespaces
- One-line commands instead of error-prone string manipulation
- Automatic validation catches errors before they break reports
- No dependencies - just Python 3.8+ standard library
- Built on [fastmcp](https://github.com/jlowin/fastmcp) for a robust, standards-compliant MCP transport

## Installation

**Requirements:**
- Python 3.8 or higher
- Python 3.10 or higher
- [uv](https://docs.astral.sh/uv/) (Python package manager and tool runner)

**Installing uv:**
Expand Down Expand Up @@ -90,14 +91,6 @@ Add to VSCode settings (`.vscode/mcp.json` in your workspace or user settings):

**After installation:** Restart your AI assistant and try: `"Describe the structure of my report.rdl file"`

<details>
<summary>Optional: Enable debug logging</summary>

Set environment variables:
- `RDL_MCP_LOG_LEVEL`: `DEBUG`, `INFO`, `WARNING`, or `ERROR`
- `RDL_MCP_LOG_FILE`: Path to log file
</details>

## Usage

Just ask your AI assistant in natural language:
Expand Down Expand Up @@ -181,7 +174,7 @@ All tools return `{success: bool, message?: string, error?: string}` or structur

**Server not appearing?**
- Check absolute path in config is correct
- Verify Python 3.8+: `python3 --version`
- Verify Python 3.10+: `python3 --version`
- Restart your MCP client

**Permission errors?**
Expand Down Expand Up @@ -237,7 +230,7 @@ PRs welcome! Priority areas:
- Better column detection for complex layouts
- More editing operations (reordering, grouping, etc.)

Requirements: Python standard library only
Requirements: Python 3.10+, fastmcp

1. Fork repo
2. Create feature branch
Expand Down
15 changes: 9 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ name = "rdl-mcp"
version = "0.1.0"
description = "Edit SSRS reports using AI - MCP server for RDL files"
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
{name = "Beth Maloney"}
requires-python = ">=3.10"
license = { text = "MIT" }
dependencies = [
"defusedxml>=0.7.1",
"fastmcp>=3.2",
]
authors = [{ name = "Beth Maloney" }]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand All @@ -29,5 +29,8 @@ Homepage = "https://github.com/bethmaloney/rdl-mcp"
Repository = "https://github.com/bethmaloney/rdl-mcp"
Issues = "https://github.com/bethmaloney/rdl-mcp/issues"

[tool.setuptools.packages.find]
where = ["."]

[project.scripts]
rdl-mcp = "rdl_mcp_server:main"
3 changes: 2 additions & 1 deletion rdl_mcp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""RDL MCP Server - Model Context Protocol server for RDL file operations."""

from .server import MCPServer, run_server
from .server import MCPServer, mcp, run_server
from .validation import validate_rdl, extract_field_references, extract_field_references_with_context
from .reader import describe_rdl_report, get_rdl_datasets, get_rdl_parameters, get_rdl_columns
from .columns import add_column, remove_column, update_column_format, update_column_header, update_column_width
Expand All @@ -11,6 +11,7 @@

__all__ = [
'MCPServer',
'mcp',
'run_server',
'validate_rdl',
'extract_field_references',
Expand Down
Loading