Skip to main content
Glama
Goose4500

mojo-kernels

by Goose4500
README.md
# Mojo MCP

FastMCP (Python) → Python extension bindings → native Mojo 1.0 CPU kernels.

## Run

Requires Linux/macOS supported by Mojo and Python 3.12 or 3.13. `uv` installs
Mojo 1.0.0 along with the Python dependencies; no separate compiler setup is needed.

```sh
uv sync
uv run mojo-mcp
```

The default transport is stdio: an MCP client launches this process and exchanges
JSON-RPC on stdin/stdout. It is not an interactive shell. Logs go to stderr.
The first startup compiles `_kernels.mojo` into a cached shared library through
`mojo.importer`. Subsequent startups reuse it; source changes trigger recompilation.
Allow extra time for first startup, or prewarm with:

```sh
uv run python -c 'from mojo_mcp.server import mcp'
```

The package directory must be writable for `__mojocache__`. This project ships
Mojo source rather than a platform-specific precompiled binary.

## MCP client configuration

Replace the project path and use an absolute `uv` executable path if your client
cannot find it on PATH:

```json
{
  "mcpServers": {
    "mojo-kernels": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/mojo-mcp", "mojo-mcp"]
    }
  }
}
```

## Pi feedback loop

This checkout is registered as `mojo-kernels` in `~/.pi/agent/mcp.json` with
`directTools: true`, using an absolute `uv` path and this project's directory.

1. Run `/reload` in Pi after changing its MCP configuration.
2. Run `/mcp reconnect mojo-kernels` to populate/refresh tool metadata. If direct
   tools are not visible yet, run `/reload` again after the connection succeeds.
3. Ask the agent to call `kernel_info`, `dot_product`, or `axpy` on `mojo-kernels`.
4. After editing Python or Mojo code, run `/mcp reconnect mojo-kernels` to restart
   the process; the Mojo importer recompiles changed source automatically.
   If tool names or schemas changed, follow with `/reload`.

The adapter's proxy also supports discovery via `mcp({server: "mojo-kernels"})`.

## Tools

- `dot_product(x, y)` → `{ "value": 32.0 }` for `[1,2,3]` and `[4,5,6]`.
- `axpy(alpha, x, y)` → `{ "values": [6.0,9.0,12.0] }` for alpha `2` and those vectors.
- `kernel_info()` → backend, precision, and input limit.

Vectors must have equal lengths, contain finite numbers, and have at most 10,000
elements. Empty inputs return zero/an empty vector. Non-finite outputs (including
floating-point overflow) are reported as tool errors, not invalid JSON values.

## Streaming telemetry server

```sh
uv run mojo-telemetry
```

Open **http://127.0.0.1:8766** and click **Start demo**. FastAPI accepts batches;
a persistent Mojo ring buffer maintains rolling statistics and detects spikes;
WebSockets stream summaries to a live chart. The MCP server is unchanged.

See [`docs/telemetry.md`](docs/telemetry.md) for the ingestion API, architecture,
limits, and lifecycle commands. Local, single-process, in-memory prototype.

## Network behavior simulator

```sh
uv run mojo-network
```

Open **http://127.0.0.1:8767** to experiment with bandwidth, latency, packet loss,
queue capacity, timeouts, and retry backoff. Compare retries against a no-retry
baseline and export the results. Mojo runs the discrete-event model; Python serves
the dashboard. No real network traffic is generated by the simulation.

See [`docs/network.md`](docs/network.md) for model assumptions, API, and limits.

## Explore Mojo without MCP

[`playground/`](playground/README.md) contains three creative standalone programs:
a ray-traced alien planet, a retro music synthesizer, and a procedural cave world.
The seven introductory examples live in `playground/fundamentals/`.
No server changes or additional packages needed.

## Development

```sh
uv run pytest
uv run ruff check .
uv run ruff format --check .
```

`tests/` exercises actual compiled kernels, MCP calls, validation, and a real
stdio subprocess. No mock or Python fallback implements the arithmetic.

### Add your own kernel

1. Add native computation to `src/mojo_mcp/_kernels.mojo`. Keep Python object
   conversion at the binding boundary, outside hot loops.
2. Wrap it in a function taking/returning `PythonObject` and register it with
   `module.def_function[...]` in `PyInit__kernels`.
3. Add a typed `@mcp.tool` function in `src/mojo_mcp/server.py` with input limits
   and JSON-safe output validation. Call the extension with positional arguments.
4. Add native and MCP tests, then restart the server to compile your changes.

### Scope and performance

Mojo 1.0 supports this architecture, but its Python extension bindings are still
marked **beta** upstream. This starter uses the official importer and bindings,
not ctypes, subprocess-per-call, arbitrary code execution, or a CLI JSON bridge.

These are simple Float64 **CPU** kernels, not GPU kernels. They copy Python lists
into native Mojo lists and copy results back. MCP JSON serialization, conversion,
and Python's GIL can dominate small operations; this is not a claim of speedup
over NumPy. Benchmark your real workload before adding SIMD, GPU execution, or
buffer-based zero-copy input. The server is local stdio only; remote deployment
would need authentication, transport/resource limits, and operational hardening.

References: [Mojo Python bindings](https://mojolang.org/docs/manual/python/mojo-from-python),
[FastMCP](https://gofastmcp.com/).