# How Codebase-Memory CLI Executes One-Shot Tool Invocations Without Starting the Daemon

> Discover how the codebase-memory CLI executes one-shot tool invocations without the daemon. Learn about process replacement techniques on Unix and Windows.

- Repository: [Martin Vogel/codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp)
- Tags: internals
- Published: 2026-07-24

---

**The codebase-memory CLI performs one-shot tool invocations by replacing the current process with `os.execv` on Unix systems or spawning via `subprocess.run` on Windows, completely bypassing the daemon socket connection.**

DeusData's codebase-memory-mcp repository provides a hybrid command-line interface that supports both persistent daemon sessions and stateless one-shot executions. When operating in one-shot mode, the CLI shim executes the native binary directly without initializing a background service, eliminating daemon startup latency for single operations.

## How the CLI Chooses Between Daemon and One-Shot Mode

The execution mode decision occurs in [`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c) within the `main()` function. The shim evaluates command-line arguments to determine whether to route the request through a running daemon or execute the tool directly.

According to the source code, the logic branches based on a `use_daemon` boolean flag:

```c
int main(int argc, char *argv[]) {
    // Parse command line arguments
    bool use_daemon = should_use_daemon(argc, argv);
    
    if (use_daemon) {
        // Connect to daemon via UNIX socket
        // ... daemon communication code
    } else {
        // Perform one-shot tool invocation
        // ... direct execution code
    }
    return 0;
}

```

When `use_daemon` evaluates to false—either through explicit flags like `--no-daemon` or when no daemon is running—the CLI enters one-shot mode and proceeds to execute the native binary immediately.

## Python Wrapper Implementation

The Python entry point at [`pkg/pypi/src/codebase_memory_mcp/_cli.py`](https://github.com/DeusData/codebase-memory-mcp/blob/main/pkg/pypi/src/codebase_memory_mcp/_cli.py) handles platform-specific execution strategies. After resolving the binary path via `_execution_path()`, the wrapper determines whether to replace the current process or spawn a child process.

### Unix Process Replacement with os.execv

On POSIX-compliant systems, the Python wrapper uses `os.execv()` to replace the interpreter process entirely with the native binary. This approach preserves the original process ID and file descriptors while eliminating Python runtime overhead during tool execution.

```python

# From pkg/pypi/src/codebase_memory_mcp/_cli.py

execution_path = _execution_path(bin_path, sys.platform)
args = [str(execution_path)] + sys.argv[1:]

# Direct exec replaces the shim; the tool runs and never returns here.

os.execv(str(execution_path), args)  # One-shot: no daemon started

```

The `os.execv()` call transforms the Python shim into the target binary, ensuring that signals, exit codes, and standard I/O streams pass directly between the shell and the tool without intermediate buffering.

### Windows Direct Execution with subprocess.run

On Windows platforms, where process replacement semantics differ, the wrapper utilizes `subprocess.run()` to execute the native binary and propagate its return code back to the shell.

```python

# Windows implementation in _cli.py

execution_path = _execution_path(bin_path, sys.platform)
args = [str(execution_path)] + sys.argv[1:]

result = subprocess.run(args)  # Runs binary directly without daemon

sys.exit(result.returncode)

```

This method maintains compatibility with Windows process creation semantics while still avoiding daemon initialization overhead.

## C Shim Architecture

The C implementation in [`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c) provides the low-level execution logic that the Python wrapper abstracts. When operating in one-shot mode, the C shim utilizes [`src/cli/agent_clients.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/agent_clients.c) to handle the actual binary spawning.

The [`agent_clients.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/agent_clients.c) module contains functions that implement `fork/exec` patterns on POSIX systems or `CreateProcess` calls on Windows when `use_daemon` is false. These routines bypass the Unix domain socket connection that would normally communicate with a long-running daemon process.

## Execution Flow for One-Shot Invocations

The complete one-shot execution follows this deterministic sequence:

1. **Argument Parsing**: The CLI parses `argv` to detect tool names and flags like `--no-daemon`
2. **Binary Resolution**: `_execution_path()` locates the platform-specific native binary in the installation directory
3. **Mode Decision**: The code evaluates `use_daemon` in [`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c) main function
4. **Direct Execution**: 
   - **Unix**: `os.execv()` replaces the Python process with the native binary
   - **Windows**: `subprocess.run()` spawns the binary and waits for completion
5. **Result Propagation**: Exit codes and stdout/stderr flow directly back to the invoking shell

This design ensures that one-shot invocations complete in a single process lifecycle without socket communication overhead or daemon state management.

## Summary

- **One-shot mode** bypasses the daemon entirely by executing native binaries directly from the CLI shim
- **Unix systems** use `os.execv()` in [`pkg/pypi/src/codebase_memory_mcp/_cli.py`](https://github.com/DeusData/codebase-memory-mcp/blob/main/pkg/pypi/src/codebase_memory_mcp/_cli.py) for process replacement
- **Windows platforms** use `subprocess.run()` to spawn the tool and capture its exit code
- **C shim logic** in [`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c) determines execution mode via the `use_daemon` flag in the `main()` function
- **Low-level spawning** is handled by [`src/cli/agent_clients.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/agent_clients.c) when daemon communication is disabled

## Frequently Asked Questions

### How do I force the CLI to use one-shot mode instead of connecting to the daemon?

Pass the `--no-daemon` flag or ensure no daemon process is currently running. The `main()` function in [`src/cli/cli.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/src/cli/cli.c) evaluates the `use_daemon` boolean based on these conditions, automatically falling back to direct binary execution via [`agent_clients.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/agent_clients.c) when the daemon is unavailable or explicitly disabled.

### Does one-shot mode affect performance compared to using the daemon?

One-shot mode eliminates daemon startup latency but incurs full binary initialization overhead for each invocation. For single sporadic commands, this is faster than daemon management. For high-frequency sequential operations, the persistent daemon connection provides better amortized performance by avoiding repeated process creation costs.

### What happens to the Python interpreter during one-shot execution on Linux?

The Python interpreter process is completely replaced by the native binary via `os.execv()` as implemented in [`pkg/pypi/src/codebase_memory_mcp/_cli.py`](https://github.com/DeusData/codebase-memory-mcp/blob/main/pkg/pypi/src/codebase_memory_mcp/_cli.py). The Python runtime does not persist after the exec call; the tool binary inherits the process ID and file descriptors directly from the shell session.

### Is the Windows implementation truly one-shot if it uses subprocess.run()?

Yes. While Windows cannot perform true process replacement like Unix `execv`, the `subprocess.run()` implementation in [`_cli.py`](https://github.com/DeusData/codebase-memory-mcp/blob/main/_cli.py) still qualifies as one-shot because it spawns the native binary directly without starting or communicating with the codebase-memory daemon service, then exits with the child's return code.