Name | cursor-notebook-mcp JSON |
Version |
0.3.1
JSON |
| download |
home_page | None |
Summary | Model Context Protocol (MCP) implementation for Jupyter notebooks to overcome limitation with Cursor |
upload_time | 2025-07-16 06:33:58 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.10 |
license | Attribution-NonCommercial-ShareAlike 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their terms
and conditions, or any related information. Creative Commons disclaims
all liability for damages resulting from their use to the fullest extent
possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright and
certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are intended for use
by those authorized to give the public permission to use material in
ways otherwise restricted by copyright and certain other rights. Our
licenses are irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it. Licensors
should also secure all rights necessary before applying our licenses so
that the public can reuse the material as expected. Licensors should
clearly mark any material not subject to the license. This includes
other CC-licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public licenses, a
licensor grants the public permission to use the licensed material under
specified terms and conditions. If the licensor's permission is not
necessary for any reason--for example, because of any applicable
exception or limitation to copyright--then that use is not regulated by
the license. Our licenses grant only permissions under copyright and
certain other rights that a licensor has authority to grant. Use of the
licensed material may still be restricted for other reasons, including
because others have copyright or other rights in the material. A
licensor may make special requests, such as asking that all changes be
marked or described. Although not required by our licenses, you are
encouraged to respect those requests where reasonable. More
considerations for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International
Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-NonCommercial-ShareAlike 4.0 International Public License
("Public License"). To the extent this Public License may be interpreted
as a contract, You are granted the Licensed Rights in consideration of
Your acceptance of these terms and conditions, and the Licensor grants
You such rights in consideration of benefits the Licensor receives from
making the Licensed Material available under these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material and
in which the Licensed Material is translated, altered, arranged,
transformed, or otherwise modified in a manner requiring permission
under the Copyright and Similar Rights held by the Licensor. For
purposes of this Public License, where the Licensed Material is a
musical work, performance, or sound recording, Adapted Material is
always produced where the Licensed Material is synched in timed
relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright and
Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. BY-NC-SA Compatible License means a license listed at
creativecommons.org/compatiblelicenses, approved by Creative Commons
as essentially the equivalent of this Public License.
d. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or categorized.
For purposes of this Public License, the rights specified in Section
2(b)(1)-(2) are not Copyright and Similar Rights.
e. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright Treaty
adopted on December 20, 1996, and/or similar international
agreements.
f. Exceptions and Limitations means fair use, fair dealing, and/or any
other exception or limitation to Copyright and Similar Rights that
applies to Your use of the Licensed Material.
g. License Elements means the license attributes listed in the name of a
Creative Commons Public License. The License Elements of this Public
License are Attribution, NonCommercial, and ShareAlike.
h. Licensed Material means the artistic or literary work, database, or
other material to which the Licensor applied this Public License.
i. Licensed Rights means the rights granted to You subject to the terms
and conditions of this Public License, which are limited to all
Copyright and Similar Rights that apply to Your use of the Licensed
Material and that the Licensor has authority to license.
j. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
k. NonCommercial means not primarily intended for or directed towards
commercial advantage or monetary compensation. For purposes of this
Public License, the exchange of the Licensed Material for other
material subject to Copyright and Similar Rights by digital
file-sharing or similar means is NonCommercial provided there is no
payment of monetary compensation in connection with the exchange.
l. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such as
reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the public
may access the material from a place and at a time individually
chosen by them.
m. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
n. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License, the
Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to exercise
the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or in
part, for NonCommercial purposes only; and
b. produce, reproduce, and Share Adapted Material for
NonCommercial purposes only.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public License
does not apply, and You do not need to comply with its terms and
conditions.
3. Term. The term of this Public License is specified in Section 6(a).
4. Media and formats; technical modifications allowed. The Licensor
authorizes You to exercise the Licensed Rights in all media and
formats whether now known or hereafter created, and to make
technical modifications necessary to do so. The Licensor waives
and/or agrees not to assert any right or authority to forbid You
from making technical modifications necessary to exercise the
Licensed Rights, including technical modifications necessary to
circumvent Effective Technological Measures. For purposes of this
Public License, simply making modifications authorized by this
Section 2(a)(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every recipient
of the Licensed Material automatically receives an offer from
the Licensor to exercise the Licensed Rights under the terms
and conditions of this Public License.
b. Additional offer from the Licensor -- Adapted Material. Every
recipient of Adapted Material from You automatically receives
an offer from the Licensor to exercise the Licensed Rights in
the Adapted Material under the conditions of the Adapter's
License You apply.
c. No downstream restrictions. You may not offer or impose any
additional or different terms or conditions on, or apply any
Effective Technological Measures to, the Licensed Material if
doing so restricts exercise of the Licensed Rights by any
recipient of the Licensed Material.
6. No endorsement. Nothing in this Public License constitutes or may
be construed as permission to assert or imply that You are, or
that Your use of the Licensed Material is, connected with, or
sponsored, endorsed, or granted official status by, the Licensor
or others designated to receive attribution as provided in Section
3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not licensed
under this Public License, nor are publicity, privacy, and/or
other similar personality rights; however, to the extent
possible, the Licensor waives and/or agrees not to assert any such
rights held by the Licensor to the limited extent necessary to
allow You to exercise the Licensed Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this Public
License.
3. To the extent possible, the Licensor waives any right to collect
royalties from You for the exercise of the Licensed Rights,
whether directly or through a collecting society under any
voluntary or waivable statutory or compulsory licensing scheme. In
all other cases the Licensor expressly reserves any right to
collect such royalties, including when the Licensed Material is
used other than for NonCommercial purposes.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified form),
You must:
a. retain the following if it is supplied by the Licensor with
the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by the
Licensor (including by pseudonym if designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and retain an
indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this Public
License, and include the text of, or the URI or hyperlink
to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
b. ShareAlike.
In addition to the conditions in Section 3(a), if You Share Adapted
Material You produce, the following conditions also apply.
1. The Adapter's License You apply must be a Creative Commons
license with the same License Elements, this version or later,
or a BY-NC-SA Compatible License.
2. You must include the text of, or the URI or hyperlink to, the
Adapter's License You apply. You may satisfy this condition in
any reasonable manner based on the medium, means, and context
in which You Share Adapted Material.
3. You may not offer or impose any additional or different terms or
conditions on, or apply any Effective Technological Measures to,
Adapted Material that restrict exercise of the rights granted
under the Adapter's License You apply.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that apply
to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to
extract, reuse, reproduce, and Share all or a substantial portion
of the contents of the database for NonCommercial purposes only;
b. if You include all or a substantial portion of the database contents
in a database in which You have Sui Generis Database Rights, then
the database in which You have Sui Generis Database Rights (but not
its individual contents) is Adapted Material, including for
purposes of Section 3(b); and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, IMPLIED,
STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, WARRANTIES
OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR
THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT KNOWN OR
DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT ALLOWED IN FULL
OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO
YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE)
OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL,
CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS,
EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR USE OF THE
LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. WHERE A
LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR IN PART, THIS
LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and Similar
Rights licensed here. However, if You fail to comply with this
Public License, then Your rights under this Public License terminate
automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided it
is cured within 30 days of Your discovery of the violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations of
this Public License.
c. For the avoidance of doubt, the Licensor may also offer the Licensed
Material under separate terms or conditions or stop distributing the
Licensed Material at any time; however, doing so will not terminate
this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different terms
or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and shall
not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted as
a limitation upon, or waiver of, any privileges and immunities that
apply to the Licensor or You, including from the legal processes of
any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public licenses.
Notwithstanding, Creative Commons may elect to apply one of its public
licenses to material it publishes and in those instances will be
considered the "Licensor." The text of the Creative Commons public
licenses is dedicated to the public domain under the CC0 Public Domain
Dedication. Except for the limited purpose of indicating that material
is shared under a Creative Commons public license or as otherwise
permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including, without
limitation, in connection with any unauthorized modifications to any of
its public licenses or any other arrangements, understandings, or
agreements concerning use of licensed material. For the avoidance of
doubt, this paragraph does not form part of the public licenses.
Creative Commons may be contacted at creativecommons.org. |
keywords |
agent
ai
cursor
ipynb
jupyter
mcp
nbformat
notebook
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
[](https://pypi.org/project/cursor-notebook-mcp/) [](https://pypi.org/project/cursor-notebook-mcp/) [](https://pepy.tech/project/cursor-notebook-mcp) [](https://creativecommons.org/licenses/by-nc-sa/4.0/) [](https://pypi.org/project/cursor-notebook-mcp/) [](https://github.com/jbeno/cursor-notebook-mcp/issues) [](https://github.com/jbeno/cursor-notebook-mcp) [](https://coveralls.io/github/jbeno/cursor-notebook-mcp?branch=main)  
# Jupyter Notebook MCP Server (for Cursor)
This directory contains a Model Context Protocol (MCP) server designed to allow AI agents **within Cursor** to interact with Jupyter Notebook (`.ipynb`) files. It was created to overcome a limitation with Cursor. As of version 0.50.5, in Agent mode, the model could not edit notebooks or notebook cells in response to dialog in the AI chat pane. This provides the agent with a suite of MCP tools that allow direct notebook cell manipulation.
Although designed to overcome a limitation with Cursor, this MCP server does not have anything specific to Cursor other than the configuration instructions. You could easily configure this for use with VS Code (Insiders) or Claude Code or any model/agent that can take advantage of MCP. Note that VS Code (Insiders) has pretty good Jupyter Notebook support now.
This MCP server uses the `nbformat` library to safely manipulate notebook structures and enforces security by restricting operations to user-defined directories. It also uses `nbconvert` to enable exporting notebooks to various formats like Python scripts, HTML, and more. The server handles all notebook operations through a clean API that maintains notebook integrity and prevents malformed changes.
## Latest Version
**Current Version:** `0.3.1` - See the [CHANGELOG.md](CHANGELOG.md) for details on recent changes. Key additions include SFTP support, Streamable HTTP transport, and new tools like `notebook_edit_cell_output`, `notebook_bulk_add_cells`, and `notebook_get_server_path_context` to improve notebook editing and path handling.
## Video Walkthrough
### [Notebook MCP Server 0.3.0 Update](https://youtu.be/R3TGyuej-IM) (YouTube)
[](https://youtu.be/R3TGyuej-IM)
* Updates in the **0.3.0 release**, overview of new tools
* FastMCP upgrade with **streamable HTTP transport**
* **SFTP support** for editing Jupyter notebooks on remote SSH servers,
* Issue resolution (#2, #4, #5) plus known issues (#1, #3)
### [Overview of Notebook MCP Server](https://youtu.be/VOVMH-tle14) (YouTube)
[](https://youtu.be/VOVMH-tle14)
- The current **limitations** of editing notebooks directly in Cursor.
- **Installing** and **configuring** the Notebook MCP Server.
- **Creating a notebook** from scratch (example shown: Singular Value Decomposition tutorial in less than 2 minutes).
- Demonstrating various **editing tools** (edit, split, duplicate cells).
- Reading notebook **metadata**.
- **Exporting** notebooks to python
## Features
Exposes the following MCP tools (registered under the `notebook_mcp` server):
* `notebook_create`: Creates a new, empty notebook file.
* `notebook_delete`: Deletes an existing notebook file.
* `notebook_rename`: Renames/moves a notebook file from one path to another.
* `notebook_read`: Reads an entire notebook and returns its structure as a dictionary.
* `notebook_read_cell`: Reads the source content of a specific cell.
* `notebook_add_cell`: Adds a new code or markdown cell after a specified index.
* `notebook_edit_cell`: Replaces the source content of a specific cell.
* `notebook_delete_cell`: Deletes a specific cell.
* `notebook_change_cell_type`: Changes a cell's type (code, markdown, or raw).
* `notebook_duplicate_cell`: Duplicates a cell multiple times (default: once).
* `notebook_get_cell_count`: Returns the total number of cells.
* `notebook_read_metadata`: Reads the top-level notebook metadata.
* `notebook_edit_metadata`: Updates the top-level notebook metadata.
* `notebook_read_cell_metadata`: Reads the metadata of a specific cell.
* `notebook_read_cell_output`: Reads the output list of a specific code cell.
* `notebook_edit_cell_metadata`: Updates the metadata of a specific cell.
* `notebook_clear_cell_outputs`: Clears the outputs and execution count of a specific cell.
* `notebook_clear_all_outputs`: Clears outputs and execution counts for all code cells.
* `notebook_move_cell`: Moves a cell to a different position.
* `notebook_split_cell`: Splits a cell into two at a specified line number.
* `notebook_merge_cells`: Merges a cell with the cell immediately following it.
* `notebook_validate`: Validates the notebook structure against the `nbformat` schema.
* `notebook_get_info`: Retrieves general information (cell count, metadata, kernel, language info).
* `notebook_export`: Exports the notebook to another format (e.g., python, html) using nbconvert. **Note:** See External Dependencies below for requirements needed for certain export formats like PDF.
* `notebook_get_outline`: Produces an outline showing cell numbers with major headings/functions and line counts to make it easier for the agent to navigate a large notebook.
* `notebook_search`: Searches cells for a keyword, showing which cell matches were found with contextual snippets. This helps the agent know which cell to read/edit when asked to modify something.
* `notebook_edit_cell_output`: Allows direct manipulation and setting of cell outputs.
* `notebook_bulk_add_cells`: Adds multiple cells to a notebook in a single operation.
* `notebook_get_server_path_context`: Provides detailed server path configuration (allowed_roots, OS path style, SFTP status, project directory validation, and path construction guidance).
## Requirements
This project has both Python package dependencies and potentially external system dependencies for full functionality.
### Python Dependencies
* **Python Version:** 3.10+
* **Core:** `mcp>=0.1.0`, `nbformat>=5.0`, `nbconvert>=6.0`, `ipython`, `jupyter_core`, `paramiko>=2.8.0`, `fastmcp>=2.7.0,<2.11`, `uvicorn>=0.20.0`, `starlette>=0.25.0`. These are installed automatically when you install `cursor-notebook-mcp` and provide support for all transport modes (stdio, Streamable HTTP, SSE).
* **Optional - Development/Testing:** `pytest>=7.0`, `pytest-asyncio>=0.18`, `pytest-cov`, `pytest-timeout>=2.0.0`, `coveralls`. Install via `pip install -e ".[dev]"` from source checkout.
### External System Dependencies (Optional)
These are **not** Python packages and must be installed separately on your system for certain features to work:
* **Pandoc:** Required by `nbconvert` for many non-HTML export formats (including the intermediate steps for PDF). See [Pandoc installation instructions](https://pandoc.org/installing.html).
* **LaTeX (XeLaTeX recommended):** Required by `nbconvert` for exporting notebooks directly to PDF (`--to pdf` option used by `notebook_export` with `export_format="pdf"`). See [Installing TeX](https://nbconvert.readthedocs.io/en/latest/install.html#installing-tex).
If these external dependencies are missing, the `notebook_export` tool may fail when attempting to export to formats that rely on them (like PDF). Be sure to install them if you plan to use these features.
## Installation
### From PyPI
The standard installation command will install all necessary dependencies to support stdio, Streamable HTTP, and SSE transport modes.
* **Using pip:**
```bash
pip install cursor-notebook-mcp
```
* **Using uv:**
```bash
uv pip install cursor-notebook-mcp
```
### Development Installation (From Source)
1. Clone this repository:
```bash
git clone https://github.com/jbeno/cursor-notebook-mcp.git # Or your fork
cd cursor-notebook-mcp
```
2. Create and activate a virtual environment (recommended):
```bash
# Using Python's venv
python -m venv .venv
source .venv/bin/activate # On Windows use `.venv\Scripts\activate`
# Or using uv (if installed)
# uv venv
# source .venv/bin/activate # On Windows use `.venv\Scripts\activate`
```
3. Install in editable mode with all optional dependencies:
* **Using pip:**
```bash
# Installs the package in editable mode along with test dependencies.
pip install -e ".[dev]"
# To install in editable mode without extra test dependencies:
# pip install -e .
```
* **Using uv:**
```bash
# Installs the package in editable mode along with test dependencies.
uv pip install -e ".[dev]"
# To install in editable mode without extra test dependencies:
# uv pip install -e .
```
## Server Configuration and Cursor Integration
This section details how to run the `cursor-notebook-mcp` server and configure Cursor to use it, depending on the chosen transport protocol.
### 1. Streamable HTTP Transport (Recommended)
With Streamable HTTP, you run the server process manually, and Cursor connects to it over the network. This is the recommended method for most setups involving Cursor.
#### A. Running the Server (Manual Start Required)
First, ensure the package is installed (e.g., `pip install cursor-notebook-mcp` or `uv pip install cursor-notebook-mcp`) and your virtual environment is active if running from source.
* **Using the installed script:**
```bash
cursor-notebook-mcp --transport streamable-http --allow-root /path/to/your/notebooks --host 127.0.0.1 --port 8080
```
* **Running from a source checkout (ensure dependencies are installed, e.g., `pip install -e .` or `uv pip install -e .`, or with `.[dev]` if you need test tools too):**
```bash
python -m cursor_notebook_mcp.server --transport streamable-http --allow-root /path/to/your/notebooks --host 127.0.0.1 --port 8080
```
Remember to replace `/path/to/your/notebooks` with the actual path to the directory you want the server to access.
#### B. Cursor `mcp.json` Configuration
Go to Cursor Settings > MCP > Add new global MCP server. Or create or update your `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project-specific) file:
```json
{
"mcpServers": {
"notebook_mcp": {
"url": "http://127.0.0.1:8080/mcp"
}
}
}
```
*Note: Adjust the `host`, `port`, and path (`/mcp` is the default for `FastMCP`'s streamable HTTP). The server must be running before Cursor attempts to connect.*
### 2. SSE Transport (Legacy Web/Network)
SSE is now considered a legacy transport, but it's still supported. Streamable HTTP is preferred for new setups. With SSE, you also run the server process manually.
#### A. Running the Server (Manual Start Required)
Ensure the package is installed (e.g., `pip install cursor-notebook-mcp` or `uv pip install cursor-notebook-mcp`) and your virtual environment is active if running from source.
* **Using the installed script:**
```bash
cursor-notebook-mcp --transport sse --allow-root /path/to/your/notebooks --host 127.0.0.1 --port 8080
```
* **Running from a source checkout:**
```bash
python -m cursor_notebook_mcp.server --transport sse --allow-root /path/to/your/notebooks --host 127.0.0.1 --port 8080
```
#### B. Cursor `mcp.json` Configuration
Go to Cursor Settings > MCP > Add new global MCP server. Or create or update your `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project-specific) file:
```json
{
"mcpServers": {
"notebook_mcp": {
"url": "http://127.0.0.1:8081/sse"
}
}
}
```
*Note: `FastMCP`'s `sse` transport uses `/sse` for the handshake. The server must be running before Cursor attempts to connect.*
### 3. stdio Transport
With `stdio` transport, Cursor launches and manages the server process directly. You do not run the server manually in your terminal for Cursor integration. Cursor communicates with it via standard input/output.
This method requires telling Cursor the command and arguments to start the server. **Care must be taken to ensure Cursor uses the correct Python environment where `cursor-notebook-mcp` and its dependencies are installed.**
#### Option 1: Using absolute paths to a specific virtual environment (Traditional `venv` / `virtualenv`)
This is reliable if you have a dedicated venv for the tool.
* If `cursor-notebook-mcp` script is in the venv's `bin`:
```json
{
"mcpServers": {
"notebook_mcp": {
"command": "/absolute/path/to/venv/bin/cursor-notebook-mcp",
"args": [
"--allow-root", "/absolute/path/to/your/notebooks"
]
}
}
}
```
* Using the venv's Python to run the module:
```json
{
"mcpServers": {
"notebook_mcp": {
"command": "/absolute/path/to/venv/bin/python",
"args": [
"-m", "cursor_notebook_mcp.server",
"--allow-root", "/absolute/path/to/your/notebooks"
]
}
}
}
```
Replace `/absolute/path/to/venv/...` and `/absolute/path/to/your/notebooks` accordingly. Remember you can add other `cursor-notebook-mcp` arguments (like `--log-level DEBUG`) to the `args` list as needed.
#### Option 2: Using `uv` to run from a specific project's virtual environment (Recommended for projects managed with `uv`)
This method uses `uv` to execute `cursor-notebook-mcp` within a designated project's Python environment. It's robust as it explicitly defines the project context for `uv`.
Ensure `uv` is installed. You might need to provide the full path to the `uv` executable in the `command` field (e.g., run `which uv` on macOS/Linux or `where uv` on Windows to find it). The project directory specified for `uv --directory` should be the root of your project where `uv` manages an environment (e.g., where a `.venv` was created by `uv venv` and `cursor-notebook-mcp` is installed).
The following examples can be used for `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project-specific).
* If `cursor-notebook-mcp` is an installed script in the `uv` environment:
```json
{
"mcpServers": {
"notebook_mcp": {
"command": "uv",
"args": [
"--directory", "/absolute/path/to/your/project/with/uv/venv",
"run", "--",
"cursor-notebook-mcp",
"--allow-root", "/absolute/path/to/your/notebooks"
]
}
}
}
```
* Using `uv run` with `python -m ...`:
```json
{
"mcpServers": {
"notebook_mcp": {
"command": "uv",
"args": [
"--directory", "/absolute/path/to/your/project/with/uv/venv",
"run", "--",
"python", "-m", "cursor_notebook_mcp.server",
"--allow-root", "/absolute/path/to/your/notebooks"
]
}
}
}
```
*Note: For these `uv` examples, `/absolute/path/to/your/project/with/uv/venv` must be the correct absolute path to your project where `cursor-notebook-mcp` is installed within its `uv`-managed environment. The `--allow-root` path for notebooks should also be an absolute path for clarity and reliability. You can add other `cursor-notebook-mcp` arguments (like `--log-level DEBUG` or `--port 8889`) to the end of the `args` list for `cursor-notebook-mcp` or `python -m cursor_notebook_mcp.server` as needed.*
## Cursor Rules for AI Guidance
The package includes a `cursor_rules.md` file that helps calibrate the agent's behavior when working with Jupyter notebooks through the MCP server. These rules ensure consistent and clean notebook actions by providing guidelines for markdown formatting, tool usage, path resolution, and more.
### Default Behavior: Visibility and Feedback
By default, the rules are optimized for visibility into the AI's actions as it constructs or modifies notebooks. The AI will tend to use individual tool calls for operations like adding cells, which means you can see the notebook being built cell by cell. This provides good feedback and allows you to intervene quickly if needed. However, this approach results in more tool calls, which can impact costs when using paid AI services.
### Configuring Rules in Cursor
To use the cursor rules:
1. Open Cursor
2. Go to Cursor > Settings > Cursor Settings
3. Click on "Rules" in the sidebar
4. You can either:
* Click "Add new rule" under "Project Rules" to apply the rules only to the current project
* Add to "User Rules" to apply them globally
### Optional: Cost-Efficient Mode
If you're more concerned about cost-effectiveness and don't mind waiting to see results, you can add the following section to the rules:
```markdown
8. **Efficiency Mode (Cost Optimization):**
* Minimize tool calls as they incur API costs.
* Use `notebook_bulk_add_cells` instead of multiple `notebook_add_cell` calls when adding multiple cells.
* Use `notebook_read` to get the full notebook state instead of reading individual cells.
* Only use `notebook_read_cell` when you need to verify a specific cell's content.
* Batch related changes together when possible.
* Skip verification reads if the operation is simple and unlikely to fail.
```
## Editing Remote Notebooks via SFTP/SSH
This server supports accessing and editing Jupyter notebooks stored on remote servers via SFTP (SSH File Transfer Protocol). This allows you to work on notebooks as if they were local, provided you have SSH access to the remote machine and SFTP is enabled on it.
### How it Works
The server uses the `paramiko` library to establish an SSH connection and then an SFTP session. When you specify one or more `--sftp-root` arguments, the server maps these remote locations to internal paths. All notebook operations (reading, writing, listing, etc.) on paths under these remote roots are then transparently handled over SFTP.
### Prerequisites
* **SFTP Enabled on Remote Server:** The SSH server on the remote machine must have the SFTP subsystem enabled. This is standard on most Linux/macOS SSH servers.
* **SSH Access:** You need valid credentials (username, password, and/or SSH key) for the remote server.
* **`paramiko` Dependency:** The `cursor-notebook-mcp` package includes `paramiko` as a core dependency, so no extra installation for this is typically needed.
### Important Note on Transports and Authentication
For SFTP connections that require interactive authentication (e.g., password prompts, 2-Factor Authentication (2FA)/Multi-Factor Authentication (MFA) codes, SSH key passphrases), you **must** run the `cursor-notebook-mcp` server manually using a network transport like `streamable-http` (recommended) or `sse`.
This is because these prompts occur when the server starts and tries to establish the SFTP connection. If using `stdio` transport (where Cursor launches the server in the background), there is no way for you to interact with these prompts, and the connection will likely fail.
When you run the server manually in your terminal with a network transport, you will be prompted directly in that terminal for any required passwords, passphrases, or 2FA codes.
### SFTP Command-Line Arguments
To configure SFTP access, you use the following command-line arguments when starting the server:
* `--sftp-root user@host:/path/to/remote/notebooks`
* Specifies a remote notebook directory. Format is `username@hostname:/absolute/path/on/server`.
* This argument can be used multiple times to map several distinct remote locations.
* Tilde expansion (`~`) is supported for the path (e.g., `user@host:~/notebooks`).
* `--sftp-password your_password_or_passphrase`
* (Optional) Provides the password for SSH password authentication or the passphrase for an encrypted SSH private key.
* **Security Note:** Supplying credentials directly on the command line can be a security risk (e.g., exposure in shell history or process lists). It is generally more secure to omit this argument and rely on interactive prompts when the server starts, or use SSH agent / key-based authentication without passphrases where possible.
* `--sftp-key /path/to/your/private_key`
* Specifies the path to your SSH private key file (e.g., `~/.ssh/id_rsa`).
* `--sftp-port port_number`
* SSH port for SFTP connections. Defaults to `22`.
* `--sftp-auth-mode mode`:
* Authentication mode for SFTP (e.g., `auto`, `key`, `password`, `key+interactive`). Defaults to `auto`.
* `--sftp-no-agent`:
* Disables using an SSH agent for SFTP authentication.
* `--sftp-no-interactive`:
* Disables all interactive SFTP authentication prompts.
* `--sftp-no-password-prompt`:
* Skips password/passphrase prompt if not provided via `--sftp-password`, but allows other interactive prompts (e.g., 2FA codes).
### SFTP Configuration Examples
Below are examples of how to start the `cursor-notebook-mcp` server with various SFTP authentication methods. Remember to use a network transport like `streamable-http`.
#### 1. Password Authentication
* **Interactively prompted for password:**
```bash
cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \
--sftp-root myuser@remote.example.com:/home/myuser/notebooks \
--sftp-auth-mode password
```
*(You will be prompted for `myuser`'s password when the server starts.)*
* **Password provided via argument (less secure):**
```bash
cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \
--sftp-root myuser@remote.example.com:/home/myuser/notebooks \
--sftp-password "MySecretP@ssw0rd" \
--sftp-auth-mode password
```
#### 2. SSH Key Authentication
* **Key without passphrase (e.g., `~/.ssh/id_rsa`):**
```bash
cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \
--sftp-root myuser@remote.example.com:~/project_notebooks \
--sftp-key ~/.ssh/id_rsa \
--sftp-auth-mode key
```
* **Key with passphrase (interactively prompted):**
```bash
cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \
--sftp-root myuser@remote.example.com:/srv/notebooks \
--sftp-key ~/.ssh/encrypted_key \
--sftp-auth-mode key
```
*(You will be prompted for the passphrase for `encrypted_key`.)*
* **Key with passphrase (provided via argument):**
```bash
cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \
--sftp-root myuser@remote.example.com:/data/notebooks \
--sftp-key ~/.ssh/encrypted_key \
--sftp-password "MyPrivateKeyPassphrase" \
--sftp-auth-mode key
```
#### 3. Keyboard-Interactive Authentication (e.g., 2FA/MFA)
* **Server prompts for username/password and/or 2FA code:**
```bash
cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \
--sftp-root myuser@remote.example.com:~/notebooks \
--sftp-auth-mode interactive
```
#### 4. Combined: SSH Key (passphrase-protected) + Keyboard-Interactive (2FA/MFA)
This scenario is for when your SSH key is encrypted with a passphrase, and the server also requires a second factor (e.g., a TOTP code) via keyboard-interactive authentication.
```bash
cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \
--sftp-root myuser@remote.example.com:~/notebooks \
--sftp-key ~/.ssh/your_encrypted_rsa_key \
--sftp-auth-mode key+interactive
```
*(When the server starts, you should be prompted first for the passphrase for `your_encrypted_rsa_key`. After successfully entering it, if the server requires further interactive authentication, you will then be prompted for your 2FA code or other interactive inputs.)*
#### 5. Combined: Password + Keyboard-Interactive (e.g., Password then 2FA Code)
```bash
cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \
--sftp-root myuser@remote.example.com:~/notebooks \
--sftp-auth-mode password+interactive
```
*(Prompts for password, then prompts for 2FA code if required by the server.)*
#### 6. Using SSH Agent
By default (`--sftp-auth-mode auto` or `key`), the server will try to use a running SSH agent. If your key is loaded in the agent, you might not need to specify `--sftp-key` or `--sftp-password` for the key passphrase.
* **Agent with 2FA (keyboard-interactive for 2FA code only):**
```bash
cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \
--sftp-root myuser@remote.example.com:~/notebooks \
--sftp-auth-mode auto # Or key+interactive if you want to be explicit
# Optional: --sftp-no-password-prompt if agent handles key, but 2FA prompt is separate
```
*(Assumes key is in agent. Will prompt for 2FA if server requires it after key auth.)*
### Multiple Remote Roots
You can specify `--sftp-root` multiple times to connect to different paths, even on different servers if they use compatible authentication methods (or if you provide specific credentials for each if the server supported per-root credential arguments, which it currently does not - all connections will try the same global credentials like password/key file if provided).
```bash
cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \
--sftp-root user1@serverA.com:/projects/alpha \
--sftp-root user1@serverA.com:~/personal_notebooks \
--sftp-key ~/.ssh/id_serverA \
--sftp-auth-mode key
```
### Path Handling
* **Tilde Expansion:** Remote paths like `~/my_notebooks` in `--sftp-root` will be expanded to the user's home directory on the remote server.
* **Internal Mapping:** The server maps these remote SFTP paths to temporary local-like representations for its internal operations. You, as the user in Cursor, will interact with them using their original remote-style paths (e.g., `myuser@remote.example.com:/home/myuser/notebooks/MyNotebook.ipynb`).
* **Understanding Context with `notebook_get_server_path_context`:** For AI agents interacting with the server, the `notebook_get_server_path_context` tool is particularly useful. It provides details about all configured roots (local and SFTP), the server's OS path style, and guidance on how paths are constructed and resolved. This helps the AI understand how a given SFTP path relates to the user's current project directory (if local) and correctly interpret user instructions that might involve mixed local or remote path references.
Once the server is running with SFTP roots configured, you can use the `notebook_mcp` tools in Cursor to interact with notebooks under these remote paths just as you would with local notebooks, provided they are within an `--allow-root` (for local files) or a configured `--sftp-root`.
## Logging
The server logs its operations to help with troubleshooting and monitoring.
* **Default Log Location:** By default, log files are stored in `~/.cursor_notebook_mcp/server.log` (the `.cursor_notebook_mcp` directory is created in your user's home directory).
* **Custom Log Directory:** You can specify a different directory for log files using the `--log-dir` command-line argument. For example: `cursor-notebook-mcp --allow-root /path/to/notebooks --log-dir /custom/log/path`
* **Log Level:** The verbosity of the logs can be controlled with the `--log-level` argument. By default, the log level is set to `INFO`. Other available levels are `DEBUG`, `WARNING`, `ERROR`, and `CRITICAL`. Setting the level to `DEBUG` is particularly useful for development or deep troubleshooting as it will show extensive output, including full stack traces for all exceptions (even those that are handled by the server).
## Command-Line Arguments
The server accepts the following command-line arguments:
* `--allow-root`: (Required if no `--sftp-root` is provided, can use multiple times) Absolute path to a directory where local notebooks are allowed.
* `--log-dir`: Directory to store log files. Defaults to `~/.cursor_notebook_mcp`.
* `--log-level`: Set the logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`. Defaults to `INFO`.
* `--max-cell-source-size`: Maximum allowed size in bytes for cell source content. Defaults to 10 MiB.
* `--max-cell-output-size`: Maximum allowed size in bytes for cell output content. Defaults to 10 MiB.
* `--transport`: Transport type to use: `stdio`, `streamable-http`, or `sse`. Defaults to `stdio`. `streamable-http` is recommended for web; `sse` is a deprecated alternative.
* `--host`: Host to bind the Streamable HTTP or SSE server to. Only used with `--transport=streamable-http` or `--transport=sse`. Defaults to `127.0.0.1`.
* `--port`: Port to bind the Streamable HTTP or SSE server to. Only used with `--transport=streamable-http` or `--transport=sse`. Defaults to `8080`.
* `--sftp-root user@host:/path/to/remote/notebooks`:
* Specifies a remote notebook directory via SFTP. Can be used multiple times.
* See the "Editing Remote Notebooks via SFTP/SSH" section for detailed usage and authentication.
* `--sftp-password your_password_or_passphrase`:
* (Optional and not recommended for security) Provides the password for SSH authentication or the passphrase for an encrypted SSH private key. It is generally more secure to omit this and enter credentials via interactive prompt if needed.
* `--sftp-key /path/to/your/private_key`:
* Path to your SSH private key file for SFTP authentication.
* `--sftp-port port_number`:
* SSH port for SFTP connections. Defaults to `22`.
* `--sftp-auth-mode mode`:
* Authentication mode for SFTP (e.g., `auto`, `key`, `password`, `key+interactive`). Defaults to `auto`.
* `--sftp-no-agent`:
* Disables using an SSH agent for SFTP authentication.
* `--sftp-no-interactive`:
* Disables all interactive SFTP authentication prompts.
* `--sftp-no-password-prompt`:
* Skips password/passphrase prompt if not provided via `--sftp-password`, but allows other interactive prompts (e.g., 2FA codes).
## Security
* **Workspace Root Enforcement:** The server requires the `--allow-root` command-line argument during startup. It will refuse to operate on any notebook file located outside the directories specified by these arguments. This is a critical security boundary.
* **Path Handling:** The server uses `os.path.realpath` to resolve paths and checks against the allowed roots before any read or write operation.
* **SFTP Authentication Security:** When connecting to remote notebooks via SFTP, it is highly recommended to use network transports (`streamable-http` or `sse`). This allows the server to interactively prompt you for credentials such as passwords, SSH key passphrases, or 2-Factor Authentication (2FA) codes directly in your terminal. This method is more secure than providing sensitive information via command-line arguments (e.g., `--sftp-password`), as it avoids exposing credentials in your shell history or system process lists. The server supports various authentication flows, including multi-factor combinations like certificate + 2FA or password + 2FA, by leveraging these interactive prompts.
* **Input Validation:** Basic checks for `.ipynb` extension are performed.
* **Cell Source Size Limit:** The server enforces a maximum size limit (configurable via `--max-cell-source-size`, default 10 MiB) on the source content provided to `notebook_edit_cell` and `notebook_add_cell` to prevent excessive memory usage.
* **Cell Output Size Limit:** The server enforces a maximum size limit (configurable via `--max-cell-output-size`, default 10 MiB) on the total serialized size of outputs returned by `notebook_read_cell_output`.
## Limitations
* **No Cell Execution:** This server cannot execute notebook cells. It operates solely on the `.ipynb` file structure using the `nbformat` library and does not interact with Jupyter kernels. Cell execution must be performed manually by the user within the Cursor UI (selecting the desired kernel and running the cell).
## Issues
If you encounter any bugs, have feature requests, or other issues, please check the existing issues or submit a new one on our GitHub issue tracker.
### Known Issues
Check the [GitHub Issues tab](https://github.com/jbeno/cursor-notebook-mcp/issues) for a list of currently known issues.
* **UI Refresh Issues:** Occasionally, some notebook operations (like cell splitting or merging) may succeed at the file level, but the Cursor UI might not show the updated content correctly. In such situations, you can:
* Close and re-open the notebook file
* Save the file, which might prompt to "Revert" or "Overwrite" - select "Revert" to reload the actual file content
* **No Checkpoint Support:** When the agent makes edits using third-party MCP tools, it does not register a checkpoint in the AI chat history with a "Restore Checkpoint" button. To mitigate against this:
* Use git to frequently commit and allow for rollback
* Create manual copies of your work at key milestones
* **No File/Line Context:** Cursor does not share the Jupyter notebook context automatically as it does with other files. In other files (Python, Markdown) it shares the current file and line number with the AI agent. However, for notebooks, it does not share any context. Ideally it would share the cell and the line number within that cell. To work around this:
* When you know, try to be explicit about which cell, function or section you want to edit
* The agent can use `notebook_get_outline` to get a rough outline of the notebook. This will help it identify which cells have key classes, functions or markdown headings.
* The agent can use `notebook_search` to determine which cells contain keywords, classes, or functions.
### Submitting an Issue
To submit a new issue:
1. Visit the [jbeno/cursor-notebook-mcp Issues page](https://github.com/jbeno/cursor-notebook-mcp/issues).
2. Click on "New Issue".
3. Provide:
* A clear description of the problem or feature request.
* Steps to reproduce the issue (if applicable).
* Expected vs. actual behavior.
* Your environment details (OS, Python version, `cursor-notebook-mcp` version, etc.).
* Any relevant error messages or logs.
* Which model and client/version you're using (if relevant to an AI interaction).
## Contributions
Contributions to improve the Jupyter Notebook MCP Server are welcome!
If you'd like to contribute, please fork the repository, create a branch for your changes, and then open a Pull Request (PR) to the `main` branch of `jbeno/cursor-notebook-mcp`.
Ensure your changes include:
* Relevant unit tests for new functionality.
* Updates to documentation (`README.md`, `CHANGELOG.md`) if your changes affect usage or add features.
* Adherence to the existing code style.
Please ensure all tests pass by running the test scripts (`./run_tests.sh` or `.\run_tests.ps1`) before submitting your PR.
**Discussion for Major Changes:** For significant changes or new features, it's a good idea to open an issue first to discuss your proposed changes and ensure they align with the project's goals.
### Development Environment Setup
First, clone the repository and set up a virtual environment. Then install the package in editable mode with all development and testing dependencies:
* **Using pip:**
```bash
# From the project root directory
python -m venv .venv
source .venv/bin/activate # On Windows use: .venv\Scripts\activate
pip install -e ".[dev]"
```
* **Using uv:**
```bash
# From the project root directory
uv venv
source .venv/bin/activate # On Windows use: .venv\Scripts\activate
uv pip install -e ".[dev]"
```
### Running Unit Tests
The project uses `pytest` for unit testing. Test files are located in the `tests/` directory. When adding new tests, please place them in this directory, following the existing naming conventions (e.g., `test_*.py`).
To run the tests, use the provided wrapper scripts. These scripts run test files individually, which helps prevent potential hanging issues that can sometimes occur when running `pytest` directly across all test files in this project, especially with asynchronous operations or SFTP tests.
* **On Linux/macOS:** Use the wrapper script to ensure environment variables are set correctly.
```bash
./run_tests.sh
# To run specific tests:
# ./run_tests.sh tests/test_notebook_tools.py
```
* **On Windows:** Use the PowerShell wrapper script.
```bash
.\run_tests.ps1
# To run specific tests:
# .\run_tests.ps1 tests/test_notebook_tools.py
```
### Code Coverage
Code coverage is automatically calculated when running tests via the wrapper scripts (`run_tests.sh` or `run_tests.ps1`), using `pytest-cov`.
Detailed coverage reports are available on Coveralls. You can view the current coverage status via the badge at the top of this README or directly at [https://coveralls.io/github/jbeno/cursor-notebook-mcp?branch=main](https://coveralls.io/github/jbeno/cursor-notebook-mcp?branch=main).
### AI-Driven Test Plan (`test_plan.md`)
In addition to the automated unit tests, the repository includes a `test_plan.md` file. This document outlines a series of scenario-based tests designed for execution by an AI agent, such as Cursor in Agent Mode or a similar conversational AI with access to the `notebook_mcp` tools.
To use it, you can instruct your AI agent to "execute the test plan found in `test_plan.md`." The plan covers a wide range of notebook operations, from basic editing to SFTP access and metadata changes, helping to verify the practical usability and correctness of the tools in realistic, multi-step workflows. The test plan has instructions that account for different operating systems (macOS/Linux or Windows).
## License
This project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
See the [LICENSE](LICENSE) file for details.
Copyright © 2025 Jim Beno
This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
<img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" />
</a>
## Author
This project was created and is maintained by Jim Beno - jim@jimbeno.net
Raw data
{
"_id": null,
"home_page": null,
"name": "cursor-notebook-mcp",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "agent, ai, cursor, ipynb, jupyter, mcp, nbformat, notebook",
"author": null,
"author_email": "Jim Beno <jim@jimbeno.net>",
"download_url": "https://files.pythonhosted.org/packages/ec/57/7da5ad7967ec663331348ff3551b79c462769351c886464a1a487c4c4b08/cursor_notebook_mcp-0.3.1.tar.gz",
"platform": null,
"description": "[](https://pypi.org/project/cursor-notebook-mcp/) [](https://pypi.org/project/cursor-notebook-mcp/) [](https://pepy.tech/project/cursor-notebook-mcp) [](https://creativecommons.org/licenses/by-nc-sa/4.0/) [](https://pypi.org/project/cursor-notebook-mcp/) [](https://github.com/jbeno/cursor-notebook-mcp/issues) [](https://github.com/jbeno/cursor-notebook-mcp) [](https://coveralls.io/github/jbeno/cursor-notebook-mcp?branch=main)  \n\n# Jupyter Notebook MCP Server (for Cursor)\n\nThis directory contains a Model Context Protocol (MCP) server designed to allow AI agents **within Cursor** to interact with Jupyter Notebook (`.ipynb`) files. It was created to overcome a limitation with Cursor. As of version 0.50.5, in Agent mode, the model could not edit notebooks or notebook cells in response to dialog in the AI chat pane. This provides the agent with a suite of MCP tools that allow direct notebook cell manipulation.\n\nAlthough designed to overcome a limitation with Cursor, this MCP server does not have anything specific to Cursor other than the configuration instructions. You could easily configure this for use with VS Code (Insiders) or Claude Code or any model/agent that can take advantage of MCP. Note that VS Code (Insiders) has pretty good Jupyter Notebook support now.\n\nThis MCP server uses the `nbformat` library to safely manipulate notebook structures and enforces security by restricting operations to user-defined directories. It also uses `nbconvert` to enable exporting notebooks to various formats like Python scripts, HTML, and more. The server handles all notebook operations through a clean API that maintains notebook integrity and prevents malformed changes.\n\n## Latest Version\n\n**Current Version:** `0.3.1` - See the [CHANGELOG.md](CHANGELOG.md) for details on recent changes. Key additions include SFTP support, Streamable HTTP transport, and new tools like `notebook_edit_cell_output`, `notebook_bulk_add_cells`, and `notebook_get_server_path_context` to improve notebook editing and path handling.\n\n## Video Walkthrough\n\n### [Notebook MCP Server 0.3.0 Update](https://youtu.be/R3TGyuej-IM) (YouTube)\n\n[](https://youtu.be/R3TGyuej-IM)\n\n* Updates in the **0.3.0 release**, overview of new tools\n* FastMCP upgrade with **streamable HTTP transport**\n* **SFTP support** for editing Jupyter notebooks on remote SSH servers,\n* Issue resolution (#2, #4, #5) plus known issues (#1, #3)\n\n### [Overview of Notebook MCP Server](https://youtu.be/VOVMH-tle14) (YouTube) \n\n[](https://youtu.be/VOVMH-tle14)\n\n - The current **limitations** of editing notebooks directly in Cursor.\n - **Installing** and **configuring** the Notebook MCP Server.\n - **Creating a notebook** from scratch (example shown: Singular Value Decomposition tutorial in less than 2 minutes).\n - Demonstrating various **editing tools** (edit, split, duplicate cells).\n - Reading notebook **metadata**.\n - **Exporting** notebooks to python\n\n## Features\n\nExposes the following MCP tools (registered under the `notebook_mcp` server):\n\n* `notebook_create`: Creates a new, empty notebook file.\n* `notebook_delete`: Deletes an existing notebook file.\n* `notebook_rename`: Renames/moves a notebook file from one path to another.\n* `notebook_read`: Reads an entire notebook and returns its structure as a dictionary.\n* `notebook_read_cell`: Reads the source content of a specific cell.\n* `notebook_add_cell`: Adds a new code or markdown cell after a specified index.\n* `notebook_edit_cell`: Replaces the source content of a specific cell.\n* `notebook_delete_cell`: Deletes a specific cell.\n* `notebook_change_cell_type`: Changes a cell's type (code, markdown, or raw).\n* `notebook_duplicate_cell`: Duplicates a cell multiple times (default: once).\n* `notebook_get_cell_count`: Returns the total number of cells.\n* `notebook_read_metadata`: Reads the top-level notebook metadata.\n* `notebook_edit_metadata`: Updates the top-level notebook metadata.\n* `notebook_read_cell_metadata`: Reads the metadata of a specific cell.\n* `notebook_read_cell_output`: Reads the output list of a specific code cell.\n* `notebook_edit_cell_metadata`: Updates the metadata of a specific cell.\n* `notebook_clear_cell_outputs`: Clears the outputs and execution count of a specific cell.\n* `notebook_clear_all_outputs`: Clears outputs and execution counts for all code cells.\n* `notebook_move_cell`: Moves a cell to a different position.\n* `notebook_split_cell`: Splits a cell into two at a specified line number.\n* `notebook_merge_cells`: Merges a cell with the cell immediately following it.\n* `notebook_validate`: Validates the notebook structure against the `nbformat` schema.\n* `notebook_get_info`: Retrieves general information (cell count, metadata, kernel, language info).\n* `notebook_export`: Exports the notebook to another format (e.g., python, html) using nbconvert. **Note:** See External Dependencies below for requirements needed for certain export formats like PDF.\n* `notebook_get_outline`: Produces an outline showing cell numbers with major headings/functions and line counts to make it easier for the agent to navigate a large notebook.\n* `notebook_search`: Searches cells for a keyword, showing which cell matches were found with contextual snippets. This helps the agent know which cell to read/edit when asked to modify something.\n* `notebook_edit_cell_output`: Allows direct manipulation and setting of cell outputs.\n* `notebook_bulk_add_cells`: Adds multiple cells to a notebook in a single operation.\n* `notebook_get_server_path_context`: Provides detailed server path configuration (allowed_roots, OS path style, SFTP status, project directory validation, and path construction guidance).\n\n## Requirements\n\nThis project has both Python package dependencies and potentially external system dependencies for full functionality.\n\n### Python Dependencies\n\n* **Python Version:** 3.10+\n* **Core:** `mcp>=0.1.0`, `nbformat>=5.0`, `nbconvert>=6.0`, `ipython`, `jupyter_core`, `paramiko>=2.8.0`, `fastmcp>=2.7.0,<2.11`, `uvicorn>=0.20.0`, `starlette>=0.25.0`. These are installed automatically when you install `cursor-notebook-mcp` and provide support for all transport modes (stdio, Streamable HTTP, SSE).\n* **Optional - Development/Testing:** `pytest>=7.0`, `pytest-asyncio>=0.18`, `pytest-cov`, `pytest-timeout>=2.0.0`, `coveralls`. Install via `pip install -e \".[dev]\"` from source checkout.\n\n### External System Dependencies (Optional)\n\nThese are **not** Python packages and must be installed separately on your system for certain features to work:\n\n* **Pandoc:** Required by `nbconvert` for many non-HTML export formats (including the intermediate steps for PDF). See [Pandoc installation instructions](https://pandoc.org/installing.html).\n* **LaTeX (XeLaTeX recommended):** Required by `nbconvert` for exporting notebooks directly to PDF (`--to pdf` option used by `notebook_export` with `export_format=\"pdf\"`). See [Installing TeX](https://nbconvert.readthedocs.io/en/latest/install.html#installing-tex).\n\nIf these external dependencies are missing, the `notebook_export` tool may fail when attempting to export to formats that rely on them (like PDF). Be sure to install them if you plan to use these features.\n\n## Installation\n\n### From PyPI\n\nThe standard installation command will install all necessary dependencies to support stdio, Streamable HTTP, and SSE transport modes.\n\n* **Using pip:**\n ```bash\n pip install cursor-notebook-mcp\n ```\n* **Using uv:**\n ```bash\n uv pip install cursor-notebook-mcp\n ```\n\n### Development Installation (From Source)\n\n1. Clone this repository:\n ```bash\n git clone https://github.com/jbeno/cursor-notebook-mcp.git # Or your fork\n cd cursor-notebook-mcp\n ```\n\n2. Create and activate a virtual environment (recommended):\n ```bash\n # Using Python's venv\n python -m venv .venv\n source .venv/bin/activate # On Windows use `.venv\\Scripts\\activate`\n\n # Or using uv (if installed)\n # uv venv\n # source .venv/bin/activate # On Windows use `.venv\\Scripts\\activate`\n ```\n\n3. Install in editable mode with all optional dependencies:\n * **Using pip:**\n ```bash\n # Installs the package in editable mode along with test dependencies.\n pip install -e \".[dev]\"\n \n # To install in editable mode without extra test dependencies:\n # pip install -e .\n ```\n * **Using uv:**\n ```bash\n # Installs the package in editable mode along with test dependencies.\n uv pip install -e \".[dev]\"\n \n # To install in editable mode without extra test dependencies:\n # uv pip install -e .\n ```\n\n## Server Configuration and Cursor Integration\n\nThis section details how to run the `cursor-notebook-mcp` server and configure Cursor to use it, depending on the chosen transport protocol.\n\n### 1. Streamable HTTP Transport (Recommended)\n\nWith Streamable HTTP, you run the server process manually, and Cursor connects to it over the network. This is the recommended method for most setups involving Cursor.\n\n#### A. Running the Server (Manual Start Required)\n\nFirst, ensure the package is installed (e.g., `pip install cursor-notebook-mcp` or `uv pip install cursor-notebook-mcp`) and your virtual environment is active if running from source.\n\n* **Using the installed script:**\n ```bash\n cursor-notebook-mcp --transport streamable-http --allow-root /path/to/your/notebooks --host 127.0.0.1 --port 8080\n ```\n* **Running from a source checkout (ensure dependencies are installed, e.g., `pip install -e .` or `uv pip install -e .`, or with `.[dev]` if you need test tools too):**\n ```bash\n python -m cursor_notebook_mcp.server --transport streamable-http --allow-root /path/to/your/notebooks --host 127.0.0.1 --port 8080\n ```\n Remember to replace `/path/to/your/notebooks` with the actual path to the directory you want the server to access.\n\n#### B. Cursor `mcp.json` Configuration\n\nGo to Cursor Settings > MCP > Add new global MCP server. Or create or update your `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project-specific) file:\n```json\n{\n \"mcpServers\": {\n \"notebook_mcp\": {\n \"url\": \"http://127.0.0.1:8080/mcp\"\n }\n }\n}\n```\n*Note: Adjust the `host`, `port`, and path (`/mcp` is the default for `FastMCP`'s streamable HTTP). The server must be running before Cursor attempts to connect.*\n\n### 2. SSE Transport (Legacy Web/Network)\n\nSSE is now considered a legacy transport, but it's still supported. Streamable HTTP is preferred for new setups. With SSE, you also run the server process manually.\n\n#### A. Running the Server (Manual Start Required)\n\nEnsure the package is installed (e.g., `pip install cursor-notebook-mcp` or `uv pip install cursor-notebook-mcp`) and your virtual environment is active if running from source.\n\n* **Using the installed script:**\n ```bash\n cursor-notebook-mcp --transport sse --allow-root /path/to/your/notebooks --host 127.0.0.1 --port 8080\n ```\n* **Running from a source checkout:**\n ```bash\n python -m cursor_notebook_mcp.server --transport sse --allow-root /path/to/your/notebooks --host 127.0.0.1 --port 8080\n ```\n\n#### B. Cursor `mcp.json` Configuration\n\nGo to Cursor Settings > MCP > Add new global MCP server. Or create or update your `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project-specific) file:\n\n```json\n{\n \"mcpServers\": {\n \"notebook_mcp\": {\n \"url\": \"http://127.0.0.1:8081/sse\"\n }\n }\n}\n```\n*Note: `FastMCP`'s `sse` transport uses `/sse` for the handshake. The server must be running before Cursor attempts to connect.*\n\n### 3. stdio Transport\n\nWith `stdio` transport, Cursor launches and manages the server process directly. You do not run the server manually in your terminal for Cursor integration. Cursor communicates with it via standard input/output.\n\nThis method requires telling Cursor the command and arguments to start the server. **Care must be taken to ensure Cursor uses the correct Python environment where `cursor-notebook-mcp` and its dependencies are installed.**\n\n#### Option 1: Using absolute paths to a specific virtual environment (Traditional `venv` / `virtualenv`)\n\nThis is reliable if you have a dedicated venv for the tool.\n\n* If `cursor-notebook-mcp` script is in the venv's `bin`:\n ```json\n {\n \"mcpServers\": {\n \"notebook_mcp\": {\n \"command\": \"/absolute/path/to/venv/bin/cursor-notebook-mcp\",\n \"args\": [\n \"--allow-root\", \"/absolute/path/to/your/notebooks\"\n ]\n }\n }\n }\n ```\n* Using the venv's Python to run the module:\n ```json\n {\n \"mcpServers\": {\n \"notebook_mcp\": {\n \"command\": \"/absolute/path/to/venv/bin/python\",\n \"args\": [\n \"-m\", \"cursor_notebook_mcp.server\",\n \"--allow-root\", \"/absolute/path/to/your/notebooks\"\n ]\n }\n }\n }\n ```\nReplace `/absolute/path/to/venv/...` and `/absolute/path/to/your/notebooks` accordingly. Remember you can add other `cursor-notebook-mcp` arguments (like `--log-level DEBUG`) to the `args` list as needed.\n\n#### Option 2: Using `uv` to run from a specific project's virtual environment (Recommended for projects managed with `uv`)\n\nThis method uses `uv` to execute `cursor-notebook-mcp` within a designated project's Python environment. It's robust as it explicitly defines the project context for `uv`.\nEnsure `uv` is installed. You might need to provide the full path to the `uv` executable in the `command` field (e.g., run `which uv` on macOS/Linux or `where uv` on Windows to find it). The project directory specified for `uv --directory` should be the root of your project where `uv` manages an environment (e.g., where a `.venv` was created by `uv venv` and `cursor-notebook-mcp` is installed).\nThe following examples can be used for `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (project-specific).\n\n* If `cursor-notebook-mcp` is an installed script in the `uv` environment:\n ```json\n {\n \"mcpServers\": {\n \"notebook_mcp\": {\n \"command\": \"uv\", \n \"args\": [\n \"--directory\", \"/absolute/path/to/your/project/with/uv/venv\", \n \"run\", \"--\", \n \"cursor-notebook-mcp\", \n \"--allow-root\", \"/absolute/path/to/your/notebooks\"\n ]\n }\n }\n }\n ```\n* Using `uv run` with `python -m ...`:\n ```json\n {\n \"mcpServers\": {\n \"notebook_mcp\": {\n \"command\": \"uv\", \n \"args\": [\n \"--directory\", \"/absolute/path/to/your/project/with/uv/venv\", \n \"run\", \"--\", \n \"python\", \"-m\", \"cursor_notebook_mcp.server\",\n \"--allow-root\", \"/absolute/path/to/your/notebooks\"\n ]\n }\n }\n }\n ```\n*Note: For these `uv` examples, `/absolute/path/to/your/project/with/uv/venv` must be the correct absolute path to your project where `cursor-notebook-mcp` is installed within its `uv`-managed environment. The `--allow-root` path for notebooks should also be an absolute path for clarity and reliability. You can add other `cursor-notebook-mcp` arguments (like `--log-level DEBUG` or `--port 8889`) to the end of the `args` list for `cursor-notebook-mcp` or `python -m cursor_notebook_mcp.server` as needed.*\n\n## Cursor Rules for AI Guidance\n\nThe package includes a `cursor_rules.md` file that helps calibrate the agent's behavior when working with Jupyter notebooks through the MCP server. These rules ensure consistent and clean notebook actions by providing guidelines for markdown formatting, tool usage, path resolution, and more.\n\n### Default Behavior: Visibility and Feedback\n\nBy default, the rules are optimized for visibility into the AI's actions as it constructs or modifies notebooks. The AI will tend to use individual tool calls for operations like adding cells, which means you can see the notebook being built cell by cell. This provides good feedback and allows you to intervene quickly if needed. However, this approach results in more tool calls, which can impact costs when using paid AI services.\n\n### Configuring Rules in Cursor\n\nTo use the cursor rules:\n\n1. Open Cursor\n2. Go to Cursor > Settings > Cursor Settings\n3. Click on \"Rules\" in the sidebar\n4. You can either:\n * Click \"Add new rule\" under \"Project Rules\" to apply the rules only to the current project\n * Add to \"User Rules\" to apply them globally\n\n### Optional: Cost-Efficient Mode\n\nIf you're more concerned about cost-effectiveness and don't mind waiting to see results, you can add the following section to the rules:\n\n```markdown\n8. **Efficiency Mode (Cost Optimization):**\n * Minimize tool calls as they incur API costs.\n * Use `notebook_bulk_add_cells` instead of multiple `notebook_add_cell` calls when adding multiple cells.\n * Use `notebook_read` to get the full notebook state instead of reading individual cells.\n * Only use `notebook_read_cell` when you need to verify a specific cell's content.\n * Batch related changes together when possible.\n * Skip verification reads if the operation is simple and unlikely to fail.\n```\n\n## Editing Remote Notebooks via SFTP/SSH\n\nThis server supports accessing and editing Jupyter notebooks stored on remote servers via SFTP (SSH File Transfer Protocol). This allows you to work on notebooks as if they were local, provided you have SSH access to the remote machine and SFTP is enabled on it.\n\n### How it Works\n\nThe server uses the `paramiko` library to establish an SSH connection and then an SFTP session. When you specify one or more `--sftp-root` arguments, the server maps these remote locations to internal paths. All notebook operations (reading, writing, listing, etc.) on paths under these remote roots are then transparently handled over SFTP.\n\n### Prerequisites\n\n* **SFTP Enabled on Remote Server:** The SSH server on the remote machine must have the SFTP subsystem enabled. This is standard on most Linux/macOS SSH servers.\n* **SSH Access:** You need valid credentials (username, password, and/or SSH key) for the remote server.\n* **`paramiko` Dependency:** The `cursor-notebook-mcp` package includes `paramiko` as a core dependency, so no extra installation for this is typically needed.\n\n### Important Note on Transports and Authentication\n\nFor SFTP connections that require interactive authentication (e.g., password prompts, 2-Factor Authentication (2FA)/Multi-Factor Authentication (MFA) codes, SSH key passphrases), you **must** run the `cursor-notebook-mcp` server manually using a network transport like `streamable-http` (recommended) or `sse`.\n\nThis is because these prompts occur when the server starts and tries to establish the SFTP connection. If using `stdio` transport (where Cursor launches the server in the background), there is no way for you to interact with these prompts, and the connection will likely fail.\n\nWhen you run the server manually in your terminal with a network transport, you will be prompted directly in that terminal for any required passwords, passphrases, or 2FA codes.\n\n### SFTP Command-Line Arguments\n\nTo configure SFTP access, you use the following command-line arguments when starting the server:\n\n* `--sftp-root user@host:/path/to/remote/notebooks`\n * Specifies a remote notebook directory. Format is `username@hostname:/absolute/path/on/server`.\n * This argument can be used multiple times to map several distinct remote locations.\n * Tilde expansion (`~`) is supported for the path (e.g., `user@host:~/notebooks`).\n* `--sftp-password your_password_or_passphrase`\n * (Optional) Provides the password for SSH password authentication or the passphrase for an encrypted SSH private key.\n * **Security Note:** Supplying credentials directly on the command line can be a security risk (e.g., exposure in shell history or process lists). It is generally more secure to omit this argument and rely on interactive prompts when the server starts, or use SSH agent / key-based authentication without passphrases where possible.\n* `--sftp-key /path/to/your/private_key`\n * Specifies the path to your SSH private key file (e.g., `~/.ssh/id_rsa`).\n* `--sftp-port port_number`\n * SSH port for SFTP connections. Defaults to `22`.\n* `--sftp-auth-mode mode`:\n * Authentication mode for SFTP (e.g., `auto`, `key`, `password`, `key+interactive`). Defaults to `auto`.\n* `--sftp-no-agent`:\n * Disables using an SSH agent for SFTP authentication.\n* `--sftp-no-interactive`:\n * Disables all interactive SFTP authentication prompts.\n* `--sftp-no-password-prompt`:\n * Skips password/passphrase prompt if not provided via `--sftp-password`, but allows other interactive prompts (e.g., 2FA codes).\n\n### SFTP Configuration Examples\n\nBelow are examples of how to start the `cursor-notebook-mcp` server with various SFTP authentication methods. Remember to use a network transport like `streamable-http`.\n\n#### 1. Password Authentication\n\n* **Interactively prompted for password:**\n ```bash\n cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \\\n --sftp-root myuser@remote.example.com:/home/myuser/notebooks \\\n --sftp-auth-mode password\n ```\n *(You will be prompted for `myuser`'s password when the server starts.)*\n\n* **Password provided via argument (less secure):**\n ```bash\n cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \\\n --sftp-root myuser@remote.example.com:/home/myuser/notebooks \\\n --sftp-password \"MySecretP@ssw0rd\" \\\n --sftp-auth-mode password\n ```\n\n#### 2. SSH Key Authentication\n\n* **Key without passphrase (e.g., `~/.ssh/id_rsa`):**\n ```bash\n cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \\\n --sftp-root myuser@remote.example.com:~/project_notebooks \\\n --sftp-key ~/.ssh/id_rsa \\\n --sftp-auth-mode key\n ```\n\n* **Key with passphrase (interactively prompted):**\n ```bash\n cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \\\n --sftp-root myuser@remote.example.com:/srv/notebooks \\\n --sftp-key ~/.ssh/encrypted_key \\\n --sftp-auth-mode key\n ```\n *(You will be prompted for the passphrase for `encrypted_key`.)*\n\n* **Key with passphrase (provided via argument):**\n ```bash\n cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \\\n --sftp-root myuser@remote.example.com:/data/notebooks \\\n --sftp-key ~/.ssh/encrypted_key \\\n --sftp-password \"MyPrivateKeyPassphrase\" \\\n --sftp-auth-mode key\n ```\n\n#### 3. Keyboard-Interactive Authentication (e.g., 2FA/MFA)\n\n* **Server prompts for username/password and/or 2FA code:**\n ```bash\n cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \\\n --sftp-root myuser@remote.example.com:~/notebooks \\\n --sftp-auth-mode interactive\n ```\n\n#### 4. Combined: SSH Key (passphrase-protected) + Keyboard-Interactive (2FA/MFA)\n\n This scenario is for when your SSH key is encrypted with a passphrase, and the server also requires a second factor (e.g., a TOTP code) via keyboard-interactive authentication.\n\n ```bash\n cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \\\n --sftp-root myuser@remote.example.com:~/notebooks \\\n --sftp-key ~/.ssh/your_encrypted_rsa_key \\\n --sftp-auth-mode key+interactive\n ```\n *(When the server starts, you should be prompted first for the passphrase for `your_encrypted_rsa_key`. After successfully entering it, if the server requires further interactive authentication, you will then be prompted for your 2FA code or other interactive inputs.)*\n\n#### 5. Combined: Password + Keyboard-Interactive (e.g., Password then 2FA Code)\n\n ```bash\n cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \\\n --sftp-root myuser@remote.example.com:~/notebooks \\\n --sftp-auth-mode password+interactive\n ```\n *(Prompts for password, then prompts for 2FA code if required by the server.)*\n\n#### 6. Using SSH Agent\n\nBy default (`--sftp-auth-mode auto` or `key`), the server will try to use a running SSH agent. If your key is loaded in the agent, you might not need to specify `--sftp-key` or `--sftp-password` for the key passphrase.\n\n* **Agent with 2FA (keyboard-interactive for 2FA code only):**\n ```bash\n cursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \\\n --sftp-root myuser@remote.example.com:~/notebooks \\\n --sftp-auth-mode auto # Or key+interactive if you want to be explicit\n # Optional: --sftp-no-password-prompt if agent handles key, but 2FA prompt is separate\n ```\n *(Assumes key is in agent. Will prompt for 2FA if server requires it after key auth.)*\n\n### Multiple Remote Roots\n\nYou can specify `--sftp-root` multiple times to connect to different paths, even on different servers if they use compatible authentication methods (or if you provide specific credentials for each if the server supported per-root credential arguments, which it currently does not - all connections will try the same global credentials like password/key file if provided).\n\n```bash\ncursor-notebook-mcp --transport streamable-http --host 0.0.0.0 --port 8080 \\\n --sftp-root user1@serverA.com:/projects/alpha \\\n --sftp-root user1@serverA.com:~/personal_notebooks \\\n --sftp-key ~/.ssh/id_serverA \\\n --sftp-auth-mode key\n```\n\n### Path Handling\n\n* **Tilde Expansion:** Remote paths like `~/my_notebooks` in `--sftp-root` will be expanded to the user's home directory on the remote server.\n* **Internal Mapping:** The server maps these remote SFTP paths to temporary local-like representations for its internal operations. You, as the user in Cursor, will interact with them using their original remote-style paths (e.g., `myuser@remote.example.com:/home/myuser/notebooks/MyNotebook.ipynb`).\n* **Understanding Context with `notebook_get_server_path_context`:** For AI agents interacting with the server, the `notebook_get_server_path_context` tool is particularly useful. It provides details about all configured roots (local and SFTP), the server's OS path style, and guidance on how paths are constructed and resolved. This helps the AI understand how a given SFTP path relates to the user's current project directory (if local) and correctly interpret user instructions that might involve mixed local or remote path references.\n\nOnce the server is running with SFTP roots configured, you can use the `notebook_mcp` tools in Cursor to interact with notebooks under these remote paths just as you would with local notebooks, provided they are within an `--allow-root` (for local files) or a configured `--sftp-root`.\n\n## Logging\n\nThe server logs its operations to help with troubleshooting and monitoring. \n\n* **Default Log Location:** By default, log files are stored in `~/.cursor_notebook_mcp/server.log` (the `.cursor_notebook_mcp` directory is created in your user's home directory).\n* **Custom Log Directory:** You can specify a different directory for log files using the `--log-dir` command-line argument. For example: `cursor-notebook-mcp --allow-root /path/to/notebooks --log-dir /custom/log/path`\n* **Log Level:** The verbosity of the logs can be controlled with the `--log-level` argument. By default, the log level is set to `INFO`. Other available levels are `DEBUG`, `WARNING`, `ERROR`, and `CRITICAL`. Setting the level to `DEBUG` is particularly useful for development or deep troubleshooting as it will show extensive output, including full stack traces for all exceptions (even those that are handled by the server).\n\n## Command-Line Arguments\n\nThe server accepts the following command-line arguments:\n\n* `--allow-root`: (Required if no `--sftp-root` is provided, can use multiple times) Absolute path to a directory where local notebooks are allowed.\n* `--log-dir`: Directory to store log files. Defaults to `~/.cursor_notebook_mcp`.\n* `--log-level`: Set the logging level: `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`. Defaults to `INFO`.\n* `--max-cell-source-size`: Maximum allowed size in bytes for cell source content. Defaults to 10 MiB.\n* `--max-cell-output-size`: Maximum allowed size in bytes for cell output content. Defaults to 10 MiB.\n* `--transport`: Transport type to use: `stdio`, `streamable-http`, or `sse`. Defaults to `stdio`. `streamable-http` is recommended for web; `sse` is a deprecated alternative.\n* `--host`: Host to bind the Streamable HTTP or SSE server to. Only used with `--transport=streamable-http` or `--transport=sse`. Defaults to `127.0.0.1`.\n* `--port`: Port to bind the Streamable HTTP or SSE server to. Only used with `--transport=streamable-http` or `--transport=sse`. Defaults to `8080`.\n* `--sftp-root user@host:/path/to/remote/notebooks`:\n * Specifies a remote notebook directory via SFTP. Can be used multiple times.\n * See the \"Editing Remote Notebooks via SFTP/SSH\" section for detailed usage and authentication.\n* `--sftp-password your_password_or_passphrase`:\n * (Optional and not recommended for security) Provides the password for SSH authentication or the passphrase for an encrypted SSH private key. It is generally more secure to omit this and enter credentials via interactive prompt if needed.\n* `--sftp-key /path/to/your/private_key`:\n * Path to your SSH private key file for SFTP authentication.\n* `--sftp-port port_number`:\n * SSH port for SFTP connections. Defaults to `22`.\n* `--sftp-auth-mode mode`:\n * Authentication mode for SFTP (e.g., `auto`, `key`, `password`, `key+interactive`). Defaults to `auto`.\n* `--sftp-no-agent`:\n * Disables using an SSH agent for SFTP authentication.\n* `--sftp-no-interactive`:\n * Disables all interactive SFTP authentication prompts.\n* `--sftp-no-password-prompt`:\n * Skips password/passphrase prompt if not provided via `--sftp-password`, but allows other interactive prompts (e.g., 2FA codes).\n\n## Security\n\n* **Workspace Root Enforcement:** The server requires the `--allow-root` command-line argument during startup. It will refuse to operate on any notebook file located outside the directories specified by these arguments. This is a critical security boundary.\n* **Path Handling:** The server uses `os.path.realpath` to resolve paths and checks against the allowed roots before any read or write operation.\n* **SFTP Authentication Security:** When connecting to remote notebooks via SFTP, it is highly recommended to use network transports (`streamable-http` or `sse`). This allows the server to interactively prompt you for credentials such as passwords, SSH key passphrases, or 2-Factor Authentication (2FA) codes directly in your terminal. This method is more secure than providing sensitive information via command-line arguments (e.g., `--sftp-password`), as it avoids exposing credentials in your shell history or system process lists. The server supports various authentication flows, including multi-factor combinations like certificate + 2FA or password + 2FA, by leveraging these interactive prompts.\n* **Input Validation:** Basic checks for `.ipynb` extension are performed.\n* **Cell Source Size Limit:** The server enforces a maximum size limit (configurable via `--max-cell-source-size`, default 10 MiB) on the source content provided to `notebook_edit_cell` and `notebook_add_cell` to prevent excessive memory usage.\n* **Cell Output Size Limit:** The server enforces a maximum size limit (configurable via `--max-cell-output-size`, default 10 MiB) on the total serialized size of outputs returned by `notebook_read_cell_output`.\n\n## Limitations\n\n* **No Cell Execution:** This server cannot execute notebook cells. It operates solely on the `.ipynb` file structure using the `nbformat` library and does not interact with Jupyter kernels. Cell execution must be performed manually by the user within the Cursor UI (selecting the desired kernel and running the cell). \n\n## Issues\n\nIf you encounter any bugs, have feature requests, or other issues, please check the existing issues or submit a new one on our GitHub issue tracker.\n\n### Known Issues\n\nCheck the [GitHub Issues tab](https://github.com/jbeno/cursor-notebook-mcp/issues) for a list of currently known issues.\n\n* **UI Refresh Issues:** Occasionally, some notebook operations (like cell splitting or merging) may succeed at the file level, but the Cursor UI might not show the updated content correctly. In such situations, you can:\n * Close and re-open the notebook file\n * Save the file, which might prompt to \"Revert\" or \"Overwrite\" - select \"Revert\" to reload the actual file content\n* **No Checkpoint Support:** When the agent makes edits using third-party MCP tools, it does not register a checkpoint in the AI chat history with a \"Restore Checkpoint\" button. To mitigate against this:\n * Use git to frequently commit and allow for rollback\n * Create manual copies of your work at key milestones\n* **No File/Line Context:** Cursor does not share the Jupyter notebook context automatically as it does with other files. In other files (Python, Markdown) it shares the current file and line number with the AI agent. However, for notebooks, it does not share any context. Ideally it would share the cell and the line number within that cell. To work around this:\n * When you know, try to be explicit about which cell, function or section you want to edit\n * The agent can use `notebook_get_outline` to get a rough outline of the notebook. This will help it identify which cells have key classes, functions or markdown headings.\n * The agent can use `notebook_search` to determine which cells contain keywords, classes, or functions. \n\n\n### Submitting an Issue\n\nTo submit a new issue:\n\n1. Visit the [jbeno/cursor-notebook-mcp Issues page](https://github.com/jbeno/cursor-notebook-mcp/issues).\n2. Click on \"New Issue\".\n3. Provide:\n * A clear description of the problem or feature request.\n * Steps to reproduce the issue (if applicable).\n * Expected vs. actual behavior.\n * Your environment details (OS, Python version, `cursor-notebook-mcp` version, etc.).\n * Any relevant error messages or logs.\n * Which model and client/version you're using (if relevant to an AI interaction).\n\n## Contributions\n\nContributions to improve the Jupyter Notebook MCP Server are welcome!\n\nIf you'd like to contribute, please fork the repository, create a branch for your changes, and then open a Pull Request (PR) to the `main` branch of `jbeno/cursor-notebook-mcp`.\n\nEnsure your changes include:\n* Relevant unit tests for new functionality.\n* Updates to documentation (`README.md`, `CHANGELOG.md`) if your changes affect usage or add features.\n* Adherence to the existing code style.\n\nPlease ensure all tests pass by running the test scripts (`./run_tests.sh` or `.\\run_tests.ps1`) before submitting your PR.\n\n**Discussion for Major Changes:** For significant changes or new features, it's a good idea to open an issue first to discuss your proposed changes and ensure they align with the project's goals.\n\n### Development Environment Setup\n\nFirst, clone the repository and set up a virtual environment. Then install the package in editable mode with all development and testing dependencies:\n\n* **Using pip:**\n ```bash\n # From the project root directory\n python -m venv .venv\n source .venv/bin/activate # On Windows use: .venv\\Scripts\\activate\n pip install -e \".[dev]\"\n ```\n* **Using uv:**\n ```bash\n # From the project root directory\n uv venv\n source .venv/bin/activate # On Windows use: .venv\\Scripts\\activate\n uv pip install -e \".[dev]\"\n ```\n\n### Running Unit Tests\n\nThe project uses `pytest` for unit testing. Test files are located in the `tests/` directory. When adding new tests, please place them in this directory, following the existing naming conventions (e.g., `test_*.py`).\n\nTo run the tests, use the provided wrapper scripts. These scripts run test files individually, which helps prevent potential hanging issues that can sometimes occur when running `pytest` directly across all test files in this project, especially with asynchronous operations or SFTP tests.\n\n* **On Linux/macOS:** Use the wrapper script to ensure environment variables are set correctly.\n ```bash\n ./run_tests.sh \n # To run specific tests:\n # ./run_tests.sh tests/test_notebook_tools.py\n ```\n* **On Windows:** Use the PowerShell wrapper script.\n ```bash\n .\\run_tests.ps1\n # To run specific tests:\n # .\\run_tests.ps1 tests/test_notebook_tools.py\n ```\n\n### Code Coverage\n\nCode coverage is automatically calculated when running tests via the wrapper scripts (`run_tests.sh` or `run_tests.ps1`), using `pytest-cov`. \n\nDetailed coverage reports are available on Coveralls. You can view the current coverage status via the badge at the top of this README or directly at [https://coveralls.io/github/jbeno/cursor-notebook-mcp?branch=main](https://coveralls.io/github/jbeno/cursor-notebook-mcp?branch=main).\n\n### AI-Driven Test Plan (`test_plan.md`)\n\nIn addition to the automated unit tests, the repository includes a `test_plan.md` file. This document outlines a series of scenario-based tests designed for execution by an AI agent, such as Cursor in Agent Mode or a similar conversational AI with access to the `notebook_mcp` tools. \n\nTo use it, you can instruct your AI agent to \"execute the test plan found in `test_plan.md`.\" The plan covers a wide range of notebook operations, from basic editing to SFTP access and metadata changes, helping to verify the practical usability and correctness of the tools in realistic, multi-step workflows. The test plan has instructions that account for different operating systems (macOS/Linux or Windows).\n\n## License\n\nThis project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.\nSee the [LICENSE](LICENSE) file for details.\n\nCopyright \u00a9 2025 Jim Beno\n\nThis work is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.\n\n<a rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\">\n<img alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png\" />\n</a>\n\n## Author\n\nThis project was created and is maintained by Jim Beno - jim@jimbeno.net",
"bugtrack_url": null,
"license": "Attribution-NonCommercial-ShareAlike 4.0 International\n =======================================================================\n \n Creative Commons Corporation (\"Creative Commons\") is not a law firm and\n does not provide legal services or legal advice. Distribution of\n Creative Commons public licenses does not create a lawyer-client or\n other relationship. Creative Commons makes its licenses and related\n information available on an \"as-is\" basis. Creative Commons gives no\n warranties regarding its licenses, any material licensed under their terms\n and conditions, or any related information. Creative Commons disclaims\n all liability for damages resulting from their use to the fullest extent\n possible.\n \n Using Creative Commons Public Licenses\n \n Creative Commons public licenses provide a standard set of terms and\n conditions that creators and other rights holders may use to share\n original works of authorship and other material subject to copyright and\n certain other rights specified in the public license below. The\n following considerations are for informational purposes only, are not\n exhaustive, and do not form part of our licenses.\n \n Considerations for licensors: Our public licenses are intended for use\n by those authorized to give the public permission to use material in\n ways otherwise restricted by copyright and certain other rights. Our\n licenses are irrevocable. Licensors should read and understand the terms\n and conditions of the license they choose before applying it. Licensors\n should also secure all rights necessary before applying our licenses so\n that the public can reuse the material as expected. Licensors should\n clearly mark any material not subject to the license. This includes\n other CC-licensed material, or material used under an exception or\n limitation to copyright. More considerations for licensors:\n wiki.creativecommons.org/Considerations_for_licensors\n \n Considerations for the public: By using one of our public licenses, a\n licensor grants the public permission to use the licensed material under\n specified terms and conditions. If the licensor's permission is not\n necessary for any reason--for example, because of any applicable\n exception or limitation to copyright--then that use is not regulated by\n the license. Our licenses grant only permissions under copyright and\n certain other rights that a licensor has authority to grant. Use of the\n licensed material may still be restricted for other reasons, including\n because others have copyright or other rights in the material. A\n licensor may make special requests, such as asking that all changes be\n marked or described. Although not required by our licenses, you are\n encouraged to respect those requests where reasonable. More\n considerations for the public:\n wiki.creativecommons.org/Considerations_for_licensees\n \n =======================================================================\n \n Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International\n Public License\n \n By exercising the Licensed Rights (defined below), You accept and agree\n to be bound by the terms and conditions of this Creative Commons\n Attribution-NonCommercial-ShareAlike 4.0 International Public License\n (\"Public License\"). To the extent this Public License may be interpreted\n as a contract, You are granted the Licensed Rights in consideration of\n Your acceptance of these terms and conditions, and the Licensor grants\n You such rights in consideration of benefits the Licensor receives from\n making the Licensed Material available under these terms and conditions.\n \n Section 1 -- Definitions.\n \n a. Adapted Material means material subject to Copyright and Similar\n Rights that is derived from or based upon the Licensed Material and\n in which the Licensed Material is translated, altered, arranged,\n transformed, or otherwise modified in a manner requiring permission\n under the Copyright and Similar Rights held by the Licensor. For\n purposes of this Public License, where the Licensed Material is a\n musical work, performance, or sound recording, Adapted Material is\n always produced where the Licensed Material is synched in timed\n relation with a moving image.\n \n b. Adapter's License means the license You apply to Your Copyright and\n Similar Rights in Your contributions to Adapted Material in\n accordance with the terms and conditions of this Public License.\n \n c. BY-NC-SA Compatible License means a license listed at\n creativecommons.org/compatiblelicenses, approved by Creative Commons\n as essentially the equivalent of this Public License.\n \n d. Copyright and Similar Rights means copyright and/or similar rights\n closely related to copyright including, without limitation,\n performance, broadcast, sound recording, and Sui Generis Database\n Rights, without regard to how the rights are labeled or categorized.\n For purposes of this Public License, the rights specified in Section\n 2(b)(1)-(2) are not Copyright and Similar Rights.\n \n e. Effective Technological Measures means those measures that, in the\n absence of proper authority, may not be circumvented under laws\n fulfilling obligations under Article 11 of the WIPO Copyright Treaty\n adopted on December 20, 1996, and/or similar international\n agreements.\n \n f. Exceptions and Limitations means fair use, fair dealing, and/or any\n other exception or limitation to Copyright and Similar Rights that\n applies to Your use of the Licensed Material.\n \n g. License Elements means the license attributes listed in the name of a\n Creative Commons Public License. The License Elements of this Public\n License are Attribution, NonCommercial, and ShareAlike.\n \n h. Licensed Material means the artistic or literary work, database, or\n other material to which the Licensor applied this Public License.\n \n i. Licensed Rights means the rights granted to You subject to the terms\n and conditions of this Public License, which are limited to all\n Copyright and Similar Rights that apply to Your use of the Licensed\n Material and that the Licensor has authority to license.\n \n j. Licensor means the individual(s) or entity(ies) granting rights\n under this Public License.\n \n k. NonCommercial means not primarily intended for or directed towards\n commercial advantage or monetary compensation. For purposes of this\n Public License, the exchange of the Licensed Material for other\n material subject to Copyright and Similar Rights by digital\n file-sharing or similar means is NonCommercial provided there is no\n payment of monetary compensation in connection with the exchange.\n \n l. Share means to provide material to the public by any means or\n process that requires permission under the Licensed Rights, such as\n reproduction, public display, public performance, distribution,\n dissemination, communication, or importation, and to make material\n available to the public including in ways that members of the public\n may access the material from a place and at a time individually\n chosen by them.\n \n m. Sui Generis Database Rights means rights other than copyright\n resulting from Directive 96/9/EC of the European Parliament and of\n the Council of 11 March 1996 on the legal protection of databases,\n as amended and/or succeeded, as well as other essentially\n equivalent rights anywhere in the world.\n \n n. You means the individual or entity exercising the Licensed Rights\n under this Public License. Your has a corresponding meaning.\n \n Section 2 -- Scope.\n \n a. License grant.\n \n 1. Subject to the terms and conditions of this Public License, the\n Licensor hereby grants You a worldwide, royalty-free,\n non-sublicensable, non-exclusive, irrevocable license to exercise\n the Licensed Rights in the Licensed Material to:\n \n a. reproduce and Share the Licensed Material, in whole or in\n part, for NonCommercial purposes only; and\n \n b. produce, reproduce, and Share Adapted Material for\n NonCommercial purposes only.\n \n 2. Exceptions and Limitations. For the avoidance of doubt, where\n Exceptions and Limitations apply to Your use, this Public License\n does not apply, and You do not need to comply with its terms and\n conditions.\n \n 3. Term. The term of this Public License is specified in Section 6(a).\n \n 4. Media and formats; technical modifications allowed. The Licensor\n authorizes You to exercise the Licensed Rights in all media and\n formats whether now known or hereafter created, and to make\n technical modifications necessary to do so. The Licensor waives\n and/or agrees not to assert any right or authority to forbid You\n from making technical modifications necessary to exercise the\n Licensed Rights, including technical modifications necessary to\n circumvent Effective Technological Measures. For purposes of this\n Public License, simply making modifications authorized by this\n Section 2(a)(4) never produces Adapted Material.\n \n 5. Downstream recipients.\n \n a. Offer from the Licensor -- Licensed Material. Every recipient\n of the Licensed Material automatically receives an offer from\n the Licensor to exercise the Licensed Rights under the terms\n and conditions of this Public License.\n \n b. Additional offer from the Licensor -- Adapted Material. Every\n recipient of Adapted Material from You automatically receives\n an offer from the Licensor to exercise the Licensed Rights in\n the Adapted Material under the conditions of the Adapter's\n License You apply.\n \n c. No downstream restrictions. You may not offer or impose any\n additional or different terms or conditions on, or apply any\n Effective Technological Measures to, the Licensed Material if\n doing so restricts exercise of the Licensed Rights by any\n recipient of the Licensed Material.\n \n 6. No endorsement. Nothing in this Public License constitutes or may\n be construed as permission to assert or imply that You are, or\n that Your use of the Licensed Material is, connected with, or\n sponsored, endorsed, or granted official status by, the Licensor\n or others designated to receive attribution as provided in Section\n 3(a)(1)(A)(i).\n \n b. Other rights.\n \n 1. Moral rights, such as the right of integrity, are not licensed\n under this Public License, nor are publicity, privacy, and/or\n other similar personality rights; however, to the extent\n possible, the Licensor waives and/or agrees not to assert any such\n rights held by the Licensor to the limited extent necessary to\n allow You to exercise the Licensed Rights, but not otherwise.\n \n 2. Patent and trademark rights are not licensed under this Public\n License.\n \n 3. To the extent possible, the Licensor waives any right to collect\n royalties from You for the exercise of the Licensed Rights,\n whether directly or through a collecting society under any\n voluntary or waivable statutory or compulsory licensing scheme. In\n all other cases the Licensor expressly reserves any right to\n collect such royalties, including when the Licensed Material is\n used other than for NonCommercial purposes.\n \n Section 3 -- License Conditions.\n \n Your exercise of the Licensed Rights is expressly made subject to the\n following conditions.\n \n a. Attribution.\n \n 1. If You Share the Licensed Material (including in modified form),\n You must:\n \n a. retain the following if it is supplied by the Licensor with\n the Licensed Material:\n \n i. identification of the creator(s) of the Licensed\n Material and any others designated to receive\n attribution, in any reasonable manner requested by the\n Licensor (including by pseudonym if designated);\n \n ii. a copyright notice;\n \n iii. a notice that refers to this Public License;\n \n iv. a notice that refers to the disclaimer of warranties;\n \n v. a URI or hyperlink to the Licensed Material to the\n extent reasonably practicable;\n \n b. indicate if You modified the Licensed Material and retain an\n indication of any previous modifications; and\n \n c. indicate the Licensed Material is licensed under this Public\n License, and include the text of, or the URI or hyperlink\n to, this Public License.\n \n 2. You may satisfy the conditions in Section 3(a)(1) in any\n reasonable manner based on the medium, means, and context in\n which You Share the Licensed Material. For example, it may be\n reasonable to satisfy the conditions by providing a URI or\n hyperlink to a resource that includes the required information.\n \n 3. If requested by the Licensor, You must remove any of the\n information required by Section 3(a)(1)(A) to the extent\n reasonably practicable.\n \n b. ShareAlike.\n \n In addition to the conditions in Section 3(a), if You Share Adapted\n Material You produce, the following conditions also apply.\n \n 1. The Adapter's License You apply must be a Creative Commons\n license with the same License Elements, this version or later,\n or a BY-NC-SA Compatible License.\n \n 2. You must include the text of, or the URI or hyperlink to, the\n Adapter's License You apply. You may satisfy this condition in\n any reasonable manner based on the medium, means, and context\n in which You Share Adapted Material.\n \n 3. You may not offer or impose any additional or different terms or\n conditions on, or apply any Effective Technological Measures to,\n Adapted Material that restrict exercise of the rights granted\n under the Adapter's License You apply.\n \n Section 4 -- Sui Generis Database Rights.\n \n Where the Licensed Rights include Sui Generis Database Rights that apply\n to Your use of the Licensed Material:\n \n a. for the avoidance of doubt, Section 2(a)(1) grants You the right to\n extract, reuse, reproduce, and Share all or a substantial portion\n of the contents of the database for NonCommercial purposes only;\n \n b. if You include all or a substantial portion of the database contents\n in a database in which You have Sui Generis Database Rights, then\n the database in which You have Sui Generis Database Rights (but not\n its individual contents) is Adapted Material, including for\n purposes of Section 3(b); and\n \n c. You must comply with the conditions in Section 3(a) if You Share\n all or a substantial portion of the contents of the database.\n \n For the avoidance of doubt, this Section 4 supplements and does not\n replace Your obligations under this Public License where the Licensed\n Rights include other Copyright and Similar Rights.\n \n Section 5 -- Disclaimer of Warranties and Limitation of Liability.\n \n a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE\n EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS\n AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY\n KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, IMPLIED,\n STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, WARRANTIES\n OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,\n NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR\n THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT KNOWN OR\n DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT ALLOWED IN FULL\n OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.\n \n b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE TO\n YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, NEGLIGENCE)\n OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, INCIDENTAL,\n CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, COSTS,\n EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR USE OF THE\n LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE\n POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR DAMAGES. WHERE A\n LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR IN PART, THIS\n LIMITATION MAY NOT APPLY TO YOU.\n \n c. The disclaimer of warranties and limitation of liability provided\n above shall be interpreted in a manner that, to the extent\n possible, most closely approximates an absolute disclaimer and\n waiver of all liability.\n \n Section 6 -- Term and Termination.\n \n a. This Public License applies for the term of the Copyright and Similar\n Rights licensed here. However, if You fail to comply with this\n Public License, then Your rights under this Public License terminate\n automatically.\n \n b. Where Your right to use the Licensed Material has terminated under\n Section 6(a), it reinstates:\n \n 1. automatically as of the date the violation is cured, provided it\n is cured within 30 days of Your discovery of the violation; or\n \n 2. upon express reinstatement by the Licensor.\n \n For the avoidance of doubt, this Section 6(b) does not affect any\n right the Licensor may have to seek remedies for Your violations of\n this Public License.\n \n c. For the avoidance of doubt, the Licensor may also offer the Licensed\n Material under separate terms or conditions or stop distributing the\n Licensed Material at any time; however, doing so will not terminate\n this Public License.\n \n d. Sections 1, 5, 6, 7, and 8 survive termination of this Public\n License.\n \n Section 7 -- Other Terms and Conditions.\n \n a. The Licensor shall not be bound by any additional or different terms\n or conditions communicated by You unless expressly agreed.\n \n b. Any arrangements, understandings, or agreements regarding the\n Licensed Material not stated herein are separate from and\n independent of the terms and conditions of this Public License.\n \n Section 8 -- Interpretation.\n \n a. For the avoidance of doubt, this Public License does not, and shall\n not be interpreted to, reduce, limit, restrict, or impose\n conditions on any use of the Licensed Material that could lawfully\n be made without permission under this Public License.\n \n b. To the extent possible, if any provision of this Public License is\n deemed unenforceable, it shall be automatically reformed to the\n minimum extent necessary to make it enforceable. If the provision\n cannot be reformed, it shall be severed from this Public License\n without affecting the enforceability of the remaining terms and\n conditions.\n \n c. No term or condition of this Public License will be waived and no\n failure to comply consented to unless expressly agreed to by the\n Licensor.\n \n d. Nothing in this Public License constitutes or may be interpreted as\n a limitation upon, or waiver of, any privileges and immunities that\n apply to the Licensor or You, including from the legal processes of\n any jurisdiction or authority.\n \n =======================================================================\n \n Creative Commons is not a party to its public licenses.\n Notwithstanding, Creative Commons may elect to apply one of its public\n licenses to material it publishes and in those instances will be\n considered the \"Licensor.\" The text of the Creative Commons public\n licenses is dedicated to the public domain under the CC0 Public Domain\n Dedication. Except for the limited purpose of indicating that material\n is shared under a Creative Commons public license or as otherwise\n permitted by the Creative Commons policies published at\n creativecommons.org/policies, Creative Commons does not authorize the\n use of the trademark \"Creative Commons\" or any other trademark or logo\n of Creative Commons without its prior written consent including, without\n limitation, in connection with any unauthorized modifications to any of\n its public licenses or any other arrangements, understandings, or\n agreements concerning use of licensed material. For the avoidance of\n doubt, this paragraph does not form part of the public licenses.\n \n Creative Commons may be contacted at creativecommons.org.",
"summary": "Model Context Protocol (MCP) implementation for Jupyter notebooks to overcome limitation with Cursor",
"version": "0.3.1",
"project_urls": {
"Bug Tracker": "https://github.com/jbeno/cursor-notebook-mcp/issues",
"Homepage": "https://github.com/jbeno/cursor-notebook-mcp",
"Source": "https://github.com/jbeno/cursor-notebook-mcp"
},
"split_keywords": [
"agent",
" ai",
" cursor",
" ipynb",
" jupyter",
" mcp",
" nbformat",
" notebook"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "a175d9b706c746135f9e0a368b67211da9261543d81e2bacb07a729a792ea2d4",
"md5": "507cfa309c9e48198b45a6fc132da61f",
"sha256": "ec83986e84783c1200ac6021957892c70902415607d790866ae5a3e565633c86"
},
"downloads": -1,
"filename": "cursor_notebook_mcp-0.3.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "507cfa309c9e48198b45a6fc132da61f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 71036,
"upload_time": "2025-07-16T06:33:56",
"upload_time_iso_8601": "2025-07-16T06:33:56.833519Z",
"url": "https://files.pythonhosted.org/packages/a1/75/d9b706c746135f9e0a368b67211da9261543d81e2bacb07a729a792ea2d4/cursor_notebook_mcp-0.3.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "ec577da5ad7967ec663331348ff3551b79c462769351c886464a1a487c4c4b08",
"md5": "cdad6a4b2b255200e6c85a4be89506cb",
"sha256": "1a2591816a4775d87c1fe41921ee863f1d1953ee60214f0a25e680f74cc87d72"
},
"downloads": -1,
"filename": "cursor_notebook_mcp-0.3.1.tar.gz",
"has_sig": false,
"md5_digest": "cdad6a4b2b255200e6c85a4be89506cb",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 8735949,
"upload_time": "2025-07-16T06:33:58",
"upload_time_iso_8601": "2025-07-16T06:33:58.427489Z",
"url": "https://files.pythonhosted.org/packages/ec/57/7da5ad7967ec663331348ff3551b79c462769351c886464a1a487c4c4b08/cursor_notebook_mcp-0.3.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-16 06:33:58",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jbeno",
"github_project": "cursor-notebook-mcp",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "cursor-notebook-mcp"
}