Jupyter Terminal MCP
Enables an agent to run shell commands through a JupyterLab/JupyterHub-hosted terminal, using REST API and WebSocket via Selenium for session handling, when SSH is not available.
README
Jupyter Terminal MCP
This MCP server lets an agent run commands through a JupyterLab/JupyterHub-hosted terminal when SSH is not available. Originally designed for man-in-the-loop debugging of NPU kernels on AMD's AUP Learning Cloud, it talks to a Jupyter Server terminal REST API and websocket endpoint using a Selenium WebDriver to keep a valid session and perform the requests. You need access to the JupyterLab machine from the system hosting the MCP server. You can also use this server without a browser, if you have a valid Jupyter token and the server is not behind Cloudflare or other login challenges.
[!WARNING] You must have permission from the system administrator to use the JupyterLab environment for research/development. Do not use this software to break rules or bypass security measures. The author is not responsible for any misuse of this software. Not affiliated with Jupyter or any other org. Always verify AI-generated commands before accepting and executing them.
Install
UV_CACHE_DIR=.uv-cache uv sync
Configure
Keep your token in environment variables or your agent's MCP config JSON.
export JUPYTER_URL="https://myjupyterserver.example.com/user/my-user/lab"
export JUPYTER_TOKEN="<your Jupyter token>" # only supported in non-browser mode
export JUPYTER_USERNAME="<your Jupyter username>"
Optional settings:
export JUPYTER_CONNECT_TIMEOUT="10"
export JUPYTER_VERIFY_TLS="true"
export JUPYTER_WEBSOCKET_RETRIES="3"
export JUPYTER_WEBSOCKET_RETRY_DELAY="1"
JUPYTER_URL may point at /lab; the server automatically converts it to the Jupyter API base URL.
The server opens the Lab URL, follows the Hub login/OAuth flow, and submits JUPYTER_USERNAME plus JUPYTER_TOKEN as the login credentials. If JUPYTER_USERNAME is omitted, it is derived from /user/<name>/ in JUPYTER_URL.
Websocket connection failures with transient statuses such as 503 Service Unavailable are retried. Before each retry, the server refreshes the JupyterHub session cookies.
In my experience, custom terminal names can sometimes remain listed after their websocket route has gone stale. Leaving JUPYTER_TERMINAL_NAME unset is usually more robust: the server reuses existing numeric terminals first, starting from the lowest name (1, then 2, and so on). If a selected terminal returns a 502/503/504 websocket handshake, the server tries the next existing numeric terminal before creating a fresh unnamed terminal.
Browser-backed mode does not require JUPYTER_TOKEN; the logged-in browser session supplies the cookies. Useful browser/socket settings:
export JUPYTER_MCP_SOCKET_HOST="127.0.0.1"
export JUPYTER_MCP_SOCKET_PORT="8765"
export CHROMEDRIVER="/path/to/chromedriver" # optional if chromedriver is already on PATH
export JUPYTER_CHROME_BINARY="/path/to/Google Chrome" # optional
export JUPYTER_CHROME_USER_DATA_DIR="/path/to/user-data-dir" # optional; reuse a Chrome user data dir
export JUPYTER_CHROME_PROFILE_DIRECTORY="Default" # optional; profile inside the user data dir
export JUPYTER_BROWSER_KEEP_OPEN="true" # optional; leave Chrome open when the daemon exits
Run
For a quick local config check:
UV_CACHE_DIR=.uv-cache uv run jupyter-terminal-mcp --check-config
For browser-backed mode, run the browser daemon in a regular terminal first:
export JUPYTER_URL="https://myjupyterserver.example.com/user/my-user/lab"
UV_CACHE_DIR=.uv-cache uv run jupyter-terminal-mcp --browser-server
Chrome opens. Complete any login procedure, Cloudflare challenge etc. manually, wait until JupyterLab is ready, then press Enter in the daemon terminal. The daemon listens for MCP JSON-RPC messages on 127.0.0.1:8765 by default.
Then configure MCP clients to launch the stdio socket proxy:
UV_CACHE_DIR=.uv-cache uv run jupyter-terminal-mcp --socket-client
Example browser-backed MCP configuration:
{
"mcpServers": {
"jupyter-terminal": {
"command": "uv",
"args": [
"--directory",
"~/Projects/jupyter-terminal-mcp",
"run",
"jupyter-terminal-mcp",
"--socket-client"
],
"env": {
"UV_CACHE_DIR": "~/Projects/jupyter-terminal-mcp/.uv-cache",
"JUPYTER_MCP_SOCKET_HOST": "127.0.0.1",
"JUPYTER_MCP_SOCKET_PORT": "8765"
}
}
}
}
In non-browser-backed mode, clients should launch:
UV_CACHE_DIR=.uv-cache uv run jupyter-terminal-mcp
Example non-browser-backed MCP configuration:
{
"mcpServers": {
"jupyter-terminal": {
"command": "uv",
"args": [
"--directory",
"~/Projects/jupyter-terminal-mcp",
"run",
"jupyter-terminal-mcp"
],
"env": {
"UV_CACHE_DIR": "~/Projects/jupyter-terminal-mcp/.uv-cache",
"JUPYTER_URL": "https://myjupyterserver.example.com/user/my-user/lab",
"JUPYTER_TOKEN": "<your Jupyter token>",
"JUPYTER_USERNAME": "my-user"
}
}
}
}
Tools
Your coding agent can then use the following tools:
| Tool | Description |
|---|---|
jupyter_terminal_run |
Run a shell command and return JSON with output, exit_code, terminal_name, timed_out, and elapsed time. |
jupyter_terminal_write |
Send raw text to the terminal for interactive prompts. |
jupyter_terminal_list |
List Jupyter terminals visible to the server. |
jupyter_terminal_run wraps each command with unique begin/end markers so the agent receives only the command's output and exit status. If a command times out, the server sends ^C to the terminal and returns the output collected so far.
[!WARNING] Make sure to gate access to
jupyter_terminal_runandjupyter_terminal_writeappropriately. These tools can be used to run arbitrary shell commands on the JupyterLab host, which is a security risk.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。