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
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Every module has detailed CLAUDE.md documentation. For module-specific guidance,
* [src/aignostics/wsi/CLAUDE.md](src/aignostics/wsi/CLAUDE.md) - Whole slide image processing
* [src/aignostics/dataset/CLAUDE.md](src/aignostics/dataset/CLAUDE.md) - Dataset operations
* [src/aignostics/bucket/CLAUDE.md](src/aignostics/bucket/CLAUDE.md) - Cloud storage management
* [src/aignostics/utils/CLAUDE.md](src/aignostics/utils/CLAUDE.md) - Core infrastructure
* [src/aignostics/utils/CLAUDE.md](src/aignostics/utils/CLAUDE.md) - Core infrastructure and MCP server
* [src/aignostics/gui/CLAUDE.md](src/aignostics/gui/CLAUDE.md) - Desktop interface
* [src/aignostics/notebook/CLAUDE.md](src/aignostics/notebook/CLAUDE.md) - Marimo notebook integration
* [src/aignostics/qupath/CLAUDE.md](src/aignostics/qupath/CLAUDE.md) - QuPath bioimage analysis
Expand Down Expand Up @@ -269,7 +269,7 @@ comprehensive view of the entire SDK's operational status.
| **wsi** | ✅ | ✅ | ✅ | Medical image processing |
| **dataset** | ✅ | ✅ | ✅ | Dataset downloads |
| **bucket** | ✅ | ✅ | ✅ | Cloud storage |
| **utils** | ✅ | | ❌ | Infrastructure |
| **utils** | ✅ | | ❌ | Core Infrastructure |
| **gui** | ✅ | ❌ | ✅ | Desktop launchpad |
| **notebook** | ✅ | ❌ | ✅ | Marimo notebooks |
| **qupath** | ✅ | ✅ | ✅ | QuPath integration |
Expand Down
71 changes: 70 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,15 @@ Choose your preferred interface for working with the Aignostics Platform. Each i
| **Use when** | Building custom analysis pipeline in Python for repeated usage and processing large datasets (10s-1000s of slides) |
| **Get started** | <a href="#example-notebooks-interact-with-the-aignostics-platform-from-your-python-notebook-environment">Run example notebooks</a> or <a href="#python-library-call-the-aignostics-platform-api-from-your-python-scripts">call the Aignostics Platform API from your Python scripts</a> |

### 🤖 MCP Server (AI Agent Integration)

| | |
|---|---|
| **What it is** | Model Context Protocol server that exposes SDK functionality to AI agents like Claude |
| **Best for** | Users who want AI assistants to help with platform operations |
| **Use when** | Working with Claude Desktop or other MCP-compatible AI tools to manage datasets, submit runs, or query results |
| **Get started** | <a href="#mcp-server-integrate-with-ai-agents">Configure Claude Desktop for MCP integration</a> |

> 💡 Launchpad and CLI handle authentication automatically. Python Library requires manual setup (see [authentication section](#example-notebooks-interact-with-the-aignostics-platform-from-your-python-notebook-environment)).

## Launchpad: Run your first computational pathology analysis in 10 minutes from your desktop
Expand Down Expand Up @@ -608,6 +617,63 @@ Self-signed URLs for files in google storage buckets can be generated using the
[required credentials](https://cloud.google.com/docs/authentication/application-default-credentials)
for the Google Storage Bucket**

## MCP Server: Integrate with AI Agents

The Python SDK includes an MCP (Model Context Protocol) server that exposes SDK functionality to AI agents like Claude. This enables AI assistants to help you interact with the Aignostics Platform through natural conversation.

### Quick Start with Claude Desktop

Add the following to your Claude Desktop configuration file:

**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
"mcpServers": {
"aignostics": {
"command": "uvx",
"args": ["aignostics", "mcp-run"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't get this to work with Claude Code + uv run ... but I think in any case this needs to be mcp run now?

Suggested change
"args": ["aignostics", "mcp-run"]
"args": ["aignostics", "mcp run"]

}
}
}
```

Restart Claude Desktop after adding this configuration.

### CLI Commands

```bash
# Using uvx (no installation required)
uvx aignostics mcp run
uvx aignostics mcp list-tools

# If aignostics is installed (uv pip install aignostics)
aignostics mcp run
aignostics mcp list-tools
```

### Using Plugins

The MCP server supports plugins that extend its functionality with additional tools. To run the MCP server with a plugin installed:

```bash
# With a local plugin
uv run --with /path/to/plugin mcp-run

# With a plugin from a git repository
uvx --with git+ssh://git@github.com/org/plugin mcp-run

# Or using the full CLI
uv run --with /path/to/plugin aignostics mcp run
```

Plugins register themselves via Python entry points and their tools are automatically discovered and namespaced by the MCP server.

### What AI Agents Can Do

Once configured, AI agents can help you with platform operations through natural language, with access to tools from the SDK and any installed plugins.

## Next Steps

Now that you have an overview of the Aignostics Python SDK and its interfaces, here are some recommended next steps to deepen your understanding and get the most out of the platform:
Expand Down Expand Up @@ -866,9 +932,12 @@ Laboratory systems that can be integrated with the Aignostics Platform for workf

### M

**Marimo**
**Marimo**
Modern notebook environment supported by the Aignostics Platform as an alternative to Jupyter.

**MCP (Model Context Protocol)**
Protocol that enables AI agents like Claude to interact with external tools and services. The Aignostics SDK includes an MCP server that exposes platform functionality to AI assistants.

**Metadata**
Descriptive information about whole slide images including dimensions, resolution, tissue type, and disease information required for processing.

Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,13 @@ dependencies = [
"lxml>=6.0.2", # For python 3.14 pre-built wheels
"filelock>=3.20.1", # CVE-2025-68146
"marshmallow>=3.26.2", # CVE-2025-68480
"fastmcp>=2.0.0,<3", # MCP server - Major version 3 is in beta as of 26/01/2026 and has not been released on PyPI. Upgraded once a stable release is out.
]

[project.optional-dependencies]
pyinstaller = ["pyinstaller>=6.14.0,<7"]
jupyter = [
"jupyter>=1.1.1,<2",
"jupyter>=1.1.1,<2",
# Transitive overrides
# WARNING: one cannot negate or downgrade a dependency required here. use override-dependencies for that.
"jupyter-core>=5.8.1", # CVE-2025-30167
Expand Down
9 changes: 5 additions & 4 deletions src/aignostics/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This file provides a comprehensive overview of all modules in the Aignostics SDK
| **wsi** | Whole slide image processing | ✅ | ✅ | ✅ |
| **dataset** | IDC dataset downloads | ✅ | ✅ | ✅ |
| **bucket** | Cloud storage operations | ✅ | ✅ | ✅ |
| **utils** | Core utilities & DI | | ❌ | ✅ |
| **utils** | Core utilities, DI & MCP | | ❌ | ✅ |
| **gui** | Desktop launchpad | ❌ | ✅ | ✅ |
| **notebook** | Marimo notebook server | ❌ | ✅ | ✅ |
| **qupath** | QuPath integration | ✅ | ✅ | ✅ |
Expand Down Expand Up @@ -76,14 +76,15 @@ This file provides a comprehensive overview of all modules in the Aignostics SDK

### 🛠️ utils

**Core infrastructure and shared utilities**
**Core infrastructure, shared utilities, and MCP server**

- **Core Features**:
- Dependency injection, logging, settings, health checks
- **Enhanced User Agent** (NEW): Context-aware user agent with CI/CD tracking
- **MCP Server** (integrated): FastMCP-based server for AI agent integration
- **Service Discovery**: `locate_implementations()`, `locate_subclasses()`
- **User Agent**: Generates `{name}/{version} ({platform}; {test}; {github_run_url})`
- **No CLI/GUI**: Infrastructure module
- **MCP CLI**: `mcp-run` (start server)
- **Used By**: All modules; platform module for SDK metadata

### 🖥️ gui
Expand Down Expand Up @@ -271,7 +272,7 @@ For detailed information about each module, see:
- [wsi/CLAUDE.md](wsi/CLAUDE.md) - Image processing
- [dataset/CLAUDE.md](dataset/CLAUDE.md) - Dataset operations
- [bucket/CLAUDE.md](bucket/CLAUDE.md) - Storage management
- [utils/CLAUDE.md](utils/CLAUDE.md) - Infrastructure details
- [utils/CLAUDE.md](utils/CLAUDE.md) - Infrastructure details and MCP server
- [gui/CLAUDE.md](gui/CLAUDE.md) - Desktop interface
- [notebook/CLAUDE.md](notebook/CLAUDE.md) - Marimo notebook integration
- [qupath/CLAUDE.md](qupath/CLAUDE.md) - QuPath integration
Expand Down
63 changes: 59 additions & 4 deletions src/aignostics/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import typer
from loguru import logger

from .constants import NOTEBOOK_DEFAULT, WINDOW_TITLE
from .utils import (
from aignostics.constants import NOTEBOOK_DEFAULT, WINDOW_TITLE
from aignostics.utils import (
__is_running_in_container__,
__python_version__,
__version__,
Expand All @@ -25,15 +25,15 @@
@cli.command()
def launchpad() -> None:
"""Open Aignostics Launchpad, the graphical user interface of the Aignostics Platform."""
from .utils import gui_run # noqa: PLC0415
from aignostics.utils import gui_run # noqa: PLC0415

gui_run(native=True, with_api=False, title=WINDOW_TITLE, icon="🔬")


if find_spec("marimo"):
from typing import Annotated

from .utils import create_marimo_app
from aignostics.utils import create_marimo_app

@cli.command()
def notebook(
Expand Down Expand Up @@ -64,6 +64,61 @@ def notebook(
uvicorn.run(create_marimo_app(notebook=notebook, override_if_exists=override_if_exists), host=host, port=port)


# MCP (Model Context Protocol) server CLI
mcp_cli = typer.Typer(name="mcp", help="MCP (Model Context Protocol) server for AI agent integration.")


@mcp_cli.command("run")
def mcp_run() -> None:
"""Run the MCP server.

Starts an MCP server using stdio transport that exposes SDK functionality
to AI agents. The server automatically discovers and mounts tools from
the SDK and any installed plugins.

Examples:
aignostics mcp run
"""
from aignostics.utils import mcp_run # noqa: PLC0415

mcp_run()


@mcp_cli.command("list-tools")
def mcp_list_tools() -> None:
"""List all available MCP tools.

Shows all tools available in the MCP server, including tools from
the SDK and any installed plugins. Each tool is displayed with its
name and description.

Examples:
aignostics mcp list-tools
"""
import operator # noqa: PLC0415

from rich.table import Table # noqa: PLC0415

from aignostics.utils import mcp_list_tools # noqa: PLC0415

tools = mcp_list_tools()

if not tools:
console.print("[dim]No tools discovered[/dim]")
return

table = Table(title="Available MCP Tools")
table.add_column("Name", style="cyan", no_wrap=True)
table.add_column("Description", style="white")

for tool in sorted(tools, key=operator.itemgetter("name")):
table.add_row(tool["name"], tool["description"])

console.print(table)


cli.add_typer(mcp_cli)

prepare_cli(
cli, f"🔬 Aignostics Python SDK v{__version__} - built with love in Berlin 🐻 // Python v{__python_version__}"
)
Expand Down
95 changes: 95 additions & 0 deletions src/aignostics/utils/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ The utils module provides core infrastructure and shared utilities used across a
- `_sentry.py` - Sentry error monitoring
- `_notebook.py` - Jupyter notebook utilities
- `_gui.py` - GUI utilities and NiceGUI helpers
- `_mcp.py` - MCP server utilities for AI agent integration

## Usage Patterns

Expand Down Expand Up @@ -115,6 +116,38 @@ class MyService(BaseService):
)
```

**MCP Server Utilities:**

```python
from aignostics.utils import (
MCP_SERVER_NAME,
MCP_TRANSPORT,
create_server,
run,
list_tools,
discover_mcp_servers,
)

# Constants
print(MCP_SERVER_NAME) # "Central Aignostics MCP Server"
print(MCP_TRANSPORT) # "stdio"

# Create and configure MCP server
server = create_server()
server = create_server(server_name="Custom Server")

# Run MCP server (blocking)
run()

# List available tools
tools = list_tools()
for tool in tools:
print(f"{tool['name']}: {tool['description']}")

# Discover all MCP servers from SDK and plugins
servers = discover_mcp_servers()
```

## Technical Implementation

**User Agent System (`_user_agent.py`):**
Expand Down Expand Up @@ -225,6 +258,7 @@ def user_agent() -> str:
- `_sentry.py` - Error monitoring
- `_notebook.py` - Jupyter integration
- `_gui.py` - GUI framework utilities
- `_mcp.py` - MCP server utilities

## Development Notes

Expand Down Expand Up @@ -272,3 +306,64 @@ def user_agent() -> str:
- Process creation flags
- File system permissions
- Environment variable handling

## MCP Server System (`_mcp.py`)

The MCP module provides utilities for creating and running Model Context Protocol servers that expose SDK functionality to AI agents.

**Functions:**

- `discover_mcp_servers()` - Discover all FastMCP server instances from SDK and plugins
- `create_server(server_name)` - Create and configure the MCP server with discovered plugins
- `run(server_name)` - Run the MCP server using stdio transport
- `list_tools(server_name)` - List all available MCP tools

**CLI Commands:**

```bash
aignostics mcp-run # Run MCP server
aignostics mcp-list-tools # List all discovered tools
```

**Claude Desktop Integration:**

```json
{
"mcpServers": {
"aignostics": {
"command": "uvx",
"args": ["--with", "aignostics", "aignostics", "mcp-run"]
}
}
}
```

## MCP Plugin Development

Plugins can expose MCP tools by:

1. Registering via entry points in `pyproject.toml`:
```toml
[project.entry-points."aignostics.plugins"]
my_plugin = "my_plugin"
```

2. Creating a FastMCP instance in `_mcp.py`:
```python
from fastmcp import FastMCP

mcp = FastMCP("my_plugin")

@mcp.tool
def my_tool(param: str) -> str:
"""Tool description."""
return f"Result: {param}"
```

3. Exporting the instance in `__init__.py`:
```python
from ._mcp import mcp
__all__ = ["mcp"]
```

Tools are namespaced automatically (e.g., `my_plugin_my_tool`).
Loading
Loading