---
title: Environment Variables
description: Configuration via environment variables
---

mcjtag is configured entirely through environment variables. No config files are required -- the defaults work for the most common case (connecting to OpenOCD on `localhost:6666`).

## Variable Reference

| Variable | Default | Description |
|----------|---------|-------------|
| `OPENOCD_HOST` | `localhost` | OpenOCD TCL server hostname |
| `OPENOCD_PORT` | `6666` | OpenOCD TCL server port |
| `OPENOCD_CONFIG` | *(none)* | Path to OpenOCD `.cfg` file -- if set, mcjtag auto-spawns OpenOCD on startup |
| `OPENOCD_SVD` | *(none)* | Path to `.svd` file -- auto-loaded when a connection is established |
| `MCJTAG_SAFE_WRITE_RANGES` | `0x20000000-0x20100000` | Comma-separated hex address ranges for `write_memory` |
| `MCJTAG_MAX_SEARCH_RANGE` | `1048576` (1 MB) | Maximum byte range for `search_memory` |
| `MCJTAG_ALLOW_RAW` | `false` | Set to `true` to disable the deny-list for `raw_command` |

---

## Connection Modes

The `OPENOCD_*` environment variables determine how mcjtag connects to OpenOCD at startup. There are three modes:

### Auto-spawn Mode

Set `OPENOCD_CONFIG` to a path. mcjtag starts OpenOCD as a subprocess, waits for it to initialize, and connects automatically.

```bash
export OPENOCD_CONFIG="/path/to/openocd-daplink-swd.cfg"
export OPENOCD_PORT=6666  # optional, defaults to 6666
mcjtag
```

The managed OpenOCD process is stopped automatically when mcjtag shuts down or when `disconnect()` is called.

This is the recommended mode for single-user setups. See [OpenOCD Configurations](/reference/openocd-configs/) for the shipped config files.

### Auto-connect Mode

Set `OPENOCD_HOST` (and optionally `OPENOCD_PORT`) without setting `OPENOCD_CONFIG`. mcjtag connects to an already-running OpenOCD instance at startup.

```bash
export OPENOCD_HOST=localhost
export OPENOCD_PORT=6666
mcjtag
```

Use this when OpenOCD is managed separately -- for example, when running OpenOCD as a system service, or when multiple clients share the same OpenOCD instance.

### Manual Mode

Don't set any `OPENOCD_*` variables. mcjtag starts with no connection. The LLM (or user) calls `connect()` or `start_openocd()` explicitly.

```bash
mcjtag
# Then use tools:
#   connect(host="192.168.1.50", port=6666)
#   or
#   start_openocd(config="/path/to/config.cfg")
```

This is useful when the connection target is not known ahead of time, or when the LLM needs to decide which probe to connect to.

---

## OPENOCD_SVD

When set, mcjtag automatically loads the specified SVD file after establishing a connection. This makes peripheral decoding available immediately via `svd_inspect()` and the `jtag://svd/*` resources without a separate load step.

```bash
export OPENOCD_SVD="/path/to/STM32F103.svd"
```

If the SVD file cannot be loaded (file not found, parse error, etc.), a warning is logged but the connection proceeds normally. SVD can always be loaded later with `svd_inspect(svd_path=...)`.

SVD files are provided by silicon vendors. A large collection is available at [cmsis-svd-data](https://github.com/cmsis-svd/cmsis-svd-data).

---

## MCJTAG_SAFE_WRITE_RANGES

Controls which memory addresses `write_memory` is allowed to target. The default restricts writes to the main SRAM region (`0x20000000`--`0x20100000`), which is safe because SRAM is volatile and cannot brick the device.

See [Memory Layout](/concepts/memory-layout/) for a detailed explanation of why this restriction exists.

### Format

Comma-separated pairs of `start-end` hex addresses (no `0x` prefix):

```bash
# Default: main SRAM only
export MCJTAG_SAFE_WRITE_RANGES="0x20000000-0x20100000"

# SRAM + CCM RAM (STM32F4)
export MCJTAG_SAFE_WRITE_RANGES="0x20000000-0x20020000,0x10000000-0x10010000"

# SRAM + external SDRAM
export MCJTAG_SAFE_WRITE_RANGES="0x20000000-0x20100000,0xD0000000-0xD1000000"
```

### Unrestricted Mode

Set to `none` to disable write address validation entirely:

```bash
export MCJTAG_SAFE_WRITE_RANGES="none"
```

This allows writing to any address, including flash, peripherals, and system regions. Use with caution -- writing to peripheral registers can change hardware state, and writing to flash requires the proper erase/program sequence (use `flash_program` instead).

### Validation Rules

- Ranges with `start >= end` are silently skipped with a log warning
- Entries without a `-` separator are skipped
- Invalid hex values are skipped
- An empty or all-invalid value falls back to an empty list (unrestricted)

---

## MCJTAG_MAX_SEARCH_RANGE

Sets the upper bound on how many bytes `search_memory` will scan in a single call. The default is 1,048,576 bytes (1 MB).

```bash
# Allow searching up to 4 MB
export MCJTAG_MAX_SEARCH_RANGE=4194304
```

The limit exists to prevent accidental multi-minute reads on slow debug links. At typical SWD speeds (1 MHz), reading 1 MB takes roughly 10 seconds. For larger searches, call `search_memory` multiple times with smaller windows.

---

## MCJTAG_ALLOW_RAW

Controls whether `raw_command` blocks destructive OpenOCD commands. When `false` (the default), a deny-list pattern match prevents commands that could modify flash, write memory, reset the target, or shut down OpenOCD.

```bash
# Disable the deny-list (use with care)
export MCJTAG_ALLOW_RAW=true
```

Accepted truthy values: `true`, `1`, `yes` (case-insensitive).

The deny-list is a best-effort safety measure, not a sandbox. TCL metaprogramming could theoretically bypass pattern matching. The typed tools (`flash_program`, `write_memory`, `target_control`) have proper validation and should be preferred for destructive operations.

See [Tools > raw_command](/reference/tools/#raw_command) for the full list of blocked patterns.

---

## Example Configurations

### Minimal: Auto-spawn with SWD probe

```bash
export OPENOCD_CONFIG="openocd-daplink-swd.cfg"
```

### Full-featured: Auto-spawn, SVD, expanded write ranges

```bash
export OPENOCD_CONFIG="openocd-daplink-swd.cfg"
export OPENOCD_SVD="/opt/svd/STM32F103.svd"
export MCJTAG_SAFE_WRITE_RANGES="0x20000000-0x20005000,0x10000000-0x10010000"
```

### Remote OpenOCD with unrestricted access

```bash
export OPENOCD_HOST=192.168.1.50
export OPENOCD_PORT=6666
export MCJTAG_SAFE_WRITE_RANGES="none"
export MCJTAG_ALLOW_RAW=true
```

### Claude Code MCP configuration

When adding mcjtag to Claude Code, environment variables go in the MCP config:

```json
{
  "mcpServers": {
    "mcjtag": {
      "command": "uvx",
      "args": ["mcjtag"],
      "env": {
        "OPENOCD_CONFIG": "/path/to/openocd-daplink-swd.cfg",
        "OPENOCD_SVD": "/path/to/STM32F103.svd"
      }
    }
  }
}
```
