oct.mcp package#

oct.mcp — Secure MCP server package for Option C Tools.

This package implements the six-layer pipeline described in the Secure MCP Architecture Blueprint (Phase 5A read-only tools + Phase 5B write tools with HITL consent):

Layer 1 — Gateway (workspace binding, rate limiting) Layer 2 — Input Validator (Pydantic models, path containment) Layer 2.5 — Safety Gate (HITL consent + dry-run enforcement, Phase 5B) Layer 3 — Policy Engine (tool allowlist, profile enforcement) Layer 4 — Execution Sandbox (env sanitisation, subprocess isolation) Layer 5 — Output Redactor (secret patterns, path anonymisation) Layer 6 — Audit Logger (JSONL at ~/.oct-mcp/audit.log)

Entry point: python -m oct.mcp [--project-root PATH] [--profile PROFILE]

class oct.mcp.McpConfig(profile: str = 'default', rate_limit_per_minute: int = 30, timeout_default_seconds: int = 60, timeout_test_seconds: int = 300, max_output_bytes: int = 1048576, max_jobs: int = 4, auto_approve_read_tools: bool = True, dry_run_default_for_writes: bool = True, redaction_always_on: bool = False, audit_log_path: str = 'C:\\Users\\UnderTow\\.oct-mcp\\audit.log', audit_log_max_files: int = 20, audit_log_max_size_mb: float = 5.0, trust_repo_config: bool = False, safe_mode: bool = False, sandbox_backend: str = 'auto', memory_limit_mb: int = 512, metrics_port: int | None = None, policy_source: str | None = None)[source]#

Bases: object

Runtime configuration for the oct-mcp server.

All fields have safe, conservative defaults that work without any config file present. Fields loaded from JSON are clamped to the valid ranges defined by the module-level constants.

trust_repo_config defaults to False — repo-level config (debug_config.json, .octrc.json) is untrusted by default per blueprint §8.1. Set to True via OCT_TRUST_REPO_CONFIG=1 or the config file field trust_repo_config: true.

audit_log_max_files: int = 20#

Maximum number of rotated audit log files to keep.

audit_log_max_size_mb: float = 5.0#

Rotation threshold per audit file, in megabytes.

audit_log_path: str = 'C:\\Users\\UnderTow\\.oct-mcp\\audit.log'#

Path to the JSONL audit log. Rotation files go in the same directory.

auto_approve_read_tools: bool = True#

If True, read-only tools execute without confirmation.

dry_run_default_for_writes: bool = True#

If True, write tools default to dry-run mode (Phase 5B guard).

max_jobs: int = 4#

Maximum --jobs value forwarded to tools that support parallelism.

max_output_bytes: int = 1048576#

Hard output-size cap per tool call. Output exceeding this is truncated.

memory_limit_mb: int = 512#

Per-subprocess memory limit in megabytes (POSIX only; 0 = disabled). On Windows this field is accepted but has no effect — use Docker for memory enforcement on Windows. Range: 0–8192.

metrics_port: int | None = None#

If set, starts a Prometheus /metrics HTTP server on this port in a background thread. Requires oct[metrics] (prometheus-client). None (default) disables metrics collection.

policy_source: str | None = None#

If set, load additional policy overrides from this source at startup. Accepts a local filesystem path or an https:// URL. Overrides are merged on top of the base config. Any load failure falls back to built-in defaults silently.

profile: str = 'default'#

"default", "strict", or "airgapped".

Type:

Active security profile

rate_limit_per_minute: int = 30#

Maximum tool calls per session per minute (Gateway rate limiter).

redaction_always_on: bool = False#

Force redaction even when not in production mode.

safe_mode: bool = False#

all tools return error; set via OCT_MCP_SAFE_MODE=1.

Type:

Hard-override

sandbox_backend: str = 'auto'#

"auto", "native", "bubblewrap", or "sandbox_exec". "auto" picks the best available backend for the current platform, falling back to "native" if no enhanced backend is found. Set via OCT_MCP_SANDBOX env var.

Type:

OS-level sandbox backend

timeout_default_seconds: int = 60#

Per-tool subprocess timeout in seconds (except oct test).

timeout_test_seconds: int = 300#

Subprocess timeout for oct test (pytest may need longer).

trust_repo_config: bool = False#

Whether to load and trust repo-level config (.octrc.json).

class oct.mcp.SafetyDecision(proceed: bool, requires_confirmation: bool, dry_run: bool, reason: str)[source]#

Bases: object

Result of a SafetyGate.check() call.

proceed#

True → execution may continue; False → return the confirmation request to the AI host.

Type:

bool

requires_confirmation#

True when the AI host must re-submit the call with confirm=True before execution proceeds.

Type:

bool

dry_run#

True → executor should pass --dry-run (or equivalent) to the CLI subprocess. Applies only to oct_format (where apply=False triggers dry-run even with confirm=True). Other tools that have their own dry_run field manage it independently.

Type:

bool

reason#

Human-readable explanation forwarded to audit logs.

Type:

str

dry_run: bool#
proceed: bool#
reason: str#
requires_confirmation: bool#
class oct.mcp.SafetyGate(config: McpConfig)[source]#

Bases: object

HITL + dry-run enforcement gate for write tools.

One instance is created per MCP server session (in server.py) and stored in ServerState.

The gate is stateless — each check() call is independent. There is no in-memory pending-confirmation queue. This eliminates the T-08 replay-window attack surface.

Parameters:

config – Active McpConfig. The gate reads config.dry_run_default_for_writes to decide the fallback dry-run behaviour.

check(tool_name: str, spec: ToolSpec, args: dict) SafetyDecision[source]#

Evaluate the HITL gate and dry-run rules for tool_name.

Parameters:
  • tool_name – MCP tool name (e.g. "oct_format").

  • specToolSpec for tool_name.

  • args – Validated args dict (model.model_dump()).

Return type:

SafetyDecision — never raises.

oct.mcp.load_config(path: Path | None = None) McpConfig[source]#

Load and return a McpConfig.

Resolution order:

  1. Read ~/.oct-mcp/config.json (or path if supplied).

  2. Validate and clamp JSON field values.

  3. Apply environment variable overrides: - OCT_MCP_SAFE_MODE=1safe_mode = True - OCT_TRUST_REPO_CONFIG=1trust_repo_config = True - OCT_MCP_PROFILE=<name>profile = <name>

  4. Return a fully-populated McpConfig.

Never raises. Any read or parse failure falls back to the default config and logs an error at level 1.

Submodules#