Skip to content

Commit d9fa424

Browse files
committed
task(BE-5757): Create central MCP server with auto-disocovery of plugin tools
1 parent 1a6cc82 commit d9fa424

File tree

14 files changed

+1248
-147
lines changed

14 files changed

+1248
-147
lines changed

CLAUDE.md

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Every module has detailed CLAUDE.md documentation. For module-specific guidance,
4545
* [src/aignostics/wsi/CLAUDE.md](src/aignostics/wsi/CLAUDE.md) - Whole slide image processing
4646
* [src/aignostics/dataset/CLAUDE.md](src/aignostics/dataset/CLAUDE.md) - Dataset operations
4747
* [src/aignostics/bucket/CLAUDE.md](src/aignostics/bucket/CLAUDE.md) - Cloud storage management
48-
* [src/aignostics/utils/CLAUDE.md](src/aignostics/utils/CLAUDE.md) - Core infrastructure
48+
* [src/aignostics/utils/CLAUDE.md](src/aignostics/utils/CLAUDE.md) - Core infrastructure and MCP server
4949
* [src/aignostics/gui/CLAUDE.md](src/aignostics/gui/CLAUDE.md) - Desktop interface
5050
* [src/aignostics/notebook/CLAUDE.md](src/aignostics/notebook/CLAUDE.md) - Marimo notebook integration
5151
* [src/aignostics/qupath/CLAUDE.md](src/aignostics/qupath/CLAUDE.md) - QuPath bioimage analysis
@@ -151,9 +151,12 @@ Module/
151151
**utils** - Infrastructure module providing:
152152

153153
* Dependency injection container (`locate_implementations`, `locate_subclasses`)
154-
* Structured logging (`get_logger`)
154+
* Structured logging (via `loguru.logger`)
155155
* Settings management (Pydantic-based)
156156
* Health check framework (`BaseService`, `Health`)
157+
* MCP server with auto-discovery of plugin tools (`mcp_create_server`, `mcp_run`, `mcp_list_tools`)
158+
* GUI navigation infrastructure (`BaseNavBuilder`, `NavItem`, `NavGroup`)
159+
* Enhanced user agent generation with CI/CD context (`user_agent`)
157160

158161
### API Layer
159162

@@ -269,7 +272,7 @@ comprehensive view of the entire SDK's operational status.
269272
| **wsi** |||| Medical image processing |
270273
| **dataset** |||| Dataset downloads |
271274
| **bucket** |||| Cloud storage |
272-
| **utils** || || Infrastructure |
275+
| **utils** || || Core Infrastructure |
273276
| **gui** |||| Desktop launchpad |
274277
| **notebook** |||| Marimo notebooks |
275278
| **qupath** |||| QuPath integration |
@@ -333,6 +336,10 @@ aignostics qupath launch --project my_project.qpproj
333336

334337
# System diagnostics
335338
aignostics system health
339+
340+
# MCP server (AI agent integration)
341+
aignostics mcp run
342+
aignostics mcp list-tools
336343
```
337344

338345
### GUI Launch

README.md

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,15 @@ Choose your preferred interface for working with the Aignostics Platform. Each i
222222
| **Use when** | Building custom analysis pipeline in Python for repeated usage and processing large datasets (10s-1000s of slides) |
223223
| **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> |
224224

225+
### 🤖 MCP Server (AI Agent Integration)
226+
227+
| | |
228+
|---|---|
229+
| **What it is** | Model Context Protocol server that exposes SDK functionality to AI agents like Claude |
230+
| **Best for** | Users who want AI assistants to help with platform operations |
231+
| **Use when** | Working with Claude Desktop or other MCP-compatible AI tools to manage datasets, submit runs, or query results |
232+
| **Get started** | <a href="#mcp-server-integrate-with-ai-agents">Configure Claude Desktop for MCP integration</a> |
233+
225234
> 💡 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)).
226235
227236
## Launchpad: Run your first computational pathology analysis in 10 minutes from your desktop
@@ -608,6 +617,56 @@ Self-signed URLs for files in google storage buckets can be generated using the
608617
[required credentials](https://cloud.google.com/docs/authentication/application-default-credentials)
609618
for the Google Storage Bucket**
610619

620+
## MCP Server: Integrate with AI Agents
621+
622+
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.
623+
624+
### Quick Start with Claude Desktop
625+
626+
Add the following to your Claude Desktop configuration file:
627+
628+
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
629+
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
630+
631+
```json
632+
{
633+
"mcpServers": {
634+
"aignostics": {
635+
"command": "uvx",
636+
"args": ["aignostics", "mcp", "run"]
637+
}
638+
}
639+
}
640+
```
641+
642+
Restart Claude Desktop after adding this configuration.
643+
644+
### CLI Commands
645+
646+
```bash
647+
# Using uvx (no installation required)
648+
uvx aignostics mcp run
649+
uvx aignostics mcp list-tools
650+
```
651+
652+
### Using Plugins
653+
654+
The MCP server supports plugins that extend its functionality with additional tools. To run the MCP server with a plugin installed:
655+
656+
```bash
657+
# With a local plugin
658+
uv run --with /path/to/plugin aignostics mcp run
659+
660+
# With a plugin from a git repository
661+
uvx --with git+ssh://git@github.com/org/plugin aignostics mcp run
662+
```
663+
664+
Plugins register themselves via Python entry points and their tools are automatically discovered and namespaced by the MCP server.
665+
666+
### What AI Agents Can Do
667+
668+
Once configured, AI agents can help you with platform operations through natural language, with access to tools from the SDK and any installed plugins.
669+
611670
## Next Steps
612671

613672
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:
@@ -866,9 +925,12 @@ Laboratory systems that can be integrated with the Aignostics Platform for workf
866925

867926
### M
868927

869-
**Marimo**
928+
**Marimo**
870929
Modern notebook environment supported by the Aignostics Platform as an alternative to Jupyter.
871930

931+
**MCP (Model Context Protocol)**
932+
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.
933+
872934
**Metadata**
873935
Descriptive information about whole slide images including dimensions, resolution, tissue type, and disease information required for processing.
874936

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,13 @@ dependencies = [
138138
"lxml>=6.0.2", # For python 3.14 pre-built wheels
139139
"filelock>=3.20.1", # CVE-2025-68146
140140
"marshmallow>=3.26.2", # CVE-2025-68480
141+
"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. Upgrade once a stable release is out.
141142
]
142143

143144
[project.optional-dependencies]
144145
pyinstaller = ["pyinstaller>=6.14.0,<7"]
145146
jupyter = [
146-
"jupyter>=1.1.1,<2",
147+
"jupyter>=1.1.1,<2",
147148
# Transitive overrides
148149
# WARNING: one cannot negate or downgrade a dependency required here. use override-dependencies for that.
149150
"jupyter-core>=5.8.1", # CVE-2025-30167

requirements/SHR-UTILS-1.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
itemId: SHR-UTILS-1
3+
itemTitle: Central MCP Server for SDK and Plugin Tool Access
4+
itemType: Requirement
5+
Requirement type: ENVIRONMENT
6+
---
7+
8+
## Description
9+
10+
Users shall be able to expose SDK and plugin functionality to AI agents via a central MCP server for use in AI-assisted development workflows.

requirements/SWR-UTILS-1-1.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
itemId: SWR-UTILS-1-1
3+
itemTitle: MCP Server with Auto-Discovery and CLI Commands
4+
itemHasParent: SHR-UTILS-1
5+
itemType: Requirement
6+
Requirement type: FUNCTIONAL
7+
Layer: System (backend logic)
8+
---
9+
10+
System shall provide a central MCP server that automatically discovers plugin tools via entry-point-based service discovery, mounts them with namespace isolation to prevent tool name collisions, and exposes CLI commands (`mcp run` to start the stdio transport server, `mcp list-tools` to enumerate all registered tools).

specifications/SPEC-UTILS-SERVICE.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ itemId: SPEC-UTILS-SERVICE
33
itemTitle: Utils Module Specification
44
itemType: Software Item Spec
55
itemIsRelatedTo: SPEC-GUI-SERVICE, SPEC-BUCKET-SERVICE, SPEC-DATASET-SERVICE, SPEC-NOTEBOOK-SERVICE, SPEC-PLATFORM-SERVICE, SPEC-QUPATH-SERVICE, SPEC-SYSTEM-SERVICE, SPEC-WSI-SERVICE
6-
itemFulfills: SWR-APPLICATION-1-1, SWR-APPLICATION-1-2, SWR-APPLICATION-2-1, SWR-APPLICATION-2-2, SWR-APPLICATION-2-3, SWR-APPLICATION-2-4, SWR-APPLICATION-2-5, SWR-APPLICATION-2-6, SWR-APPLICATION-2-7, SWR-APPLICATION-2-8, SWR-APPLICATION-2-9, SWR-APPLICATION-2-10, SWR-APPLICATION-2-11, SWR-APPLICATION-2-12, SWR-APPLICATION-2-13, SWR-APPLICATION-2-14, SWR-APPLICATION-2-15, SWR-APPLICATION-2-16, SWR-APPLICATION-3-1, SWR-APPLICATION-3-2, SWR-APPLICATION-3-3, SWR-BUCKET-1-1, SWR-BUCKET-1-2, SWR-BUCKET-1-3, SWR-BUCKET-1-4, SWR-BUCKET-1-5, SWR-BUCKET-1-6, SWR-BUCKET-1-7, SWR-BUCKET-1-8, SWR-BUCKET-1-9, SWR-DATASET-1-1, SWR-DATASET-1-2, SWR-DATASET-1-3, SWR-NOTEBOOK-1-1, SWR-VISUALIZATION-1-1, SWR-VISUALIZATION-1-2, SWR-VISUALIZATION-1-3, SWR-VISUALIZATION-1-4, SWR_SYSTEM_CLI_HEALTH_1, SWR_SYSTEM_GUI_HEALTH_1, SWR_SYSTEM_GUI_SETTINGS_1
6+
itemFulfills: SWR-APPLICATION-1-1, SWR-APPLICATION-1-2, SWR-APPLICATION-2-1, SWR-APPLICATION-2-2, SWR-APPLICATION-2-3, SWR-APPLICATION-2-4, SWR-APPLICATION-2-5, SWR-APPLICATION-2-6, SWR-APPLICATION-2-7, SWR-APPLICATION-2-8, SWR-APPLICATION-2-9, SWR-APPLICATION-2-10, SWR-APPLICATION-2-11, SWR-APPLICATION-2-12, SWR-APPLICATION-2-13, SWR-APPLICATION-2-14, SWR-APPLICATION-2-15, SWR-APPLICATION-2-16, SWR-APPLICATION-3-1, SWR-APPLICATION-3-2, SWR-APPLICATION-3-3, SWR-BUCKET-1-1, SWR-BUCKET-1-2, SWR-BUCKET-1-3, SWR-BUCKET-1-4, SWR-BUCKET-1-5, SWR-BUCKET-1-6, SWR-BUCKET-1-7, SWR-BUCKET-1-8, SWR-BUCKET-1-9, SWR-DATASET-1-1, SWR-DATASET-1-2, SWR-DATASET-1-3, SWR-NOTEBOOK-1-1, SWR-UTILS-1-1, SWR-VISUALIZATION-1-1, SWR-VISUALIZATION-1-2, SWR-VISUALIZATION-1-3, SWR-VISUALIZATION-1-4, SWR_SYSTEM_CLI_HEALTH_1, SWR_SYSTEM_GUI_HEALTH_1, SWR_SYSTEM_GUI_SETTINGS_1
77
Layer: Infrastructure Service
88
Version: 1.0.0
99
Date: 2025-10-13
@@ -28,6 +28,7 @@ The Utils Module shall:
2828
- **[FR-07]** Implement settings management with validation, serialization, and sensitive data handling
2929
- **[FR-08]** Provide file system utilities for user data directory management and path sanitization
3030
- **[FR-09]** Support process information gathering and runtime environment detection
31+
- **[FR-10]** Provide a central MCP server with auto-discovery of plugin tools, namespace isolation, and CLI commands for running the server and listing available tools
3132

3233
### 1.3 Non-Functional Requirements
3334

@@ -65,6 +66,7 @@ utils/
6566
├── _console.py # Rich console configuration
6667
├── _logfire.py # Logfire integration (optional)
6768
├── _sentry.py # Sentry integration (optional)
69+
├── _mcp.py # MCP server with auto-discovery and plugin mounting
6870
├── _notebook.py # Marimo notebook utilities (optional)
6971
└── boot.py # Application bootstrap and initialization
7072
```
@@ -220,6 +222,8 @@ uvx aignostics [module-name] [subcommand] [options]
220222
| ---------------- | ----------------------------- | ------------------ | ---------------------- |
221223
| `prepare_cli()` | Dynamic command registration | Typer instance | Configured CLI |
222224
| Service commands | Module-specific functionality | Service parameters | Module-specific output |
225+
| `mcp run` | Start MCP server (stdio) | None | Running MCP server |
226+
| `mcp list-tools` | Enumerate registered tools | None | Tool name/description |
223227

224228
### 4.3 GUI Interface
225229

@@ -253,6 +257,7 @@ uvx aignostics [module-name] [subcommand] [options]
253257
| `nicegui` | ^1.0 | GUI framework support | Optional | CLI-only mode |
254258
| `logfire` | ^0.41 | Observability and monitoring | Optional | Standard logging |
255259
| `sentry-sdk` | ^2.0 | Error tracking and performance | Optional | Local error handling |
260+
| `fastmcp` | >=2.0,<3 | MCP server framework | Required | N/A - MCP functionality |
256261
| `marimo` | ^0.8 | Notebook utilities | Optional | Notebook features disabled |
257262

258263
_Note: For exact version requirements, refer to `pyproject.toml` and dependency lock files._

src/aignostics/CLAUDE.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This file provides a comprehensive overview of all modules in the Aignostics SDK
1111
| **wsi** | Whole slide image processing ||||
1212
| **dataset** | IDC dataset downloads ||||
1313
| **bucket** | Cloud storage operations ||||
14-
| **utils** | Core utilities & DI | |||
14+
| **utils** | Core utilities & DI | |||
1515
| **gui** | Desktop launchpad ||||
1616
| **notebook** | Marimo notebook server ||||
1717
| **qupath** | QuPath integration ||||
@@ -25,8 +25,8 @@ This file provides a comprehensive overview of all modules in the Aignostics SDK
2525

2626
- **Core Features**:
2727
- OAuth 2.0 authentication, JWT token management, API client wrapper
28-
- **SDK Metadata System** (NEW): Automatic tracking of execution context, user info, CI/CD environment
29-
- JSON Schema validation for metadata with versioning (v0.0.1)
28+
- **SDK Metadata System**: Automatic tracking of execution context, user info, CI/CD environment
29+
- JSON Schema validation for metadata with versioning (Run v0.0.4, Item v0.0.3)
3030
- Operation caching for non-mutating API calls
3131
- **CLI**:
3232
- `user login`, `user logout`, `user whoami` for authentication
@@ -80,10 +80,11 @@ This file provides a comprehensive overview of all modules in the Aignostics SDK
8080

8181
- **Core Features**:
8282
- Dependency injection, logging, settings, health checks
83-
- **Enhanced User Agent** (NEW): Context-aware user agent with CI/CD tracking
83+
- Enhanced user agent with CI/CD context tracking
84+
- **MCP Server**: Central MCP server with auto-discovery of plugin tools (`mcp_create_server`, `mcp_run`, `mcp_list_tools`)
85+
- **Navigation**: GUI sidebar navigation infrastructure (`BaseNavBuilder`, `NavItem`, `NavGroup`)
8486
- **Service Discovery**: `locate_implementations()`, `locate_subclasses()`
85-
- **User Agent**: Generates `{name}/{version} ({platform}; {test}; {github_run_url})`
86-
- **No CLI/GUI**: Infrastructure module
87+
- **User Agent**: Generates `{name}-python-sdk/{version} ({platform}; +{repo_url}; {test}; {github_run_url})`
8788
- **Used By**: All modules; platform module for SDK metadata
8889

8990
### 🖥️ gui
@@ -227,7 +228,7 @@ utils.locate_implementations(BaseService)
227228

228229
- **Authentication**: Token cached by `platform`, used by all API calls
229230
- **Settings**: Managed by `utils`, consumed by all modules
230-
- **Logging**: Centralized through `utils.get_logger()`
231+
- **Logging**: Centralized through `loguru.logger`
231232
- **Health Checks**: All services implement `BaseService.health()`
232233

233234
## CLI Usage Examples

src/aignostics/cli.py

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import typer
88
from loguru import logger
99

10-
from .constants import NOTEBOOK_DEFAULT, WINDOW_TITLE
11-
from .utils import (
10+
from aignostics.constants import NOTEBOOK_DEFAULT, WINDOW_TITLE
11+
from aignostics.utils import (
1212
__is_running_in_container__,
1313
__python_version__,
1414
__version__,
@@ -25,15 +25,15 @@
2525
@cli.command()
2626
def launchpad() -> None:
2727
"""Open Aignostics Launchpad, the graphical user interface of the Aignostics Platform."""
28-
from .utils import gui_run # noqa: PLC0415
28+
from aignostics.utils import gui_run # noqa: PLC0415
2929

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

3232

3333
if find_spec("marimo"):
3434
from typing import Annotated
3535

36-
from .utils import create_marimo_app
36+
from aignostics.utils import create_marimo_app
3737

3838
@cli.command()
3939
def notebook(
@@ -64,6 +64,61 @@ def notebook(
6464
uvicorn.run(create_marimo_app(notebook=notebook, override_if_exists=override_if_exists), host=host, port=port)
6565

6666

67+
# MCP (Model Context Protocol) server CLI
68+
mcp_cli = typer.Typer(name="mcp", help="MCP (Model Context Protocol) server for AI agent integration.")
69+
70+
71+
@mcp_cli.command("run")
72+
def mcp_run() -> None:
73+
"""Run the MCP server.
74+
75+
Starts an MCP server using `stdio` transport that exposes SDK functionality
76+
to AI agents. The server automatically discovers and mounts tools from
77+
the SDK and any installed plugins.
78+
79+
Examples:
80+
uv run aignostics mcp run
81+
"""
82+
from aignostics.utils import mcp_run # noqa: PLC0415
83+
84+
mcp_run()
85+
86+
87+
@mcp_cli.command("list-tools")
88+
def mcp_list_tools() -> None:
89+
"""List all available MCP tools.
90+
91+
Shows all tools available in the MCP server, including tools from
92+
the SDK and any installed plugins. Each tool is displayed with its
93+
name and description.
94+
95+
Examples:
96+
uv run aignostics mcp list-tools
97+
"""
98+
import operator # noqa: PLC0415
99+
100+
from rich.table import Table # noqa: PLC0415
101+
102+
from aignostics.utils import mcp_list_tools # noqa: PLC0415
103+
104+
tools = mcp_list_tools()
105+
106+
if not tools:
107+
console.print("[dim]No tools discovered[/dim]")
108+
return
109+
110+
table = Table(title="Available MCP Tools")
111+
table.add_column("Name", style="cyan", no_wrap=True)
112+
table.add_column("Description", style="white")
113+
114+
for tool in sorted(tools, key=operator.itemgetter("name")):
115+
table.add_row(tool["name"], tool["description"])
116+
117+
console.print(table)
118+
119+
120+
cli.add_typer(mcp_cli)
121+
67122
prepare_cli(
68123
cli, f"🔬 Aignostics Python SDK v{__version__} - built with love in Berlin 🐻 // Python v{__python_version__}"
69124
)

0 commit comments

Comments
 (0)