Skip to main content
Glama

loommux

CI PyPI Python >=3.13 License

loommux is a Model Context Protocol (MCP) server for persistent, inspectable IPython work. A loommux server owns logical kernel resources on behalf of MCP sessions. Each resource has an independent namespace, execution history, client lease set, and replaceable kernel process. Python variables, imports, and definitions survive from one submitted cell to the next inside that selected resource.

The project is for MCP clients and agents that need more than a one-shot subprocess. It makes a running cell observable without losing it: callers can wait later, inspect its state, read a selected output stream by line range, search retained output, interrupt the active cell, or restart the kernel.

What It Provides

  • Session-private kernel resources by default and explicitly named shared resources when clients need one collaborative namespace.

  • One persistent IPython session, execution sequence, and retained history per logical resource.

  • Activity or standard MCP-ping leases with automatic orphan reclamation.

  • A strictly increasing positive integer execution coordinate for every accepted cell during its logical resource's lifetime.

  • In-memory output retained separately as combined, stdout, stderr, result, and traceback streams.

  • IOPub-order combined output, including IPython-style Out[execution]: labels for display results.

  • Terminal-formatted IOPub text normalized into ordinary append-only text transcripts before it reaches public output.

  • A non-blocking execution model: a tool-call timeout ends only that MCP call; it does not terminate the Python cell.

  • Explicit interrupt and kernel-reset operations, with preserved historical execution records after a reset.

  • A single MCP entrypoint with content-only defaults and an explicit structured result mode.

loommux is intentionally not a multi-user notebook service, a durable job queue, or a sandbox. Kernel state and execution records are memory-only and belong to their logical resource; server shutdown retires every resource.

Related MCP server: LLM Python Code Sandbox

Requirements And Installation

loommux requires Python 3.13 or newer. The installed package brings the runtime dependencies needed to launch an IPython kernel.

python -m pip install loommux

Windows

Native Windows support covers Windows 10 and Windows 11 with CPython 3.13 or newer. Install into the interpreter that the MCP host will use:

py -m pip install loommux

The installed command is loommux.exe. Point an MCP host directly at that executable rather than through a shell wrapper, and use an absolute Windows workspace path for cwd:

{
  "mcpServers": {
    "loommux": {
      "command": "C:\\workspace\\.venv\\Scripts\\loommux.exe",
      "args": ["--result-mode", "structured"],
      "cwd": "C:\\workspace"
    }
  }
}

loommux launches the kernel with the same interpreter as loommux.exe, keeps its IPython and Jupyter state in a private temporary directory, and uses a Windows Job Object so restart and server shutdown also end child processes launched by the kernel. A submitted cell remains arbitrary Python: commands inside that cell must target the operating system on which the kernel is running. WSL is a separate Linux deployment, not a substitute for native Windows coverage. Because IPython kernels do not accept Ctrl+C through this entry point on Windows, interrupt replaces the private kernel after marking the active cell interrupted; later cells use the fresh kernel.

The package installs one console command:

loommux                   content-only results over Studio stdio
loommux --server          content-only results over Streamable HTTP

loommux uses an MCP Studio or host's child-process stdio connection by default. --server starts a Streamable HTTP service with configurable --host, --port, and --path. Both forms return only content by default. --result-mode structured is the explicit opt-in that additionally returns structuredContent.

For development, use uv:

git clone https://github.com/MichengLiang/loommux.git
cd loommux
uv sync --locked --group dev

Default Studio Connection

loommux defaults to MCP stdio transport and returns model-oriented content only. This is the Studio-compatible default and prevents a client from preferring raw structuredContent over the presentation intended for the model.

The server process's working directory is the default kernel workspace. A generic MCP configuration therefore assigns the desired project directory as the command's cwd:

{
  "mcpServers": {
    "loommux": {
      "command": "loommux",
      "cwd": "/absolute/path/to/your/workspace"
    }
  }
}

The exact enclosing configuration shape depends on the MCP host. The material facts are that the host starts loommux, the process runs in the intended workspace, and the Python environment running loommux can import ipykernel.

On startup, loommux resolves its workspace, builds a kernel launch from the server interpreter, and starts the kernel before accepting MCP tools. Server startup fails rather than exposing a partially configured execution service.

HTTP Server And Structured Opt-In

loommux --server exposes the same tools, input schemas, execution behavior, and model-readable text over Streamable HTTP. It remains content-only unless --result-mode structured is explicitly supplied.

Start a loopback-only content-only HTTP service from the workspace you want the kernel to use:

cd /absolute/path/to/your/workspace
loommux --server --host 127.0.0.1 --port 8801 --path /mcp

Its MCP endpoint is http://127.0.0.1:8801/mcp. --result-mode structured is available only when a client genuinely needs the raw status object:

loommux --server --result-mode structured --host 127.0.0.1 --port 8801 --path /mcp

MCP Studio, Inspector, and other Streamable HTTP clients use the same endpoint URL. There is no separate Studio protocol. The complete matrix, subprocess configuration examples, and security guidance are in MCP Connection Guide.

HTTP is a deployment boundary, not a different execution model: the tools, resource-local execution sequences, output streams, workspace resolution, and presentation rules are the same as the stdio server. The HTTP application also serves a resource console at / and operational JSON APIs under /api. Binding it beyond the local machine exposes arbitrary Python execution and requires network controls and authentication outside loommux.

Kernel Resources And Client Leases

An ordinary MCP connection selects a resource without changing the eight-tool surface. Without an additional header, its MCP Session ID addresses a private workbench. X-Loommux-Resource selects a named shared workbench; every participating MCP session still holds an independent lease.

The server publishes the current lease policy at /api/lease-policy. The included loommux.client.LeaseAwareClient discovers and pins that policy generation before initialization and sends standard MCP ping while a heartbeat lease is active:

from loommux.client import LeaseAwareClient


async with LeaseAwareClient(
    "http://127.0.0.1:8801/mcp",
    "analysis-agent",
    resource_name="shared-analysis",
) as client:
    result = await client.call_tool(
        "run_cell",
        {"freeform": "value = 1\nprint(value)"},
    )

The operator label is optional. Omitting it or passing None leaves the X-Loommux-Operator header absent, so the server uses its session-derived fallback display name.

The complete runnable client-cooperation example is in examples/lease-aware-client.

The complete identity, lifecycle, policy, orphan-execution, control API, and source-ownership contract is documented in Kernel Resource Daemon Design.

Workspace And Interpreter

Workspace selection occurs when the server process starts. loommux does not provide a runtime tool that changes the workspace or Python interpreter.

By default, the server's current working directory is the workspace and the interpreter that launched loommux launches the kernel. This preserves the same virtual environment that imported loommux and avoids an ambiguous second Python-selection mechanism.

LOOMMUX_WORKSPACE_CONFIG is the only optional workspace configuration entrance for the Python/IPython loommux server. Set it to the absolute path of a trusted Python resolver defining resolve_workspace(launch_cwd: Path) -> Path | str. loommux never searches or executes loommux_workspace.py, .codex, or any other workspace-tree file or marker. Resolver failures prevent startup before tools are available.

The generic and Codex resolver examples are inert until explicitly selected through that environment variable. See workspace configuration and the canonical Coding Agent Control Plane Design for the complete contract.

Execution Model

Each accepted run_cell submission creates an execution record with one public identity:

execution: positive integer

The sequence begins at 1 for a newly provisioned logical resource and increases only when a cell is accepted. Loommux accepts one running cell at a time inside each resource; separate resources may execute concurrently. A second run_cell call against the same busy resource is rejected with status="busy"; it is not queued.

An execution can be running, completed, error, interrupted, or killed. Python errors are recorded execution states, not MCP transport failures. The error summary identifies the exception while the collected traceback remains available from the execution's traceback stream.

The integer is owned by loommux rather than copied from IPython's kernel-local execution counter. It stays stable for the logical resource, including across restart. When a cell yields a text/plain display result, loommux authors the combined log with its own stable coordinate:

Out[5]: 42

After a reset, the replacement IPython kernel may have restarted its internal counter, but the next loommux execution number remains consecutive and prior records remain readable.

MCP Tools

All tools below are exposed by the single loommux entrypoint. Calls that take an optional execution share one selection rule: an explicitly supplied positive integer selects that record; otherwise loommux selects the current running record, then the most recently accepted record. With neither, the tool returns execution_not_found.

Tool

Purpose

run_cell(freeform)

Submit one loommux IPython cell to the persistent kernel and wait for its initial result.

status()

Inspect the workspace, its authored source category, interpreter, kernel PID, busy state, and current or recent execution.

execution_status(execution=None)

Inspect lifecycle and diagnostic metadata without returning the full output body.

read_output(...)

Read a selected execution stream, optionally by line range and with per-line clipping.

search_output(...)

Search a selected output stream using literal text or regular expressions.

wait(execution=None, timeout_seconds=30)

Wait for an execution without interrupting it.

interrupt()

Send an interrupt signal to the current running execution.

restart()

Restart the kernel while preserving execution records and the resource-local sequence.

Submitting A Cell

run_cell accepts one freeform loommux IPython cell. Ordinary source and the resulting Python values of validated Apply Patch literals are available to later cells in the same selected logical resource.

import math
radius = 3
math.pi * radius**2

Apply Patch Literals

Use an outer triple-double-quoted literal containing a valid Apply Patch program to pass patch text through a Python cell. The exact *** Begin Patch and *** End Patch markers, valid file-operation controls, and hunk lines are validated before loommux converts the literal into an equivalent Python str. The patch text remains part of the resulting value, including embedded triple quotes, backslashes, and braces.

patch = f"""
*** Begin Patch
*** Update File: example.py
@@
+message = r"""
+hello
+"""
*** End Patch
"""

patch contains the complete Apply Patch program. The outer r and f prefixes do not apply raw-string or f-string interpretation to the converted patch text. Marker-shaped text with invalid patch grammar is ordinary Python source and is not converted. See Apply Patch Literal Transform Design for the full contract and acceptance rules.

The default initial wait for one MCP call is 10 seconds. A cell can make its complete submission policy explicit with a Loommux control directive:

# loommux: --wait 120
build_report()

--wait only changes how long that run_cell call waits. It does not limit Python runtime, interrupt the cell when time expires, modify later calls, or add a variable to the kernel. A malformed or duplicated option returns invalid_loommux_directive before an execution is allocated or source is submitted. Valid directive lines are transport-only metadata: Loommux consumes them before IPython receives the cell, so they do not appear in IPython history or execution records. A directive may therefore precede a %% cell magic.

When the call returns while the cell is still running, use wait, execution_status, read_output, search_output, interrupt, or restart to continue observing or controlling the same execution.

Output Streams And Long Output

Each execution retains five append-only text projections:

Stream

Contents

combined

stdout, stderr, display results, and tracebacks in IOPub arrival order.

stdout

Python stdout stream events.

stderr

Python stderr stream events.

result

text/plain from IPython execute-result and display-data events.

traceback

Traceback text from Python error events.

Completed combined output of at most 5,000 o200k_base tokens is returned by run_cell and wait beneath an In [execution]: header. A display result then keeps its IPython-style Out[execution]: line; a silent cell returns only the input header, and stdout or traceback remains in its original combined order. For an execution that is still running, or for an unmarked terminal execution whose combined output exceeds 5,000 tokens, the response retains the record but omits the full body. Its omission notice reports the combined output's total lines, Unicode code point characters, and UTF-8 size using one binary unit (B, KiB, MiB, and so on). The structured run_cell, wait, and execution_status surfaces expose the corresponding exact counts as output_total_lines, output_total_characters, and output_total_utf8_bytes. The output is not discarded; the notice itself names the recovery paths, and the caller reads or searches the retained text through read_output and search_output, or requests the complete body with the # loommux: --full-output directive. Token counting is required for this automatic delivery policy; if the o200k_base tokenizer cannot be loaded, the call fails instead of silently changing to another limit.

read_output uses start:stop inclusive line coordinates. Positive endpoints are 1-indexed, endpoints may be omitted, and negative endpoints count from the end of the selected stream:

:10    first 10 lines
-10:   final 10 lines
20:40  lines 20 through 40
3:3    only line 3

When the caller has determined that the selected stream must be consumed in full, omit line_range. read_output returns all of its lines in one response, so there is no need to divide the read into consecutive small ranges.

max_chars clips each returned line without changing stored text or line coordinates. search_output supports literal, regex, and auto matching. In auto mode, loommux treats the query as a regular expression when it compiles and falls back to literal matching when it does not. Search results preserve original line numbers, mark matching lines with M, and mark selected context lines with C.

Requesting Complete Output

When a cell's entire terminal combined output is the intended result, include --full-output in a Loommux control directive:

# loommux: --full-output
build_report()

The option applies only to that execution. Once the execution is terminal, it bypasses the normal 5,000-token delivery threshold and makes run_cell or a later wait return the complete collected combined output. It does not cause partial running output to be returned and does not alter the input or behavior of read_output and search_output.

The full-output and wait options are independent and may appear in the same directive:

# loommux: --wait 120 --full-output
build_report()

They may also be split across two directives:

# loommux: --wait 120
# loommux: --full-output
build_report()

Interrupting And Resetting

interrupt requests an interrupt for the current running cell. An interrupt_sent response only confirms signal delivery; the execution reaches its final state after the kernel reports IOPub idle.

restart is stronger: it stops the existing kernel and starts a replacement in the same workspace with the same interpreter. A running record is marked killed. Reset does not erase stored executions, their output, or the sequence counter, so historical records can still be read by their integer execution value and the next accepted cell receives the next number.

Stopping the loommux server retires all resources. Their kernels, namespaces, execution-record tables, output streams, and sequences are not persisted to disk. Recycling one resource has the same persistence boundary for that resource; a subsequently provisioned resource begins a fresh sequence at 1.

Security

Arbitrary Python execution is loommux's central capability. Treat the MCP client, its process account, installed packages, the selected workspace, and any reachable network endpoint as parts of the same security boundary. Give the server access only to files, environments, and network resources the MCP client is authorized to use.

The stdio server is generally the least exposed deployment mode. The HTTP server must never be placed directly on an untrusted network. For a vulnerability in loommux itself, use the private reporting process in SECURITY.md, not a public issue.

Architecture And Documentation

The runtime is deliberately divided into narrow responsibilities:

loommux/
    session.py
        Owns one persistent IPython namespace, execution identity, selection,
        waiting, control operations, and historical execution records.
    kernel/
        launch.py
            Builds the interpreter command, child environment, and private root.
        runtime.py
            Owns Jupyter kernel process lifecycle and platform containment.
        session.py
            Correlates IOPub messages with the active execution record.
    execution/
        record.py
            Stores one execution's lifecycle facts and normalized projections.
        events.py
            Names visible text, image, and delivery-failure events.
        logs.py
            Provides append-only streams, line ranges, clipping, and search.
        terminal.py
            Removes terminal controls while preserving chunk boundaries.
    submission/
        cell.py
            Combines directive consumption and source transformation into one
            prepared cell passed to the session.
        directives.py
            Parses and consumes submission-owned control directives.
        apply_patch_literals.py
            Converts valid Apply Patch literals before kernel submission.
    mcp/
        factory.py
            Registers MCP tools that consume the protocol-neutral session.
        result.py
            Projects session facts into MCP text, structured, and image content.
        presentation.py
            Renders MCP-facing model-readable text.
        entrypoints.py and server.py
            Select MCP transport and expose the installed command.

The workspace authorization and resolution modules remain at the package boundary until their independent configuration work is complete. They are deliberately not mixed into this structural change.

The top-level loommux package imports only the protocol-neutral Python session API. FastMCP is entered explicitly through loommux.mcp; the runtime does not depend on its transport consumer.

The current public contract is documented in Coding Agent Control Plane Design. Focused references cover freeform cell control, complete-output control, workspace configuration, and the changelog.

Development And Release Checks

Run the Python checks from the repository root:

uv run pytest
uv run ruff check src tests examples
uv run basedpyright src
uv build --out-dir dist
uv run twine check dist/*

The project metadata declares this README as the package readme:

[project]
readme = "README.md"

Consequently, the same document is rendered on PyPI when a new release is built and uploaded. The explicit source-distribution allowlist includes this file, the runtime package, tests, and public documentation while excluding workspace-only material.

See CONTRIBUTING.md for contribution expectations.

License

Copyright 2026 MichengLiang.

loommux is licensed under the Apache License, Version 2.0.

Available Tools

8 tools
execution_statusA

返回一个 execution 的状态与元数据,不返回完整输出正文。

选择规则

提供 execution 时,只选择该正整数记录。省略时,先选择当前 running 记录;不存在 running 记录时,选择最近一次被接受的记录; 两者都不存在时返回 execution_not_found

ParametersJSON Schema
NameRequiredDescriptionDefault
executionNo要查看的正整数执行编号。省略时使用当前记录,随后 使用最近记录。

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of disclosing behavior. It does disclose the return type (status/metadata, not full output) and a specific error condition, but it does not explicitly state whether the operation is read-only, whether it has side effects, or any other behavioral constraints such as rate limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-organized, using a short introductory sentence followed by a clear '选择规则' section. Every statement serves a useful purpose, and there is no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description explains what the tool returns at a high level and gives the selection rules and error condition, which is enough to call it. However, there is no output schema and the description does not enumerate the specific status values or metadata fields returned, leaving the response shape somewhat underspecified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already fully documents the single parameter, including its type, nullability, default, and meaning. The description reinforces this by explaining the exact fallback resolution order when the parameter is omitted, adding clear value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool returns execution status and metadata and explicitly excludes the full output body, which distinguishes it from output-reading tools. However, it does not explicitly differentiate itself from the sibling tool named 'status', so some ambiguity remains.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit selection rules for the 'execution' parameter: use the provided ID, fall back to the current running execution, then to the most recent accepted execution, and return 'execution_not_found' if none exist. It gives clear operational guidance for the parameter, though it does not discuss when to prefer this tool over sibling tools other than implying that full output is obtained elsewhere.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

interruptA

向当前正在运行的 execution 发送 kernel 中断信号。

中断语义

该工具只作用于当前 running 记录。信号已发送不等同于记录已终态: kernel 到达 IOPub idle 后,记录才会报告 interruptederror 或其他最终状态。kernel 空闲时返回 idle。

Returns: 已发送信号时返回目标 execution;kernel 空闲时返回 idle。

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full responsibility for transparency. It explains the interrupt semantics, including that sending the signal does not immediately finalize the record, and describes the return behavior in different states. This gives a complete picture of the tool's side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured, starting with the primary action and then providing semantic details. It is not overly verbose and conveys necessary information efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity and lack of output schema, the description is sufficiently complete. It covers the action, side effects, and return values. No critical information appears to be missing for an agent to use the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has no parameters, so there is nothing to explain. According to the rubric, a baseline of 4 is appropriate for zero parameters, and the description does not need to add any parameter-related meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action: sending a kernel interrupt signal to the currently running execution. It also explains the intended effect, leaving no ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides guidance by specifying that the tool only affects the current running record. This implies it should be used when there is an active execution, and it clarifies the expected behavior when the kernel is idle, helping the agent decide when to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_outputB

读取一个 execution 的指定输出流。

选择与流

execution 的选择规则与 execution_status 相同。stream 只能为 combinedstdoutstderrresulttraceback

行坐标

line_range 使用 start:stop。正数端点是从 1 开始的流行号, stop 包含在范围内;端点可省略,负数端点从所选流尾部计数。:10 读取前十行,-10: 读取后十行,3:3 只读取第三行。

完整读取

调用者已确定需要完整消费所选流时,省略 line_range。工具会在一次响应 中返回全部行,无需把阅读拆成连续小范围。

ParametersJSON Schema
NameRequiredDescriptionDefault
streamNo输出流;默认 ``combined``,其余值为 ``stdout``、``stderr``、 ``result`` 与 ``traceback``。combined
executionNo要读取的正整数执行编号。省略时使用当前记录,随后 使用最近记录。
max_charsNo每个返回行允许显示的最大字符数;必须为正数。超出 部分只在响应中裁切,不改变已保存文本或行坐标。
line_rangeNo``start:stop`` 行范围;已确定需要完整消费所选流时省略, 工具会一次返回全部行,无需拆分为多个小范围。

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses the truncation behavior of max_chars (only in response, does not alter saved text or line coordinates). It does not mention any other side effects, permissions, or that it is a read-only operation, so transparency is partial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured into sections (选择与流, 行坐标, 完整读取) which aids readability. However, some repetition occurs (e.g., line_range explanation appears both in the main text and in the parameter schema). It is not overly verbose but could be more concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description conveys that the tool returns lines of output (via '返回行' and truncation context) and explains how to request subsets. Since there is no output schema, this explanation is sufficient for basic usage, but it does not detail the exact return structure (e.g., whether it returns a list, the format of each line). Overall, it is complete enough for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema covers all 4 parameters with descriptions, achieving 100% coverage. The tool description repeats some parameter details but does not add significant new meaning beyond the schema. Baseline 3 is appropriate given the high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: reading a specified output stream of an execution. The verb '读取' (read) is specific and the resource 'execution 的输出流' is unambiguous. It does not explicitly differentiate from sibling tools like search_output, but the core purpose is clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides some usage guidance, such as how to select the execution (rules same as execution_status) and when to omit line_range for full consumption. However, it does not explicitly mention when to use this tool over alternatives like search_output, leaving some ambiguity for an agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

restartA

重启 IPython kernel,并保留当前持久 IPython 会话的 execution 历史。

重置边界

若存在 running execution,它会先标记为 killed;随后旧 kernel 停止并创建替代 kernel。已存在的记录及其输出流仍可按原整数 execution 读取,下一次接受的 cell 使用连续的下一个编号。

Returns: 新 kernel 的状态与 PID;重启失败时返回 workspace 或 kernel 启动错误。

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description outlines the behavioral sequence (killing running executions, stopping old kernel, creating new kernel) and explicitly notes that execution history is preserved. It also addresses the edge case of a running execution. However, it does not mention potential side effects on non-persistent state or any error handling beyond return values.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, well-structured with a clear purpose and a separate section for the reset boundary. It avoids unnecessary verbosity while covering key behavioral aspects.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description includes explicit return values (new kernel status and PID, or error on failure) and covers the main execution conditions. It is complete for an agent to understand the tool's output without additional information.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has no parameters, and the schema coverage is 100%, so the baseline is 3. The description does not need to explain parameters, and it correctly omits them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: restart the IPython kernel while preserving execution history. It specifies the verb (restart) and the resource (IPython kernel), and it is distinct from sibling tools like run_cell or interrupt.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly mention when to use this tool versus alternatives. It implies usage for restarting the kernel but lacks guidance on scenarios where this is preferable to other tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_cellA

向持久 IPython kernel 提交一个原始 IPython cell。

请你使用 IPython 的思想来优雅使用本系列工具。

输入

接受一段 loommux IPython cell 源码。普通 Python 文本使用默认策略;若作者 需要声明本次 cell 的观察策略,使用位于物理行首的 # loommux: 控制 注释。Loommux 在提交前验证并完全消费有效控制注释,因此它们不会进入 IPython history 或下游 cell-magic body。变量、导入和其他 namespace 状态会 与当前持久 IPython 会话中的后续 cell 共享。

等待上限

本次调用默认最多等待 10 秒。# loommux:--wait 正有限十进制 值只覆盖本次调用的等待上限::

# loommux: --wait 120
build_report()

# loommux: --wait 120# loommux: --full-output 可写在同一条 或不同的控制注释中。重复选项、未知选项、缺少值或非正值会返回 invalid_loommux_directive,不会分配 execution 或提交 kernel。等待 到期不会中断仍在运行的 cell;directive 不改变 Python runtime 或后续 调用的等待上限。

完整输出

若任一有效 # loommux: 控制注释包含 --full-output,该 execution 在终态时直接交付完整 combined 正文,不受默认 5,000-token 交付阈值限制::

# loommux: --full-output
print("\n".join(generate_manifest()))

--wait--full-output 可以组合为 # loommux: --wait 120 --full-output。这些选项只作用于本次 execution。有效控制注释在提交前被 Loommux 完全消费,不会进入 IPython history、cell magic body 或 execution 响应。在明确需要完整阅读某些信息, 例如阅读某些文件、资料时,使用该选项避免无意义的反复阅读开销。

图像展示

IPython display() 产生的 PNG、JPEG、WEBP 或单帧 GIF 图像会按输出 顺序直接交付给agent。普通 display(image) 使用高视觉细节;本次展示 需要整体确认或密集文字时,分别书写 display(image, metadata={"detail": "low"})display(image, metadata={"detail": "original"})detail 只作用于这一处 display() 调用。

执行编号与后续操作

每个已接受的提交都会获得一个连续递增的正整数 execution。后续工具 使用它定位当前持久 IPython 会话中的这次执行。若执行仍在运行,或未标记 --full-output 的 combined 输出超过 5,000 token,响应不携带完整输出 正文;行数、Unicode code point 字符数和 UTF-8 字节数描述同一份 normalized combined 文本。使用 wait 等待,使用 execution_status 查看状态,使用 read_outputsearch_output 读取或搜索保留的输出。

ParametersJSON Schema
NameRequiredDescriptionDefault
freeformYes原始 IPython cell 源码文本。

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure, and it does so thoroughly. It discloses the default 10-second wait, how '--wait' overrides it, that control comments are fully consumed and do not enter history or cell-magic bodies, that waiting expiry does not interrupt a running cell, the 5,000-token output truncation threshold, the effect of '--full-output', image display behavior with detail metadata, and the execution numbering scheme. This is comprehensive transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well-structured with clear sections (输入, 等待上限, 完整输出, 图像展示, 执行编号与后续操作). Every section adds essential information, and the main purpose is front-loaded in the first sentence. It could be slightly more concise, but the organization makes it easy to navigate.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with one parameter and no output schema, the description is exceptionally complete. It covers input format, control directives, wait behavior, output truncation and the full-output override, image display options, execution numbering, and explicitly mentions the sibling tools for subsequent operations. An agent has all the information needed to invoke run_cell correctly and understand its effects.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema only describes 'freeform' as '原始 IPython cell 源码文本' (raw IPython cell source text). The description adds significant meaning by explaining the 'loommux:' control comment syntax, including '--wait' and '--full-output' options, their combinations, validation behavior, and how they affect the execution. This goes far beyond the schema's minimal description, giving the agent actionable details for constructing valid input.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action: '向持久 IPython kernel 提交一个原始 IPython cell' (submit a raw IPython cell to a persistent kernel). It distinguishes itself from sibling tools by positioning itself as the submission entry point, with siblings like wait, execution_status, read_output, and search_output described as subsequent operations for handling the execution.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for using the tool, including when to use the '--full-output' option (when full reading of information like files or materials is needed to avoid repeated reading overhead) and how to combine options. It also implies that for checking status or reading output, one should use the sibling tools (wait, execution_status, read_output, search_output), but it doesn't explicitly state when not to use run_cell itself. The guidance is implicit but effective.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_outputA

在一个 execution 的指定输出流中搜索文本或正则表达式。

选择与匹配

execution 的选择规则与 execution_status 相同;可选的 stream 值与 read_output 相同。query_mode="literal" 按字面文本匹配,query_mode="regex" 要求 query 是有效正则, query_mode="auto" 先按正则解释,仅在编译失败时回退到字面匹配。

命中上下文

每条命中保留原始所选流行号,并以 M 标记;前后上下文行以 C 标记。

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes要匹配的字面文本或正则表达式。
streamNo输出流;默认 ``combined``,其余值为 ``stdout``、``stderr``、 ``result`` 与 ``traceback``。combined
executionNo要搜索的正整数执行编号。省略时使用当前记录,随后 使用最近记录。
max_charsNo每个返回行允许显示的最大字符数;必须为正数,且只 裁切响应文本。
query_modeNo匹配解释方式:``literal``、``regex`` 或 ``auto``; 默认 ``auto``。auto
ignore_caseNo为 true 时忽略大小写。
context_afterNo每个命中之后附加的相邻行数;必须大于或等于 0。
context_beforeNo每个命中之前附加的相邻行数;必须大于或等于 0。

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description does not include any annotations, so it carries the full burden of disclosing behavioral traits. It explains how the tool selects executions (current or most recent when omitted), how matching modes work, and how context lines are added. However, it does not disclose potential side effects (e.g., it is read-only), whether it modifies any state, or any error conditions. The description is mostly about operation mechanics, not behavioral caveats, so it partially covers transparency but leaves gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with clear section headers for '选择与匹配' and '命中上下文', and the prose is concise. Each sentence provides useful information without redundancy. The description is appropriately sized for the complexity of the tool, covering key aspects without unnecessary verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of this tool (search with modes, context lines, stream selection) and no output schema, the description is quite complete. It provides enough information for an agent to understand how to use it correctly. It references sibling tools for parameter selection, which reduces the need for repeating those rules. However, it could mention that this tool is read-only (non-destructive) and what the return format looks like (a list of matches with context), but the absence of an output schema is somewhat compensated by the description. Minor gaps exist but overall it's sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers 100% of the parameters with descriptions. The description adds further semantics by explaining the selection rules for 'execution' (same as execution_status) and 'stream' (same as read_output), which are not fully apparent from the schema alone. It also clarifies the behavior of query_mode with examples (literal vs regex vs auto fallback). However, some parameters like max_chars have a schema description already, and the additional description of truncation is consistent but not substantially new. Overall, the description adds meaningful context beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: searching text or regex in specified output streams of an execution. It names the resource ('execution'), the action ('search'), and the target (output stream), which distinguishes it from sibling tools like read_output (which reads without searching) and execution_status (which retrieves status). However, it does not explicitly name a sibling tool for contrast, though the references to read_output and execution_status in the description imply differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage guidance: it explains how to select the 'execution' parameter (same rules as execution_status), how to choose the 'stream' parameter (same values as read_output), and how query_mode behaves with literal vs regex vs auto. It also explains context lines and max_chars truncation. However, it does not explicitly state when to use this tool instead of alternatives like read_output, though the contrast is implied by describing search-specific features.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

statusB

返回 workspace、kernel 与最近执行记录的观察状态。

状态范围

返回当前 IPython 工作台启动时解析的 workspace、其 workspace_resolution 来源 类别、Python 解释器、kernel PID、kernel 是否已启动,以及 kernel 是否 正忙。workspace_resolution 只能是 launch_cwdexplicit_config;它不公开 resolver 的路径或内容,也不公开 kernel session 的 private runtime root。忙碌时 current_execution 是正在 运行的正整数执行编号;空闲时 recent_execution 是最近一次被接受的 执行编号。kernel-local execution count 只用于诊断,不能用来选择 loommux execution。

.. code-block:: text

可见标签 In [N]
        =
loommux execution N
        !=
IPython kernel-local execution_count

IPython 通过原生 ZMQ 协议连接,拥有完整能力。

Returns: 当前 IPython 工作台与 kernel 的状态快照。

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the transparency burden. It is unusually explicit about what the tool does not expose (resolver path/content, private runtime root) and that execution counts are diagnostic-only, which gives users a clear behavioral boundary.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is organized with headings and a code block, but it repeats the same summary sentence ('Returns workspace, kernel, and recent execution status') multiple times. Some redundancy makes it slightly less concise than necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description supplies substantial detail about return fields, including enum values for workspace_resolution, busy/idle semantics, and the meaning of execution IDs. It is not perfectly precise about JSON structure but is sufficiently complete for a status tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and the schema coverage is 100%, so the baseline score applies. There are no parameter semantics to explain beyond the empty schema, and the description does not need to add more.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool returns workspace, kernel, and recent execution status, using a specific verb and resource. It does not explicitly distinguish itself from the sibling execution_status tool, but the detailed field list makes its purpose evident.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not say when to prefer this tool over alternatives such as execution_status or read_output. It provides no usage context, prerequisites, or when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

waitA

等待一个 execution 结束,或在指定时限到达时返回其当前状态。

选择与等待

execution 的选择规则与 execution_status 相同。等待 到期只结束本次工具调用,不中断 Python cell。后续可再次调用本工具, 或用 read_output 查看已到达的输出。

完整输出交付

当所选 execution 的原始 run_cell 请求含有效 --full-output 且已达到 终态时,本工具直接返回完整 combined 正文,不应用默认 5,000-token 省略。该策略仅保留为 private runtime state;仍在运行的 execution 继续 返回 running,而非不完整正文。

ParametersJSON Schema
NameRequiredDescriptionDefault
executionNo要等待的正整数执行编号。省略时使用当前记录,随后 使用最近记录。
timeout_secondsNo本次调用最多等待的正数秒数;默认 30 秒。

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses key behavioral traits: it waits for completion or timeout, does not interrupt the cell, can be called again, and returns full output under certain conditions. Without annotations, this is good transparency, though it could mention potential side effects or error cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with sections, but it contains some redundancy, particularly the 'full output delivery' section which repeats similar wording about full-output and 5,000-token omission. Still, it's relatively concise and organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple tool with two parameters, the description covers the main aspects: what it does, selection rules, timeout behavior, and output handling. No output schema exists, so return value details are not required. It's complete enough for an agent to use correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Both parameters (execution and timeout_seconds) are described in the schema with default values and meanings. The description adds context about selection rules and timeout behavior, fully complementing the schema's 100% coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool waits for an execution to finish or returns its current status after a timeout. It names the specific resource (execution) and the action (wait/return status), though it doesn't explicitly contrast with sibling tools like execution_status, which is a minor gap.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explains when to use the tool: to wait for an execution, and mentions that timeout doesn't interrupt the Python cell. It also references read_output as an alternative for viewing output later. However, it doesn't explicitly say when to prefer this over execution_status or other siblings, though the context is implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 16 tool updatesv0.1.13
    • Addedexecution_status
    • Addedinterrupt
    • Removedinterrupt_python
    • Removedpython_execution_status
    • Removedpython_status
    • Addedread_output
    • Removedread_python_output
    • Removedreset_python
    • Addedrestart
    • Addedrun_cell
    • Removedrun_python
    • Addedsearch_output
    • Removedsearch_python_output
    • Addedstatus
    • Addedwait
    • Removedwait_python
  2. 8 tool updatesv0.1.11
    • First observedinterrupt_python
    • First observedpython_execution_status
    • First observedpython_status
    • First observedread_python_output
    • First observedreset_python
    • First observedrun_python
    • First observedsearch_python_output
    • First observedwait_python

TDQS

A3.9/5.0

Scored across 8 tools

Disambiguation4/5

Each tool has a distinct role in the IPython execution lifecycle: submit, wait, interrupt, restart, global status, per-execution status, read, and search. The only real ambiguity is between status and execution_status, which are easy to confuse by name even though one is a workspace/kernel snapshot and the other is per-execution.

Naming Consistency4/5

Names are all lowercase snake_case and group logically: action tools are imperative verbs (run_cell, wait, interrupt, restart) and retrieval/query tools are noun or verb_noun forms (status, execution_status, read_output, search_output). The mix of bare verbs and noun-only status names is a minor deviation from a strict verb_noun pattern but remains predictable.

Tool Count5/5

Eight tools is well-scoped for a persistent IPython kernel server: submission, lifecycle control, and output retrieval each have dedicated tools without redundancy. No tool feels superfluous.

Completeness4/5

The core lifecycle is covered: run, wait, interrupt, restart, status, and output reading/searching. A minor gap is the lack of a way to list or enumerate past executions beyond the most recent one, which agents must track themselves.

Maintenance

ActivityActive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides persistent IPython shell sessions per conversation with DataFrame-centric architecture, enabling stateful data analysis, CLI tool execution, and integration of external MCP servers within the same workspace context.
    23
    Apache 2.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to execute Jupyter notebook cells with persistent kernel state, output persistence, and structured JSON control surface.
    2
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Provides a persistent Jupyter kernel for executing code, inspecting variables and dataframes, and checking SQL query plans, enabling agents to work with stateful Python sessions.
    -