Metadata-Version: 2.4
Name: odsbox-jaquel-mcp
Version: 1.5.0
Summary: ASAM ODS MCP Server - Query and analyze measurement data from ASAM ODS servers in AI agent systems.
Author-email: Andreas K <totonga@gmail.com>
License: Apache-2.0
Project-URL: Homepage, https://github.com/totonga/odsbox-jaquel-mcp/tree/main#readme
Project-URL: Documentation, https://github.com/totonga/odsbox-jaquel-mcp/tree/main#readme
Project-URL: Repository, https://github.com/totonga/odsbox-jaquel-mcp
Project-URL: Tracker, https://github.com/totonga/odsbox-jaquel-mcp/issues
Project-URL: Changelog, https://github.com/totonga/odsbox-jaquel-mcp/blob/main/CHANGELOG.md
Keywords: mcp,jaquel,odsbox,asam,ods,measurement,data access,data science,data analysis
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
Classifier: Topic :: System :: Monitoring
Classifier: Topic :: Database :: Front-Ends
Requires-Python: >=3.13
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastmcp>=3.0.0
Requires-Dist: odsbox>=1.0.15
Requires-Dist: pip-system-certs
Requires-Dist: matplotlib
Requires-Dist: Jinja2>=3.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-asyncio>=1.2.0; extra == "dev"
Requires-Dist: black>=23.0; extra == "dev"
Requires-Dist: isort>=5.0; extra == "dev"
Requires-Dist: flake8>=6.0; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: build>=0.8.0; extra == "dev"
Requires-Dist: pandas-stubs>=2.3; extra == "dev"
Requires-Dist: python-semantic-release>=10.5.3; extra == "dev"
Requires-Dist: pre-commit>=3.0; extra == "dev"
Provides-Extra: lint
Requires-Dist: commitlint>=1.13.3; extra == "lint"
Provides-Extra: play
Requires-Dist: flask; extra == "play"
Requires-Dist: plotly; extra == "play"
Requires-Dist: seaborn; extra == "play"
Requires-Dist: scipy; extra == "play"
Requires-Dist: jupyter; extra == "play"
Dynamic: license-file


# ASAM ODS Jaquel MCP Server

![PyPI version](https://img.shields.io/pypi/v/odsbox-jaquel-mcp.svg)
![Apache 2.0 License](https://img.shields.io/badge/license-Apache%202.0-green.svg)
![Python](https://img.shields.io/badge/python-3.13%2B-blue.svg)
![Status](https://img.shields.io/badge/status-experimental-orange)
![Build Status](https://img.shields.io/github/actions/workflow/status/totonga/odsbox-jaquel-mcp/build.yml?branch=main)
![Stars](https://img.shields.io/github/stars/totonga/odsbox-jaquel-mcp?style=social)

<!-- mcp-name: io.github.totonga/odsbox-jaquel-mcp -->

**A Model Context Protocol (MCP) server for ASAM ODS with odsbox Jaquel query tools, ODS connection management, and measurement data access.**

---

## Overview

- 🔌 Built-in ODS connection management
- 🧰 MCP tools: schema inspection, query validation, direct ODS query execution and measurement data analysis
- 🏗️ Entity hierarchy visualization (AoTest → AoMeasurement)
- 🚀 Validate, explain and execute JAQueL queries for ASAM ODS
- 📦 Bulk timeseries/submatrix data access and script generation
- 📊 Automatic Jupyter notebook generation for measurement comparison
- 📈 Matplotlib visualization code generation
- 📉 Statistical measurement comparison and correlation analysis
- 🔎 Measurement hierarchy exploration and discovery
- 💡 Interactive starting prompts for guided workflows
- 🤖 AI-guided bulk API learning with `help_bulk_api` tool
- 📝 Comprehensive documentation and test suite

---

## Documentation

- **Prompts Guide:** See [`PROMPTS.md`](https://github.com/totonga/odsbox-jaquel-mcp/blob/main/PROMPTS.md) for starting prompts documentation
- **Tool Reference:** See [`TOOLS_GUIDE.md`](https://github.com/totonga/odsbox-jaquel-mcp/blob/main/TOOLS_GUIDE.md)
- **Changelog:** See [`CHANGELOG.md`](https://github.com/totonga/odsbox-jaquel-mcp/blob/main/CHANGELOG.md)

## Quick Start

### Installation

#### Using uvx (Recommended)

The easiest way to use this MCP server is with `uvx`:

```bash
uvx odsbox-jaquel-mcp@latest
```

This automatically installs and runs the server without managing virtual environments.

#### Using pipx

For a persistent installation:

```bash
pipx install odsbox-jaquel-mcp
odsbox-jaquel-mcp
```

#### Traditional pip Installation

```bash
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
pip install odsbox-jaquel-mcp[play]
```

> **Note:** The `[play]` extra includes optional data analysis and visualization dependencies (pandas, matplotlib, scipy) for working with Jupyter notebooks and data analysis.

### Running the Server

The server runs on stdin/stdout and waits for MCP messages from an MCP client:

```bash
# With uvx (auto-installs and runs)
uvx odsbox-jaquel-mcp@latest

# With pipx (if installed)
odsbox-jaquel-mcp

# With pip in virtual environment
python -m odsbox_jaquel_mcp
```

### Configuration for MCP Clients

Add to your MCP client configuration (e.g., Claude Desktop, VS Code):

```json
{
  "mcpServers": {
    "ods-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["odsbox-jaquel-mcp@latest"]
    }
  }
}
```

Or with pipx:

```json
{
  "mcpServers": {
    "ods-mcp": {
      "type": "stdio",
      "command": "odsbox-jaquel-mcp"
    }
  }
}
```

## Environment Variables

| Variable | Default | Description |
|---|---|---|
| `ODSBOX_STATS_ENABLED` | not set (disabled) | Set to `1`, `true`, or `yes` to enable tool and resource call monitoring. Statistics are persisted to a SQLite database (`odsbox-jaquel-mcp-stats.db`) for cross-session tracking. |
| `FASTMCP_LOG_LEVEL` | `INFO` | Controls the server-side log level (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`). With stdio transport all logs go to stderr, which MCP clients may display as warnings. Set to `WARNING` to reduce noise. |
| `ODSBOX_MCP_URL` | not set | ODS server URL for `ods_connect_using_env` |
| `ODSBOX_MCP_USER` | not set | ODS username for `ods_connect_using_env` |
| `ODSBOX_MCP_PASSWORD` | not set | ODS password for `ods_connect_using_env` |

### Usage Monitoring

When `ODSBOX_STATS_ENABLED=true` is set, the server records tool call and resource read statistics to a local SQLite database:

- **Location**: `~/.local/share/odsbox-jaquel-mcp/odsbox-jaquel-mcp-stats.db` (Linux/macOS) or `%APPDATA%\odsbox-jaquel-mcp\odsbox-jaquel-mcp-stats.db` (Windows), with fallback to the system temp directory.
- **Tracked per tool**: call count, error count, total execution time (ms), last called timestamp.
- **Tracked per resource**: read count, error count, total execution time (ms), last read timestamp.
- **Cross-process safe**: uses SQLite WAL mode, so multiple concurrent MCP sessions can write safely.

You can query the stats database directly:

```bash
sqlite3 ~/.local/share/odsbox-jaquel-mcp/odsbox-jaquel-mcp-stats.db \
  "SELECT name, calls, errors, total_ms FROM tool_stats ORDER BY calls DESC"
```

Example MCP client configuration with monitoring enabled:

```json
{
  "mcpServers": {
    "ods-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["odsbox-jaquel-mcp@latest"],
      "env": {
        "ODSBOX_STATS_ENABLED": "true",
        "FASTMCP_LOG_LEVEL": "WARNING"
      }
    }
  }
}
```

## Development

### Setup

```bash
git clone https://github.com/totonga/odsbox-jaquel-mcp.git
cd odsbox-jaquel-mcp
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
pip install -e ".[dev]"
```

### Common Tasks

```bash
# Run server locally
python -m odsbox_jaquel_mcp

# Run tests
pytest tests/
# or
python run_tests.py

# Code formatting and linting
black .
isort .
flake8 .

# Build package
python -m build

# Test with MCP Inspector
npx @modelcontextprotocol/inspector uvx odsbox-jaquel-mcp@latest
```

## Contributing

Pull requests and issues are welcome! Please:
- Follow PEP8 and use type hints
- Add/maintain tests for new features
- Update documentation as needed

## License

This project is licensed under the Apache License 2.0. See [LICENSE](https://github.com/totonga/odsbox-jaquel-mcp/blob/main/LICENSE).

## Links

- [ASAM ODS](https://www.asam.net/standards/detail/ods/)
- [MCP Protocol](https://github.com/modelcontextprotocol)
- [odsbox](https://pypi.org/project/odsbox/)


## Features

### Core MCP Tools

#### Connection Management
- **ods_connect** - Establish ODS connection
- **ods_connect_using_env** - Establish ODS connection using environment variables
- **ods_disconnect** - Close ODS connection
- **ods_get_connection_info** - Get connection status

#### Schema Inspection
- **schema_get_entity** - Get all fields for entity
- **schema_list_entities** - List all entities with relationships
- **schema_test_to_measurement_hierarchy** - Get ASAM ODS test hierarchy structure

#### Query Building & Validation
- **query_validate** - Check query syntax and structure
- **query_describe** - Get plain English explanation
- **query_execute** - Execute query on ODS server

#### Timeseries/Submatrix Data Access
- **data_get_quantities** - List measurement quantities for submatrix
- **data_read_submatrix** - Read timeseries data from submatrix
- **data_generate_fetcher_script** - Generate Python scripts for data fetching

#### Pattern & Example Library
- **query_generate_skeleton** - Generate query skeleton (basic query) for entity
- **query_get_pattern** - Get template for common patterns
- **query_list_patterns** - List available patterns
- **query_get_operator_docs** - Learn about operators


### Starting Prompts
Discover and use the server's capabilities through **interactive guided prompts**:
- **ODS Server Connection** - Set up and manage connections
- **Validate a Jaquel Query** - Learn query validation
- **Explore Query Patterns** - Find common query templates
- **Bulk Data Access** - Master the 3-step Bulk API workflow
- **Measurement Analysis** - Compare measurements and visualize data

See [`PROMPTS.md`](https://github.com/totonga/odsbox-jaquel-mcp/blob/main/PROMPTS.md) for complete details on all starting prompts.


## Error Handling

### Common Errors and Solutions

#### Not connected
```json
{
  "error": "Model not loaded",
  "hint": "Connect to ODS server using 'ods_connect' tool first"
}
```
Solution: Call ods_connect first

#### Invalid entity
```json
{
  "error": "Entity not found: InvalidEntity",
  "available_entities": ["AoUnit", "AoMeasurement", ...]
}
```
Solution: Use valid entity from available_entities

#### Invalid field
```json
{
  "valid": false,
  "issues": ["Field 'invalid_field' not found"],
  "suggestions": ["id", "name", "description"]
}
```
Solution: Use one of the suggested fields

#### Connection failed
```json
{
  "success": false,
  "error": "Connection refused",
  "error_type": "ConnectionError"
}
```
Solution: Check URL, server availability, firewall

## Troubleshooting

### Issue: Tools not discovered
- Ensure mcp>=0.1.0 is installed
- Check ToolsCapability is set in ServerCapabilities
- Restart MCP client

### Issue: Schema tools fail
- Ensure ODS server is accessible
- Check username/password
- Verify network connectivity
- Review server logs

### Issue: Queries timeout
- Increase request_timeout in connect
- Reduce $rowlimit
- Check ODS server performance

## Performance Tips

1. **Use specific filters** - Avoid querying all records
2. **Limit rows** - Always use `$rowlimit` appropriately
3. **Select attributes** - Only retrieve needed columns/attributes
4. **Index awareness** - Filter on indexed fields first
5. **Connection reuse** - Keep connection open when possible
6. **Cache schemas** - Schema inspection is cached

## Security Notes

- Credentials are only held in memory during connection
- Connection is cleaned up on disconnect
- No credentials stored in config files
- Use HTTPS with `verify_certificate: true` for production

## Install in VSCode

![install in VSCode](https://github.com/totonga/odsbox-jaquel-mcp/blob/main/docs/install_in_vscode.gif){width=300px}

Try with example server configuration:

```json
{
	"servers": {
		"ods": {
			"type": "stdio",
			"command": "uvx",
			"args": [
				"odsbox-jaquel-mcp@latest"
			],
			"env": {
				"ODSBOX_MCP_URL": "https://docker.peak-solution.de:10032/api",
				"ODSBOX_MCP_USER": "Demo",
				"ODSBOX_MCP_PASSWORD": "mdm"
			}
		}
	},
	"inputs": []
}
```

## Support

For issues or questions:
1. Check the error message and hints
2. Review the documentation
