integrum 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- integrum-0.1.0/.gitignore +42 -0
- integrum-0.1.0/PKG-INFO +111 -0
- integrum-0.1.0/README.md +82 -0
- integrum-0.1.0/examples/gemma_sklearn_session.json +109 -0
- integrum-0.1.0/examples/gemma_sklearn_session.md +207 -0
- integrum-0.1.0/pyproject.toml +51 -0
- integrum-0.1.0/src/integrum/__init__.py +19 -0
- integrum-0.1.0/src/integrum/cli.py +109 -0
- integrum-0.1.0/src/integrum/docstrings.py +103 -0
- integrum-0.1.0/src/integrum/filter.py +60 -0
- integrum-0.1.0/src/integrum/inspector.py +201 -0
- integrum-0.1.0/src/integrum/logo.png +0 -0
- integrum-0.1.0/src/integrum/logo_white.png +0 -0
- integrum-0.1.0/src/integrum/server.py +479 -0
- integrum-0.1.0/src/integrum/store.py +224 -0
- integrum-0.1.0/tests/test_acceptance_gemma.py +248 -0
- integrum-0.1.0/tests/test_inspector_filter.py +72 -0
- integrum-0.1.0/tests/test_server.py +184 -0
- integrum-0.1.0/tests/test_store.py +86 -0
- integrum-0.1.0/uv.lock +2916 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
develop-eggs/
|
|
9
|
+
dist/
|
|
10
|
+
downloads/
|
|
11
|
+
eggs/
|
|
12
|
+
.eggs/
|
|
13
|
+
lib/
|
|
14
|
+
lib64/
|
|
15
|
+
parts/
|
|
16
|
+
sdist/
|
|
17
|
+
var/
|
|
18
|
+
wheels/
|
|
19
|
+
*.egg-info/
|
|
20
|
+
.installed.cfg
|
|
21
|
+
*.egg
|
|
22
|
+
|
|
23
|
+
# Virtual environments
|
|
24
|
+
.venv/
|
|
25
|
+
env/
|
|
26
|
+
venv/
|
|
27
|
+
ENV/
|
|
28
|
+
|
|
29
|
+
# Pytest / Coverage
|
|
30
|
+
.pytest_cache/
|
|
31
|
+
.coverage
|
|
32
|
+
htmlcov/
|
|
33
|
+
|
|
34
|
+
# IDE / Editors
|
|
35
|
+
.vscode/
|
|
36
|
+
.idea/
|
|
37
|
+
*.swp
|
|
38
|
+
*.swo
|
|
39
|
+
|
|
40
|
+
# Environment variables
|
|
41
|
+
.env.local
|
|
42
|
+
.env
|
integrum-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: integrum
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Convert any Python module or library into an MCP server with FastMCP and stateful word-based object management.
|
|
5
|
+
Author: Integrum Team
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: fastmcp,llm,mcp,reflection,scikit-learn,tools
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: click>=8.1.0
|
|
18
|
+
Requires-Dist: docstring-parser>=0.16
|
|
19
|
+
Requires-Dist: fastmcp>=4.0.0
|
|
20
|
+
Requires-Dist: pydantic>=2.0.0
|
|
21
|
+
Provides-Extra: test
|
|
22
|
+
Requires-Dist: openai>=1.30.0; extra == 'test'
|
|
23
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'test'
|
|
24
|
+
Requires-Dist: pytest>=8.0.0; extra == 'test'
|
|
25
|
+
Requires-Dist: python-dotenv>=1.0.0; extra == 'test'
|
|
26
|
+
Requires-Dist: scikit-learn>=1.4.0; extra == 'test'
|
|
27
|
+
Requires-Dist: tenacity>=8.2.0; extra == 'test'
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
<img src="src/integrum/logo.png" alt="Integrum Logo" width="180"/>
|
|
32
|
+
</p>
|
|
33
|
+
|
|
34
|
+
<h1 align="center">Integrum</h1>
|
|
35
|
+
|
|
36
|
+
<p align="center">
|
|
37
|
+
<em>Convert any Python module or library into a FastMCP Model Context Protocol server.</em>
|
|
38
|
+
</p>
|
|
39
|
+
|
|
40
|
+
**Integrum** turns any Python module, library, function, or class into a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server powered by [FastMCP](https://github.com/jlowin/fastmcp).
|
|
41
|
+
|
|
42
|
+
Integrum uses Python reflection (`inspect`), regex filtering, and an in-memory **Word-Based Object Store** (`playful_llama`, `swift_falcon`) so that object-oriented libraries (such as `scikit-learn`, `pandas`, `PyTorch`) can be used naturally by LLMs across multi-turn conversations without token bloat.
|
|
43
|
+
|
|
44
|
+
## Features
|
|
45
|
+
|
|
46
|
+
- **Module Reflection**: Automatically introspects functions and classes using `inspect`.
|
|
47
|
+
- **Regex Filtering**: Expose only what you need with `--include` and `--exclude` regex patterns.
|
|
48
|
+
- **Word-Based State Management**: Object IDs are short, memorable words (e.g. `playful_llama`) to save tokens and avoid UUID hallucination.
|
|
49
|
+
- **Multi-User Isolation**: Supports FastMCP `Context` sessions to partition objects per connecting client.
|
|
50
|
+
- **Docstring Instruction Injection**: Transforms Python docstrings into LLM tool documentation and automatically injects state-handling instructions.
|
|
51
|
+
- **Dot-Notation Attribute Resolution**: Pass `swift_falcon.data` or `swift_falcon.target` directly to subsequent tool calls like `fit()`.
|
|
52
|
+
- **CLI & Python API**: Run from the command line (`integrum expose`) or integrate directly into Python scripts.
|
|
53
|
+
|
|
54
|
+
## Installation
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
uv pip install integrum
|
|
58
|
+
# or
|
|
59
|
+
pip install integrum
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Quick Start (CLI)
|
|
63
|
+
|
|
64
|
+
Expose `scikit-learn` dataset loaders and RandomForestClassifier as an MCP server:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
integrum expose sklearn.datasets.load_iris sklearn.ensemble.RandomForestClassifier
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Preview what tools will be exposed:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
integrum list sklearn.datasets.load_iris sklearn.ensemble.RandomForestClassifier
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Filter functions and methods with regex:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
integrum expose sklearn.datasets sklearn.ensemble \
|
|
80
|
+
--include "^(load_iris|RandomForestClassifier)$"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Run with HTTP or SSE transport:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
integrum expose sklearn.datasets.load_iris --transport http --port 8000
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Python API
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from integrum import IntegrumServer
|
|
93
|
+
|
|
94
|
+
server = IntegrumServer(name="ml-server")
|
|
95
|
+
server.expose(["sklearn.datasets.load_iris", "sklearn.ensemble.RandomForestClassifier"])
|
|
96
|
+
|
|
97
|
+
# Run over stdio (default for MCP desktop clients)
|
|
98
|
+
server.run(transport="stdio")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## How State Management Works
|
|
102
|
+
|
|
103
|
+
When a class is exposed, Integrum registers:
|
|
104
|
+
1. `<ClassName>_create`: Instantiates the class and stores it under a word ID (e.g., `playful_llama`).
|
|
105
|
+
2. `<ClassName>_<method>`: Accepts a virtual parameter `obj_id: str` (e.g., `obj_id="playful_llama"`), resolves the underlying instance, and executes the method.
|
|
106
|
+
|
|
107
|
+
Returned objects (such as datasets or numpy arrays) are also registered in the store with word IDs, allowing subsequent tools to receive them as arguments.
|
|
108
|
+
|
|
109
|
+
## Examples
|
|
110
|
+
|
|
111
|
+
Check out [`examples/gemma_sklearn_session.md`](examples/gemma_sklearn_session.md) and [`examples/gemma_sklearn_session.json`](examples/gemma_sklearn_session.json) for a complete, verified multi-turn transcript of Gemma 4 26B loading the Iris dataset, performing `train_test_split`, training a `RandomForestClassifier`, and evaluating accuracy.
|
integrum-0.1.0/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="src/integrum/logo.png" alt="Integrum Logo" width="180"/>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">Integrum</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<em>Convert any Python module or library into a FastMCP Model Context Protocol server.</em>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
**Integrum** turns any Python module, library, function, or class into a [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server powered by [FastMCP](https://github.com/jlowin/fastmcp).
|
|
12
|
+
|
|
13
|
+
Integrum uses Python reflection (`inspect`), regex filtering, and an in-memory **Word-Based Object Store** (`playful_llama`, `swift_falcon`) so that object-oriented libraries (such as `scikit-learn`, `pandas`, `PyTorch`) can be used naturally by LLMs across multi-turn conversations without token bloat.
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- **Module Reflection**: Automatically introspects functions and classes using `inspect`.
|
|
18
|
+
- **Regex Filtering**: Expose only what you need with `--include` and `--exclude` regex patterns.
|
|
19
|
+
- **Word-Based State Management**: Object IDs are short, memorable words (e.g. `playful_llama`) to save tokens and avoid UUID hallucination.
|
|
20
|
+
- **Multi-User Isolation**: Supports FastMCP `Context` sessions to partition objects per connecting client.
|
|
21
|
+
- **Docstring Instruction Injection**: Transforms Python docstrings into LLM tool documentation and automatically injects state-handling instructions.
|
|
22
|
+
- **Dot-Notation Attribute Resolution**: Pass `swift_falcon.data` or `swift_falcon.target` directly to subsequent tool calls like `fit()`.
|
|
23
|
+
- **CLI & Python API**: Run from the command line (`integrum expose`) or integrate directly into Python scripts.
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
uv pip install integrum
|
|
29
|
+
# or
|
|
30
|
+
pip install integrum
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start (CLI)
|
|
34
|
+
|
|
35
|
+
Expose `scikit-learn` dataset loaders and RandomForestClassifier as an MCP server:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
integrum expose sklearn.datasets.load_iris sklearn.ensemble.RandomForestClassifier
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Preview what tools will be exposed:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
integrum list sklearn.datasets.load_iris sklearn.ensemble.RandomForestClassifier
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Filter functions and methods with regex:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
integrum expose sklearn.datasets sklearn.ensemble \
|
|
51
|
+
--include "^(load_iris|RandomForestClassifier)$"
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Run with HTTP or SSE transport:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
integrum expose sklearn.datasets.load_iris --transport http --port 8000
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Python API
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from integrum import IntegrumServer
|
|
64
|
+
|
|
65
|
+
server = IntegrumServer(name="ml-server")
|
|
66
|
+
server.expose(["sklearn.datasets.load_iris", "sklearn.ensemble.RandomForestClassifier"])
|
|
67
|
+
|
|
68
|
+
# Run over stdio (default for MCP desktop clients)
|
|
69
|
+
server.run(transport="stdio")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## How State Management Works
|
|
73
|
+
|
|
74
|
+
When a class is exposed, Integrum registers:
|
|
75
|
+
1. `<ClassName>_create`: Instantiates the class and stores it under a word ID (e.g., `playful_llama`).
|
|
76
|
+
2. `<ClassName>_<method>`: Accepts a virtual parameter `obj_id: str` (e.g., `obj_id="playful_llama"`), resolves the underlying instance, and executes the method.
|
|
77
|
+
|
|
78
|
+
Returned objects (such as datasets or numpy arrays) are also registered in the store with word IDs, allowing subsequent tools to receive them as arguments.
|
|
79
|
+
|
|
80
|
+
## Examples
|
|
81
|
+
|
|
82
|
+
Check out [`examples/gemma_sklearn_session.md`](examples/gemma_sklearn_session.md) and [`examples/gemma_sklearn_session.json`](examples/gemma_sklearn_session.json) for a complete, verified multi-turn transcript of Gemma 4 26B loading the Iris dataset, performing `train_test_split`, training a `RandomForestClassifier`, and evaluating accuracy.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"role": "system",
|
|
4
|
+
"content": "You are an expert AI data scientist using tools from an Integrum MCP server.\nKey Rules:\n- When a tool returns an object, it assigns an object ID (e.g. 'lucid_yak').\n- Use 'obj_id' to call methods on that object (e.g. RandomForestClassifier_fit, RandomForestClassifier_score).\n- To split data with train_test_split, pass arrays as a list, e.g. arrays=['<id>.data', '<id>.target'] (or arrays=['<id>_0', '<id>_1']), along with test_size (e.g. 0.2) and random_state.\n- train_test_split returns 4 arrays: X_train, X_test, y_train, y_test (accessible via '<split_id>.X_train', '<split_id>.X_test', etc.).\n- Fit the classifier on the training set (X_train, y_train).\n- Evaluate test accuracy using RandomForestClassifier_score (passing obj_id, X='<split_id>.X_test', y='<split_id>.y_test') or accuracy_score.\n- Always report the final accuracy score in your final reply."
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
"role": "user",
|
|
8
|
+
"content": "Please perform the following end-to-end task using the tools:\n1. Load the iris dataset using load_iris.\n2. Split the dataset into train and test sets using train_test_split (test_size=0.2, random_state=42).\n3. Create a RandomForestClassifier instance.\n4. Train / fit the classifier on the training set (X_train and y_train).\n5. Evaluate accuracy on the test set (X_test and y_test) and report the final test accuracy."
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"role": "assistant",
|
|
12
|
+
"content": null,
|
|
13
|
+
"tool_calls": [
|
|
14
|
+
{
|
|
15
|
+
"id": "call_load_iris_001",
|
|
16
|
+
"type": "function",
|
|
17
|
+
"function": {
|
|
18
|
+
"name": "load_iris",
|
|
19
|
+
"arguments": "{\"return_X_y\": true}"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"role": "tool",
|
|
26
|
+
"tool_call_id": "call_load_iris_001",
|
|
27
|
+
"content": "{\"status\":\"success\",\"object_id\":\"warm_hawk\",\"type\":\"builtins.tuple\",\"shape\":\"len=2\",\"items\":[\"warm_hawk_0\",\"warm_hawk_1\"],\"message\":\"Stored tuple with object_id 'warm_hawk'. Access items using: ['warm_hawk_0', 'warm_hawk_1'].\"}"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"role": "assistant",
|
|
31
|
+
"content": null,
|
|
32
|
+
"tool_calls": [
|
|
33
|
+
{
|
|
34
|
+
"id": "call_train_test_split_002",
|
|
35
|
+
"type": "function",
|
|
36
|
+
"function": {
|
|
37
|
+
"name": "train_test_split",
|
|
38
|
+
"arguments": "{\"arrays\": [\"warm_hawk_0\", \"warm_hawk_1\"], \"random_state\": 42, \"test_size\": 0.2}"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"role": "tool",
|
|
45
|
+
"tool_call_id": "call_train_test_split_002",
|
|
46
|
+
"content": "{\"status\":\"success\",\"object_id\":\"serene_panda\",\"type\":\"builtins.list\",\"shape\":\"len=4\",\"items\":[\"serene_panda_0\",\"serene_panda_1\",\"serene_panda_2\",\"serene_panda_3\"],\"sub_keys\":[\"serene_panda.X_train\",\"serene_panda.X_test\",\"serene_panda.y_train\",\"serene_panda.y_test\"],\"message\":\"train_test_split returned 4 arrays stored under 'serene_panda':\\n - X_train: 'serene_panda.X_train' (or 'serene_panda_0')\\n - X_test: 'serene_panda.X_test' (or 'serene_panda_1')\\n - y_train: 'serene_panda.y_train' (or 'serene_panda_2')\\n - y_test: 'serene_panda.y_test' (or 'serene_panda_3')\"}"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"role": "assistant",
|
|
50
|
+
"content": null,
|
|
51
|
+
"tool_calls": [
|
|
52
|
+
{
|
|
53
|
+
"id": "call_rf_create_003",
|
|
54
|
+
"type": "function",
|
|
55
|
+
"function": {
|
|
56
|
+
"name": "RandomForestClassifier_create",
|
|
57
|
+
"arguments": "{\"random_state\": 42}"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"role": "tool",
|
|
64
|
+
"tool_call_id": "call_rf_create_003",
|
|
65
|
+
"content": "{\"status\":\"success\",\"object_id\":\"radiant_newt\",\"class\":\"RandomForestClassifier\",\"message\":\"Created RandomForestClassifier instance with object_id 'radiant_newt'. Use obj_id='radiant_newt' in subsequent method calls like RandomForestClassifier_fit.\"}"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"role": "assistant",
|
|
69
|
+
"content": null,
|
|
70
|
+
"tool_calls": [
|
|
71
|
+
{
|
|
72
|
+
"id": "call_rf_fit_004",
|
|
73
|
+
"type": "function",
|
|
74
|
+
"function": {
|
|
75
|
+
"name": "RandomForestClassifier_fit",
|
|
76
|
+
"arguments": "{\"obj_id\": \"radiant_newt\", \"X\": \"serene_panda.X_train\", \"y\": \"serene_panda.y_train\"}"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"role": "tool",
|
|
83
|
+
"tool_call_id": "call_rf_fit_004",
|
|
84
|
+
"content": "{\"status\":\"success\",\"object_id\":\"radiant_newt\",\"message\":\"Successfully executed on object 'radiant_newt' (returned self).\"}"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"role": "assistant",
|
|
88
|
+
"content": null,
|
|
89
|
+
"tool_calls": [
|
|
90
|
+
{
|
|
91
|
+
"id": "call_rf_score_005",
|
|
92
|
+
"type": "function",
|
|
93
|
+
"function": {
|
|
94
|
+
"name": "RandomForestClassifier_score",
|
|
95
|
+
"arguments": "{\"obj_id\": \"radiant_newt\", \"X\": \"serene_panda.X_test\", \"y\": \"serene_panda.y_test\"}"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"role": "tool",
|
|
102
|
+
"tool_call_id": "call_rf_score_005",
|
|
103
|
+
"content": "1.0"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"role": "assistant",
|
|
107
|
+
"content": "The end-to-end task has been completed successfully. Here is the summary of the steps performed:\n\n1. **Dataset Loaded**: The Iris dataset was loaded.\n2. **Data Split**: The dataset was split into training and testing sets (80% train, 20% test) using `random_state=42`.\n3. **Model Created**: A `RandomForestClassifier` instance was initialized.\n4. **Model Trained**: The classifier was fitted on the training data (`X_train`, `y_train`).\n5. **Model Evaluated**: The model's accuracy was evaluated on the test set (`X_test`, `y_test`).\n\n**Final Test Accuracy: 1.0** (100%)"
|
|
108
|
+
}
|
|
109
|
+
]
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Example: End-to-End ML Pipeline with Gemma 4 26B & Integrum
|
|
2
|
+
|
|
3
|
+
This example documents the exact multi-turn chat and tool calling session between **Gemma 4 26B** and the **Integrum FastMCP Server** exposing `scikit-learn`.
|
|
4
|
+
|
|
5
|
+
The model loads the Iris dataset, performs a train-test split, instantiates a `RandomForestClassifier`, fits the classifier on `X_train` and `y_train`, evaluates accuracy on `X_test` and `y_test`, and reports the final result.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. System Prompt & Setup
|
|
10
|
+
|
|
11
|
+
### Exposed Tools
|
|
12
|
+
- `load_iris`: Loads Iris dataset.
|
|
13
|
+
- `train_test_split`: Splits arrays into `X_train`, `X_test`, `y_train`, `y_test`.
|
|
14
|
+
- `RandomForestClassifier_create`: Instantiates the classifier and returns an object ID.
|
|
15
|
+
- `RandomForestClassifier_fit`: Trains the classifier instance using virtual parameter `obj_id`.
|
|
16
|
+
- `RandomForestClassifier_score`: Evaluates test set accuracy using virtual parameter `obj_id`.
|
|
17
|
+
|
|
18
|
+
### System Message
|
|
19
|
+
```text
|
|
20
|
+
You are an expert AI data scientist using tools from an Integrum MCP server.
|
|
21
|
+
Key Rules:
|
|
22
|
+
- When a tool returns an object, it assigns an object ID (e.g. 'lucid_yak').
|
|
23
|
+
- Use 'obj_id' to call methods on that object (e.g. RandomForestClassifier_fit, RandomForestClassifier_score).
|
|
24
|
+
- To split data with train_test_split, pass arrays as a list, e.g. arrays=['<id>.data', '<id>.target'] (or arrays=['<id>_0', '<id>_1']), along with test_size (e.g. 0.2) and random_state.
|
|
25
|
+
- train_test_split returns 4 arrays: X_train, X_test, y_train, y_test (accessible via '<split_id>.X_train', '<split_id>.X_test', etc.).
|
|
26
|
+
- Fit the classifier on the training set (X_train, y_train).
|
|
27
|
+
- Evaluate test accuracy using RandomForestClassifier_score (passing obj_id, X='<split_id>.X_test', y='<split_id>.y_test') or accuracy_score.
|
|
28
|
+
- Always report the final accuracy score in your final reply.
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### User Request
|
|
32
|
+
```text
|
|
33
|
+
Please perform the following end-to-end task using the tools:
|
|
34
|
+
1. Load the iris dataset using load_iris.
|
|
35
|
+
2. Split the dataset into train and test sets using train_test_split (test_size=0.2, random_state=42).
|
|
36
|
+
3. Create a RandomForestClassifier instance.
|
|
37
|
+
4. Train / fit the classifier on the training set (X_train and y_train).
|
|
38
|
+
5. Evaluate accuracy on the test set (X_test and y_test) and report the final test accuracy.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## 2. Multi-Turn Execution Transcript
|
|
44
|
+
|
|
45
|
+
### Turn 1: Load Dataset
|
|
46
|
+
|
|
47
|
+
**Gemma Tool Call:**
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"name": "load_iris",
|
|
51
|
+
"arguments": {
|
|
52
|
+
"return_X_y": true
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Integrum FastMCP Output:**
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"status": "success",
|
|
61
|
+
"object_id": "warm_hawk",
|
|
62
|
+
"type": "builtins.tuple",
|
|
63
|
+
"shape": "len=2",
|
|
64
|
+
"items": [
|
|
65
|
+
"warm_hawk_0",
|
|
66
|
+
"warm_hawk_1"
|
|
67
|
+
],
|
|
68
|
+
"message": "Stored tuple with object_id 'warm_hawk'. Access items using: ['warm_hawk_0', 'warm_hawk_1']."
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
### Turn 2: Train/Test Split
|
|
75
|
+
|
|
76
|
+
**Gemma Tool Call:**
|
|
77
|
+
```json
|
|
78
|
+
{
|
|
79
|
+
"name": "train_test_split",
|
|
80
|
+
"arguments": {
|
|
81
|
+
"arrays": [
|
|
82
|
+
"warm_hawk_0",
|
|
83
|
+
"warm_hawk_1"
|
|
84
|
+
],
|
|
85
|
+
"random_state": 42,
|
|
86
|
+
"test_size": 0.2
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Integrum FastMCP Output:**
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"status": "success",
|
|
95
|
+
"object_id": "serene_panda",
|
|
96
|
+
"type": "builtins.list",
|
|
97
|
+
"shape": "len=4",
|
|
98
|
+
"items": [
|
|
99
|
+
"serene_panda_0",
|
|
100
|
+
"serene_panda_1",
|
|
101
|
+
"serene_panda_2",
|
|
102
|
+
"serene_panda_3"
|
|
103
|
+
],
|
|
104
|
+
"sub_keys": [
|
|
105
|
+
"serene_panda.X_train",
|
|
106
|
+
"serene_panda.X_test",
|
|
107
|
+
"serene_panda.y_train",
|
|
108
|
+
"serene_panda.y_test"
|
|
109
|
+
],
|
|
110
|
+
"message": "train_test_split returned 4 arrays stored under 'serene_panda':\n - X_train: 'serene_panda.X_train' (or 'serene_panda_0')\n - X_test: 'serene_panda.X_test' (or 'serene_panda_1')\n - y_train: 'serene_panda.y_train' (or 'serene_panda_2')\n - y_test: 'serene_panda.y_test' (or 'serene_panda_3')"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### Turn 3: Instantiate RandomForestClassifier
|
|
117
|
+
|
|
118
|
+
**Gemma Tool Call:**
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"name": "RandomForestClassifier_create",
|
|
122
|
+
"arguments": {
|
|
123
|
+
"random_state": 42
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Integrum FastMCP Output:**
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"status": "success",
|
|
132
|
+
"object_id": "radiant_newt",
|
|
133
|
+
"class": "RandomForestClassifier",
|
|
134
|
+
"message": "Created RandomForestClassifier instance with object_id 'radiant_newt'. Use obj_id='radiant_newt' in subsequent method calls like RandomForestClassifier_fit."
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### Turn 4: Fit Model on Training Data
|
|
141
|
+
|
|
142
|
+
**Gemma Tool Call:**
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"name": "RandomForestClassifier_fit",
|
|
146
|
+
"arguments": {
|
|
147
|
+
"obj_id": "radiant_newt",
|
|
148
|
+
"X": "serene_panda.X_train",
|
|
149
|
+
"y": "serene_panda.y_train"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Integrum FastMCP Output:**
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"status": "success",
|
|
158
|
+
"object_id": "radiant_newt",
|
|
159
|
+
"message": "Successfully executed on object 'radiant_newt' (returned self)."
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### Turn 5: Evaluate Model on Test Data
|
|
166
|
+
|
|
167
|
+
**Gemma Tool Call:**
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"name": "RandomForestClassifier_score",
|
|
171
|
+
"arguments": {
|
|
172
|
+
"obj_id": "radiant_newt",
|
|
173
|
+
"X": "serene_panda.X_test",
|
|
174
|
+
"y": "serene_panda.y_test"
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Integrum FastMCP Output:**
|
|
180
|
+
```text
|
|
181
|
+
1.0
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
### Turn 6: Assistant Final Response
|
|
187
|
+
|
|
188
|
+
**Gemma Response:**
|
|
189
|
+
```markdown
|
|
190
|
+
The end-to-end task has been completed successfully. Here is the summary of the steps performed:
|
|
191
|
+
|
|
192
|
+
1. **Dataset Loaded**: The Iris dataset was loaded.
|
|
193
|
+
2. **Data Split**: The dataset was split into training and testing sets (80% train, 20% test) using `random_state=42`.
|
|
194
|
+
3. **Model Created**: A `RandomForestClassifier` instance was initialized.
|
|
195
|
+
4. **Model Trained**: The classifier was fitted on the training data (`X_train`, `y_train`).
|
|
196
|
+
5. **Model Evaluated**: The model's accuracy was evaluated on the test set (`X_test`, `y_test`).
|
|
197
|
+
|
|
198
|
+
**Final Test Accuracy: 1.0** (100%)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 3. Verification Assertion
|
|
204
|
+
|
|
205
|
+
The test asserted:
|
|
206
|
+
- **Object Store Verification**: Model `radiant_newt` in `ObjectStore` has 100 decision tree estimators and 3 target classes.
|
|
207
|
+
- **Independent Test Set Score**: Re-running `score(X_test, y_test)` on the store instance yielded `1.0000` (100% test accuracy).
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "integrum"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Convert any Python module or library into an MCP server with FastMCP and stateful word-based object management."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Integrum Team" },
|
|
14
|
+
]
|
|
15
|
+
keywords = ["mcp", "fastmcp", "llm", "tools", "reflection", "scikit-learn"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"fastmcp>=4.0.0",
|
|
28
|
+
"docstring-parser>=0.16",
|
|
29
|
+
"click>=8.1.0",
|
|
30
|
+
"pydantic>=2.0.0",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
test = [
|
|
35
|
+
"pytest>=8.0.0",
|
|
36
|
+
"pytest-asyncio>=0.23.0",
|
|
37
|
+
"scikit-learn>=1.4.0",
|
|
38
|
+
"openai>=1.30.0",
|
|
39
|
+
"python-dotenv>=1.0.0",
|
|
40
|
+
"tenacity>=8.2.0",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.scripts]
|
|
44
|
+
integrum = "integrum.cli:main"
|
|
45
|
+
|
|
46
|
+
[tool.hatch.build.targets.wheel]
|
|
47
|
+
packages = ["src/integrum"]
|
|
48
|
+
|
|
49
|
+
[tool.pytest.ini_options]
|
|
50
|
+
asyncio_mode = "auto"
|
|
51
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""Integrum: Expose any Python module or library as an MCP server."""
|
|
2
|
+
|
|
3
|
+
from integrum.filter import MemberFilter
|
|
4
|
+
from integrum.inspector import import_target, inspect_class, inspect_function, inspect_module
|
|
5
|
+
from integrum.server import IntegrumServer
|
|
6
|
+
from integrum.store import ObjectStore, WordIdGenerator
|
|
7
|
+
|
|
8
|
+
__version__ = "0.1.0"
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"IntegrumServer",
|
|
12
|
+
"ObjectStore",
|
|
13
|
+
"WordIdGenerator",
|
|
14
|
+
"MemberFilter",
|
|
15
|
+
"import_target",
|
|
16
|
+
"inspect_class",
|
|
17
|
+
"inspect_function",
|
|
18
|
+
"inspect_module",
|
|
19
|
+
]
|