Skip to content

Commit edcb134

Browse files
committed
core: pre-commit
1 parent a57586f commit edcb134

File tree

8 files changed

+52
-41
lines changed

8 files changed

+52
-41
lines changed

README.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ This repository provides an **MCPStack tool that wraps the official Python Jupyt
3131

3232
- Upstream project: [datalayer/jupyter-mcp-server](https://github.com/datalayer/jupyter-mcp-server)
3333
- We **reuse their MCP actions** and surface them through **MCPStack**.
34-
- As the upstream evolves, **some actions / endpoints may deprecate**. Our wrapper is intentionally lightweight, so updating to new upstream versions should be straightforward.
34+
- As the upstream evolves, **some actions / endpoints may deprecate**. Our wrapper is intentionally lightweight, so updating to new upstream versions should be straightforward.
3535
If you hit an incompatibility, **please open an issue** and we’ll track an update to align with the Jupyter MCP Server.
3636

3737
### What is MCPStack, in layman’s terms?
3838

39-
The **Model Context Protocol (MCP)** standardises how tools talk to LLMs.
39+
The **Model Context Protocol (MCP)** standardises how tools talk to LLMs.
4040
`MCPStack` lets you **stack multiple MCP tools together** into a pipeline and expose them to an LLM host (e.g., Claude Desktop).
4141

4242
Think **scikit-learn pipelines, but for LLM tooling**:
@@ -96,7 +96,7 @@ uv run jupyter lab \
9696
```
9797

9898
> [!NOTE]
99-
> Docs reference: https://jupyter-mcp-server.datalayer.tech/jupyter/
99+
> Docs reference: https://jupyter-mcp-server.datalayer.tech/jupyter/
100100
101101
Make sure to have a notebook open in Jupyter lab, e.g., `notebook.ipynb` or whatever you have defined in the configuration.
102102

@@ -108,7 +108,7 @@ Use the tool’s CLI to create a small `MCPStack ToolConfig` JSON. **At minimum
108108
uv run mcpstack tools jupyter configure \
109109
--token MY_TOKEN \
110110
--output jupyter_config.json
111-
111+
112112
# MY_TOKEN can for instance be: 1117bf468693444a5608e882ab3b55d511f354a1750df02 (must match the Jupyter server token)
113113
```
114114

@@ -170,7 +170,7 @@ Tokens remain **required** and are enforced upfront by MCPStack when building th
170170

171171
## 📖 Programmatic API
172172

173-
Use the `Jupyter` tool class directly in a pipeline.
173+
Use the `Jupyter` tool class directly in a pipeline.
174174
Tokens are taken from the environment (the pipeline config or your process env):
175175

176176
```python
@@ -195,33 +195,33 @@ pipeline = (
195195

196196
>[!NOTE]
197197
> Common upstream actions you can expose (see `configuration/tools.yaml`):
198-
>
199-
> - `append_markdown_cell`,
200-
> - `insert_markdown_cell`,
201-
> - `overwrite_cell_source`,
198+
>
199+
> - `append_markdown_cell`,
200+
> - `insert_markdown_cell`,
201+
> - `overwrite_cell_source`,
202202
> - `delete_cell`
203-
> - `append_execute_code_cell`,
203+
> - `append_execute_code_cell`,
204204
> - `insert_execute_code_cell`
205-
> - `execute_cell_with_progress`,
206-
> - `execute_cell_simple_timeout`,
205+
> - `execute_cell_with_progress`,
206+
> - `execute_cell_simple_timeout`,
207207
> - `execute_cell_streaming`
208-
> - `read_cell`,
209-
> - `read_all_cells`,
208+
> - `read_cell`,
209+
> - `read_all_cells`,
210210
> - `get_notebook_info`
211211
212212
---
213213

214214
## 🧰 Troubleshooting
215215

216-
- **403 Forbidden / `_xsrf` missing / cannot create kernels**
217-
Ensure you ran Jupyter with a token and that your `ToolConfig` provides **both** `DOCUMENT_TOKEN` and `RUNTIME_TOKEN`.
216+
- **403 Forbidden / `_xsrf` missing / cannot create kernels**
217+
Ensure you ran Jupyter with a token and that your `ToolConfig` provides **both** `DOCUMENT_TOKEN` and `RUNTIME_TOKEN`.
218218
In most setups it’s the same token.
219219

220-
- **404 on `notebook.ipynb`**
220+
- **404 on `notebook.ipynb`**
221221
Update `--document-id` to the actual notebook path relative to Jupyter’s working directory (e.g., `Untitled.ipynb` or `notebooks/analysis.ipynb`).
222222

223-
- **Nothing happens in Lab**
224-
Prefer `http://127.0.0.1:8888` over `http://localhost:8888`.
223+
- **Nothing happens in Lab**
224+
Prefer `http://127.0.0.1:8888` over `http://localhost:8888`.
225225
Confirm your pipeline is running and that the tool is listed in `mcpstack list-tools`.
226226

227227
---
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
from .jupyter import Jupyter
22

3-
__all__ = ["Jupyter"]
3+
__all__ = ["Jupyter"]

src/mcpstack_jupyter/tools/jupyter/cli.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
from rich.table import Table
1313

1414
from mcpstack_jupyter.tools.jupyter.utils.config_loader import (
15-
load_env_defaults,
1615
load_cli_defaults,
16+
load_env_defaults,
1717
load_known_tools,
1818
)
1919

@@ -37,8 +37,12 @@ def get_app(cls) -> typer.Typer:
3737
pretty_exceptions_show_locals=False,
3838
rich_markup_mode="markdown",
3939
)
40-
app.command(help="Configure the Jupyter tool (Token,Provider,Kernel, etc.).")(cls.configure)
41-
app.command(help="Display the current status of the Jupyter tool (Validate with Original Library, etc.")(cls.status)
40+
app.command(help="Configure the Jupyter tool (Token,Provider,Kernel, etc.).")(
41+
cls.configure
42+
)
43+
app.command(
44+
help="Display the current status of the Jupyter tool (Validate with Original Library, etc."
45+
)(cls.status)
4246
return app
4347

4448
@classmethod
@@ -242,4 +246,4 @@ def status(cls, verbose: bool = False) -> None:
242246

243247
except Exception as e:
244248
console.print(f"[red]❌ Error getting status: {e}[/red]")
245-
logger.error("Status failed: %s", e, exc_info=True)
249+
logger.error("Status failed: %s", e, exc_info=True)

src/mcpstack_jupyter/tools/jupyter/configuration/cli_defaults.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ output_filename: "jupyter_config.json"
44
prompts:
55
document_url: "Document URL"
66
document_id: "Notebook path"
7-
runtime_url: "Runtime URL (Enter to reuse Document URL)"
7+
runtime_url: "Runtime URL (Enter to reuse Document URL)"

src/mcpstack_jupyter/tools/jupyter/configuration/env_defaults.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ provider: "jupyter"
33
document_url: "http://127.0.0.1:8888"
44
document_id: "notebook.ipynb"
55
runtime_url: null
6-
require_tokens: true
6+
require_tokens: true

src/mcpstack_jupyter/tools/jupyter/configuration/tools.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ known_tools:
1818
read_only:
1919
- read_cell
2020
- read_all_cells
21-
- get_notebook_info
21+
- get_notebook_info

src/mcpstack_jupyter/tools/jupyter/jupyter.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
import importlib
22
import os
3-
from typing import Any, Dict, List, Optional, Callable
3+
from collections.abc import Callable
4+
from typing import Any, ClassVar
45

56
from beartype import beartype
67
from MCPStack.core.tool.base import BaseTool
7-
from mcpstack_jupyter.tools.jupyter.utils.config_loader import load_env_defaults, load_known_tools
8+
9+
from mcpstack_jupyter.tools.jupyter.utils.config_loader import (
10+
load_env_defaults,
11+
load_known_tools,
12+
)
813

914

1015
@beartype
1116
class Jupyter(BaseTool):
12-
KNOWN_TOOLS: List[str] = []
17+
KNOWN_TOOLS: ClassVar[list[str]] = []
1318

14-
def __init__(self, include: Optional[List[str]] = None) -> None:
19+
def __init__(self, include: list[str] | None = None) -> None:
1520
super().__init__()
1621
self.include = include
1722
self._server = None
18-
self._bound: List[Callable[..., Any]] = []
23+
self._bound: list[Callable[..., Any]] = []
1924

2025
env_cfg = load_env_defaults()
2126
self._env_defaults = env_cfg
@@ -42,14 +47,14 @@ def _teardown(self) -> None:
4247
def _post_load(self) -> None:
4348
pass
4449

45-
def actions(self) -> List[Callable[..., Any]]:
50+
def actions(self) -> list[Callable[..., Any]]:
4651
return list(self._bound)
4752

48-
def to_dict(self) -> Dict[str, Any]:
53+
def to_dict(self) -> dict[str, Any]:
4954
return {"include": self.include}
5055

5156
@classmethod
52-
def from_dict(cls, params: Dict[str, Any]) -> "Jupyter":
57+
def from_dict(cls, params: dict[str, Any]) -> "Jupyter":
5358
return cls(include=params.get("include"))
5459

5560
def _import_and_bind(self) -> None:
@@ -98,4 +103,4 @@ def _import_and_bind(self) -> None:
98103
f"'{name}' not found in jupyter_mcp_server.server. "
99104
"Install a compatible version that provides this tool."
100105
) from e
101-
self._bound.append(fn)
106+
self._bound.append(fn)
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
from __future__ import annotations
22

33
from importlib.resources import files
4-
from typing import Any, Dict, List
4+
from typing import Any
55

66
import yaml
77

88
PKG = "mcpstack_jupyter.tools.jupyter.configuration"
99

10+
1011
def _load_yaml(name: str) -> dict:
1112
with files(PKG).joinpath(name).open("rb") as f:
1213
data = yaml.safe_load(f)
1314
return data or {}
1415

1516

16-
def load_env_defaults() -> Dict[str, Any]:
17+
def load_env_defaults() -> dict[str, Any]:
1718
return _load_yaml("env_defaults.yaml")
1819

19-
def load_cli_defaults() -> Dict[str, Any]:
20+
21+
def load_cli_defaults() -> dict[str, Any]:
2022
return _load_yaml("cli_defaults.yaml")
2123

2224

23-
def load_known_tools() -> Dict[str, List[str]]:
25+
def load_known_tools() -> dict[str, list[str]]:
2426
data = _load_yaml("tools.yaml")
2527
data.setdefault("known_tools", [])
2628
data.setdefault("read_only", [])
27-
return data
29+
return data

0 commit comments

Comments
 (0)