# WinOLS MCP

WinOLS MCP is a free, MIT-licensed Rust Model Context Protocol server with a Lua bridge for inspecting and creating map definitions in WinOLS. Compatible MCP clients discover structured tools and call them over stdio.

- Human-readable documentation: https://api.redlineautohaus.com/docs/winols-mcp/
- Source: https://github.com/amirdauti/redline-autohaus-winols-mcp
- License: https://github.com/amirdauti/redline-autohaus-winols-mcp/blob/main/LICENSE
- Documentation index: https://api.redlineautohaus.com/docs/
- Version described: package version 0.1.0, including the byte-inspection and native-creation compatibility updates.

## Product status and requirements

The server and bridge are free to use, modify, and distribute under the MIT license. WinOLS and OLS530 are separate commercial EVC products; their software and licenses are not included.

The mock backend runs on Windows and Linux without WinOLS. It uses a synthetic in-memory project and resets its definitions when the server exits.

The live backend requires Windows, a licensed WinOLS 5.93 or later installation in the WinOLS 5 series, and the separately licensed OLS530 Lua plugin. A demo installation is insufficient. The live adapter is experimental. Limited checks on WinOLS 5.93.01 with OLS530 3.006 verified two map creations, property readback, map inventory, and original/current byte reads. Full live acceptance, including persistence, supported-layout coverage, and native rollback cases, remains pending. Automated tests exercise the portable server and simulated EVC functions; they do not certify a WinOLS version. See the [native verification scope](https://github.com/amirdauti/redline-autohaus-winols-mcp/blob/main/docs/winols-api.md#what-is-verified).

## Architecture and scope

```text
MCP client -- stdio --> Rust MCP server -- local mailbox files --> Lua bridge in WinOLS
                              |
                              +-- optional in-memory mock backend
```

This is a locally launched stdio server, not a hosted HTTP MCP endpoint at api.redlineautohaus.com. The live bridge works inside the active WinOLS project. Project metadata and requested firmware bytes returned through MCP become available to the client, which controls their subsequent handling.

Creation changes map metadata only. The server does not identify maps automatically, change firmware bytes, save projects, or flash ECUs. Addresses, map meaning, and scaling must come from verified source data.

## Tools

| Tool | Arguments | Behavior |
| --- | --- | --- |
| `winols_status` | None | Check the selected backend and whether the bridge responds. |
| `winols_get_project` | None | Return project `id`, `name`, `size_bytes`, and `map_count`. |
| `winols_read_bytes` | `expected_project_id`, `address`, `count` (1–4096) | Read original/current byte arrays at a zero-based project offset, with observed window and version-name context. |
| `winols_list_maps` | `offset` (default 0), `limit` (default 50, range 1–100) | Return paginated `maps` and `total`. Each map contains `id` and `definition`. |
| `winols_get_map` | `id` | Read a definition identified by a listing or creation result. |
| `winols_validate_map` | `definition` | Validate dimensions, integer layout, axes, scaling, and byte ranges against the current project without creating a map. Does not identify meaning or check duplicates. |
| `winols_create_map` | `expected_project_id`, `definition` | Recheck project identity, reject duplicate name/address, create unsaved metadata, and verify readback. |

Tool schemas are advertised through MCP. Inputs and project metadata are data, not instructions. No tool accepts arbitrary Lua or shell code.

## Build and try mock mode

Install Rust through https://rustup.rs/. The repository selects its compiler in `rust-toolchain.toml`. Windows builds require the MSVC C++ build tools and Windows SDK.

```powershell
git clone https://github.com/amirdauti/redline-autohaus-winols-mcp.git
cd redline-autohaus-winols-mcp
cargo build --release --locked
.\target\release\winols-mcp.exe --backend mock --doctor
```

On Linux the executable is `./target/release/winols-mcp`. Source installation does not depend on the availability of downloadable release bundles.

`--doctor` prints diagnostic JSON and exits. For MCP operation, omit that flag. The process then waits for MCP input on stdio; logs are written to stderr.

Register a local stdio server in your MCP client using these executable settings, adapted to your client's configuration format:

```json
{
  "command": "C:\\path\\to\\winols-mcp.exe",
  "args": ["--backend", "mock"]
}
```

Use an absolute executable path. Repository client examples: https://github.com/amirdauti/redline-autohaus-winols-mcp/tree/main/examples

Suggested first request:

> Check winols_status, read the current project, and list its maps. Read examples/synthetic-map.json, validate that definition, create it using the current project ID if valid, and read back the returned map ID.

Your client needs access to the example file, or you can paste its JSON. This example is synthetic and does not describe a vehicle or ECU.

## Live bridge setup

Follow the complete setup and acceptance procedure at https://github.com/amirdauti/redline-autohaus-winols-mcp/blob/main/bridge/README.md.

1. Copy the complete `bridge` directory to a stable local location.
2. Create a private local mailbox directory, writable by your Windows user, outside shared or synchronized folders. Use one server and one bridge per mailbox, under the same Windows account.
3. Open a saved synthetic project. The adapter supports one contiguous element beginning at byte zero, with current element offset zero. The original SHA-256 must be available in project properties, and the project must allow reading map structure. Multi-element projects are rejected.
4. Export the map list as CSV with all maps and all columns. Inspect the exact address-column header and delimiter used by your installation. Strict decimal and explicitly `$`-prefixed hexadecimal byte offsets are accepted; unprefixed values are not guessed as hexadecimal.
5. Edit these settings at the top of `winols_bridge.lua`:

   ```lua
   local SCRIPT_DIRECTORY = [[C:\winols-mcp\bridge]]
   local BRIDGE_DIRECTORY = [[C:\winols-mcp-mailbox]]
   local CSV_ADDRESS_COLUMN = "YOUR EXACT EXPORTED ADDRESS COLUMN TITLE"
   local CSV_DELIMITER = ";"
   ```

   Use your actual paths, exact column header, and actual delimiter. The delimiter can be a semicolon, comma, or tab as appropriate to the export. The column header is installation-specific.

6. Drag `winols_bridge.lua` onto the target project window in WinOLS to start its polling loop.
7. Check the connection:

   ```powershell
   & "C:\path\to\winols-mcp.exe" --backend winols --bridge-dir "C:\winols-mcp-mailbox" --doctor
   ```

8. Register your local stdio server with these launch settings:

   ```json
   {
     "command": "C:\\path\\to\\winols-mcp.exe",
     "args": ["--backend", "winols", "--bridge-dir", "C:\\winols-mcp-mailbox"]
   }
   ```

9. Call read-only tools first. Compare project identity and complete map inventory against WinOLS before enabling creation. Repeat this comparison after changing CSV export settings.

The default backend is `winols` and requires `--bridge-dir`. Mock mode must be explicit. `--timeout-ms` defaults to 10000 and accepts 100–60000 milliseconds.

## Byte inspection and Ghidra analysis

Call `winols_get_project`, then use its `id` as `expected_project_id` in `winols_read_bytes`. Supply a zero-based project byte `address` and `count` from 1 through 4096; the entire range must fit the project. The response contains `original_bytes`, `current_bytes`, `project_id`, `address`, a decimal-string `window_id`, and the observed `version_name`. The original and current arrays contain the same number of integer bytes.

The bridge checks the observed project, window, and version name before and after reading. Window IDs expire with the session and version names can be duplicated; these fields do not establish a unique version identifier or a revision lock.

[Ghidra MCP](https://api.redlineautohaus.com/docs/ghidra-mcp/) provides a separate local analysis connection for inspecting instructions, functions, references, and data. To use its findings in WinOLS, verify the source hash and the relevant current bytes in both programs, resolve Ghidra CPU addresses to WinOLS file offsets, and establish dimensions, axes, units, and scaling from evidence. Review cached/uncached aliases explicitly. Neither MCP automatically transfers or certifies map definitions. See the [Ghidra guide](https://api.redlineautohaus.com/docs/ghidra-mcp/guide.md).

## Definition format

A definition describes a contiguous, row-major integer map. All addresses are zero-based byte offsets within the project binary. Scaling is `physical = raw * factor + offset`. X-axis length equals `columns`; Y-axis length equals `rows`.

```json
{
  "name": "Synthetic demonstration map",
  "address": 256,
  "columns": 4,
  "rows": 2,
  "data_type": "u16_le",
  "factor": 0.1,
  "offset": 0.0,
  "unit": "demo",
  "x_axis": {
    "address": 64,
    "data_type": "u16_le",
    "factor": 1.0,
    "offset": 0.0,
    "unit": "demo_x"
  },
  "y_axis": {
    "address": 96,
    "data_type": "u16_le",
    "factor": 1.0,
    "offset": 0.0,
    "unit": "demo_y"
  }
}
```

This object is the `definition` argument, not a file imported directly by the executable. `winols_create_map` additionally requires `expected_project_id` from the current `winols_get_project` result.

Supported `data_type` values:

- `u8`, `i8`
- `u16_le`, `u16_be`, `i16_le`, `i16_be`
- `u32_le`, `u32_be`, `i32_le`, `i32_be`

Required map fields: `name`, `address`, `columns`, `rows`, and `data_type`. Scaling defaults to factor 1 and offset 0; unit defaults to an empty string. Axes are optional. Each axis requires its own `address` and `data_type` and has the same scaling/unit defaults.

Dimensions must be 1–4096, with at most 1,048,576 cells per map. Map and axis ranges must fit the project. Factors must be finite and nonzero; offsets must be finite. Names must be nonblank, contain no control characters, and have at most 128 characters. Units may contain at most 64 characters and no control characters. The map inventory is limited to 10,000 entries.

The live bridge rejects floating-point, bitfield, noncontiguous, reversed/inverted, reciprocal, accumulated/subtracted, and user-defined text/value-axis layouts. Unsupported existing layouts produce an error rather than an inaccurate definition.

Native API mapping and limits: https://github.com/amirdauti/redline-autohaus-winols-mcp/blob/main/docs/winols-api.md

## Creation sequence

1. Call `winols_status` and confirm the intended backend.
2. Call `winols_get_project` and retain its current `id`.
3. Validate a proposed `definition` with `winols_validate_map`.
4. Create using the same definition and `expected_project_id`.
5. Read the returned map ID with `winols_get_map`.
6. Stop the Lua bridge before inspecting and saving the project manually in WinOLS.

Stop if the active project changes. Get a fresh project ID before further creation; IDs include a bridge-session identifier.

## Stop, inspect, and save

The Lua polling script occupies WinOLS while running. End it by creating a `stop` file in the mailbox:

```powershell
New-Item -ItemType File -Path C:\winols-mcp-mailbox\stop
```

After the loop ends, inspect the resulting definitions and save manually. Stop the MCP client too, remove the `stop` file, and restart both the Lua bridge and client for another session. Obtain a fresh project ID.

## Uncertain outcomes and troubleshooting

An interrupted or timed-out creation may already have completed in WinOLS. Invalid or mismatched readback also leaves an uncertain outcome. The MCP server stops using that bridge connection, including for reads. Do not automatically retry creation.

Inspect the project directly in WinOLS, stop the MCP server and Lua bridge, and follow mailbox recovery before restarting, listing maps, or retrying. Keep pending files until the last operation is understood. The adapter refuses to start with pending request/response files and does not replay them.

Recovery protocol: https://github.com/amirdauti/redline-autohaus-winols-mcp/blob/main/docs/bridge-protocol.md

| Symptom | Next step |
| --- | --- |
| Executable waits silently | Connect an MCP client, or use `--doctor` for a one-shot diagnostic. |
| Bridge timeout | Confirm the Lua script is running and both processes use the same local mailbox. If creation was attempted, follow uncertain-outcome recovery. |
| Project unavailable or changed | Open the intended project and obtain its identity again. |
| Definition rejected | Check byte offsets, bounds, dimensions, supported storage types, and scaling. |
| Map inventory differs from WinOLS | Correct CSV export settings and compare all pages before creation. |
| Mailbox busy or stale | Inspect the last operation, stop both processes, and follow mailbox recovery. |

WinOLS is a product of EVC electronic GmbH. This is an independent project and is not affiliated with EVC or OpenAI.
