Skip to main content
Glama

tegh

tegh pins the MCP tools a coding agent uses. It wraps a project's agent so that every tool call goes through a local broker, which allows the call, refuses it, or holds it for your approval, and writes each decision to an audit tape you can verify. It runs on a Mac with a local SQLite store and needs no cloud account.

NOTE: This project contains code that was written with AI.

tegh wraps agents you don't control; agents you build can use the broker directly. MCP is how tegh reaches a stock agent. An agent you write yourself can call the platform's broker without it, and docs/canonical-consumer.md and examples/ in the platform repository show that path.

Status

Alpha, in single-player mode: one person, one machine, one OS user. tegh is published on PyPI. Nobody but the maintainer has walked the quickstart yet (#2), so nothing here states a setup time.

Related MCP server: Accord

Supported agents

Agent

Wrapped

Posture reached

Maintained by

Claude Code

Yes

1

core

OpenClaw

No, planned next

none

OpenCode

No, planned

none

Hermes

No, planned

none

Cursor

No, planned

none

"Core" means the adapter lives in this repository under tegh/harnesses/ and its tests run in this repository's CI. No community-maintained adapter exists.

What the Claude Code row covers, and where it stops:

  • The gateway's MCP tools are gated. Built-in tools are mediated by the broker, and not contained. tegh rewrites the three configuration blocks it can write for the project (local, project and user scope) so that the gateway is the only MCP server in them, and the broker decides every call to a tool the gateway serves. A server Claude Code loads from somewhere tegh cannot write, such as a plugin or a claude.ai connector, is not behind the gateway. Claude Code's built-in shell, file and network tools do not go through the gateway. tegh wrap adds two hooks to the project's .claude/settings.local.json: a PreToolUse hook that asks the broker before each built-in call and relays its answer, and a PostToolUse hook that reports the call to the audit tape after it ran. tegh writes no allow rule, so the broker's answer is the only approval a built-in call gets from tegh's side, and a refusal or a hold reaches the agent in the broker's own words. A read outside the project, a web fetch or a web search taints the turn, so the agent's next external write through the gateway is held for you. On a tainted turn a shell command, a web fetch and a file write or edit inside the project are still permitted, unless the wrap named their class with tegh wrap --hold-when-tainted <class> (for example shell); a file write or edit outside the project is held. With the gateway down the hook refuses the call, and if the hook itself fails, its onFailure: "block" setting refused the call on Claude Code 2.1.295. The answer binds only where Claude Code runs the hook: --bare, disableAllHooks in a lower settings file or a removed entry leaves the call to Claude Code's own rules, and those ran calls with no approval at all in auto mode, the default for interactive sessions, and approve any call an allow rule you add names. docs/managed-profile.md defines managed settings under which a managed hook stayed in place on a test runner against a lower-scope disableAllHooks and an unwritable policy file, with --bare recorded as a note rather than a predicted cell and a managed command hook untested; it says where that evidence stops, and tegh does not install them. Nothing contains a built-in call: a permitted one runs with your user's full reach. Every built-in call now runs tegh hook twice, before and after. tegh wrap --no-hooks leaves both hooks out. A project wrapped by tegh 0.3.0 does not start its gateway on this version until tegh upgrade regenerates its manifest, re-attests its grants through the platform's ceremony and adds the PreToolUse hook, keeping its audit tape.

  • An MCP server tegh could not displace is asked about as other, and its reads are not known to be reads. Servers a plugin provides and claude.ai connectors are not in any configuration tegh can rewrite, so their tools are not served by the gateway. The hook asks the broker about each such call at the other/unknown coordinate under the harness code claude-code-mcp, which is how the tape names a call that went around the gateway, and reports it after it ran. It does not taint the turn: tegh cannot tell whether the call read anything, and the platform has no tool class for it yet (wjatx/ptc-gal-reference#187). A read made through one of these servers therefore does not hold the next external write.

  • What the hook leaves off the tape. A call the gateway brokered is recorded once, by the broker, and the hook adds nothing for it. Claude Code's own deferred-tool lookup (ToolSearch) is not recorded, because it reaches nothing outside the session; that list is one name long and lives in tegh/hook.py. Any tool tegh has no row for is recorded as other.

  • Stdio servers, credentialed ones included. A literal credential in a stdio server's env is moved out of the Claude Code configuration into tegh's store and delivered when the server is spawned. A remote server that takes a credential in an HTTP header is refused (#4), and a server on the sse or ws transport cannot be recorded in the lock.

  • Whether a wrapped Claude Code can undo its own wrap is unresolved. tegh posture reports it as unknown and cites what the vendor's documentation does and does not say.

Posture

The platform's posture ladder names three postures by where the boundary between the agent and its controller sits. Every claim in this repository is made at one of them, and tegh posture prints which one a project is on, with a source for each line.

Posture

What it is

What tegh does today

1

A local wrapper, running as the same OS user as the agent

Built. A wrapped project is at posture 1; tegh posture reports an unwrapped one as below it.

2

The agent inside a sandbox, the gateway outside, egress to the gateway and the model provider and nothing else

Not built on a Mac. tegh/openshift/ is a leg that runs tegh posture from inside an OpenShift pod. The project it reports on there is not wrapped, so the posture it derives is pre-1, below posture 1. Containment does not raise the posture tegh posture prints, and the leg requires the report to mark the pod's egress and RBAC refusals unknown, because the report attempts neither. The shipped transcript records the leg as skipped.

3

The broker under its own cloud identity, the agent holding no credentials

Not reachable from tegh. The platform's cloud floor is posture 3, and tegh does not connect a project to it.

Posture 1 is a boundary against an injected agent: one that follows a poisoned instruction and edits where it normally edits. tegh's keys and store sit outside the project tree, in ~/.tegh. The same OS user can still read and write that directory, so posture 1 does not stop someone who already has your login, and the local audit tape is self-consistent without being tamper-evident. Posture 2 is the recommended hardening for an agent that handles anything you would mind losing: tegh wrapping an agent that runs in a sandbox.

The quickstart ends with "What this does not prove", which lists these limits against the walk it has just shown.

Install

In a virtual environment, with Python 3.12 or newer:

python3 -m venv venv && source venv/bin/activate
python -m pip install tegh
tegh --help

To have every dependency checked against a pinned hash, use the lock file attached to each GitHub release. tegh-<version>-requirements.txt pins tegh at the hash of the released wheel and every package it depends on, the platform included, at an exact version with hashes:

python -m pip install --require-hashes -r tegh-<version>-requirements.txt

docs/tegh-quickstart.md walks the whole path: tegh init, tegh wrap claude with a reviewed admission, a call held and released with tegh approve, a call refused, tegh audit --verify, tegh status and tegh diff against the lock, and tegh unwrap. docs/tegh-lock.md describes the lockfile.

How it relates to the platform

tegh is a consumer of safe-agents, the reference implementation published from wjatx/ptc-gal-reference, pinned to an exact version in pyproject.toml. The broker, the admission ceremony, the approval release and the audit chain are the platform's. tegh imports only what the platform publishes for a consumer to fill and to run (safe_agents.broker.schemas and the gateway client from safe_agents.broker.api) and runs the platform's commands as child processes. tegh/tests/test_lock.py enforces that boundary. A change tegh needs in the platform lands there first and is consumed here at a version.

docs/references/harnesses/claude-code.md records, with sources, how Claude Code stores and loads MCP configuration. The wrap mechanics are built against it.

Develop

From a checkout, in a virtual environment. requirements/dev.txt holds the project's dependencies and its dev extra at exact versions with hashes, and the second command installs the checkout against them without downloading anything:

python -m pip install --require-hashes -r requirements/dev.txt
python -m pip install --no-index --no-build-isolation --check-build-dependencies -e ".[dev]"
pytest
ruff check .

The header of .github/workflows/ci.yml says how the lock files under requirements/ are regenerated when a dependency changes.

tegh posture cites its sources, and tegh/tests/test_posture_citations.py checks that each one still resolves. Some resolve in the platform repository through the gh command; without gh those checks skip, and TEGH_CITATIONS_STRICT=1 makes them fail instead.

The fresh-install drill (tegh/tests/drill_fresh_install.py) installs the package into a clean environment and walks the quickstart's chain against the installed command. It runs on macOS in .github/workflows/tegh-fresh-mac-drill.yml.

License

Apache-2.0. Copyright 2026 Wes Jackson.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Governed MCP gateway that lets AI agents call tools with policy enforcement, prompt-injection screening, a kill-switch, and tamper-evident signed audit logs.
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides a policy-controlled MCP gateway that lets agents invoke tools with explicit policies, bounded execution, scoped visibility, and decision receipts.
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enforces default-deny policies, budgets, and tamper-evident audit logging for MCP tool calls before they reach upstream servers.
    -
  • A
    license
    A
    quality
    A
    maintenance
    Enables MCP-speaking agents to execute tool calls through an authorization gate, producing signed decision records and reconciled effect rows for accountability.
    6
    Apache 2.0