# JEFFREY MCP BRIDGE — PORTABILITY / BACKUP / RESTORE ANCHOR

Date: 2026-09-26
Status: CANONICAL INFRASTRUCTURE STANDARD

## Purpose

`Jeffrey MCP Bridge` is an independent, versioned infrastructure component used to give ChatGPT controlled administrative access to a server through OAuth-protected MCP.

It must not be treated as an ad-hoc one-off install tied permanently to one host. The target state is a portable, reproducible deployment package that can be backed up, moved to a replacement server, restored after failure, or used to bootstrap another clean host.

The bridge is operational infrastructure and is separate from DATASET, SOLO Research Plane, and the Jeffrey trading/runtime application.

## Current verified implementation

Current host state verified 2026-09-26:

- public MCP endpoint: `https://tesh.combatsolo.info/mcp`;
- local MCP listener: `127.0.0.1:8766`;
- systemd service: `jeffrey-mcp.service`;
- implementation path: `/opt/jeffrey-mcp`;
- OAuth state path: `/var/lib/jeffrey-mcp/oauth_state.json`;
- nginx OAuth/basic-auth credential file: `/etc/nginx/jeffrey-mcp.htpasswd`;
- MCP SDK line: `mcp==1.26.0`;
- OAuth 2.1 protection is active;
- DCR works;
- authorization-code + PKCE S256 works;
- refresh-token support is enabled;
- unauthenticated MCP access returns HTTP 401 with `WWW-Authenticate`;
- ChatGPT authenticated successfully;
- `bridge_ping` works;
- `root_exec` works and has been verified to execute as `uid=0(root)` during bootstrap.

Compatibility note: `mcp==1.26.0` `AuthorizationCode`/`RefreshToken` do not expose `.subject`; the private single-owner provider uses a fixed local owner identity instead.

## Portability objective

A fresh Debian server should be able to receive the bridge from a clean archive/repository and become operational through a short, deterministic install flow.

The bridge package should not assume:

- the old server hostname;
- the old public domain;
- the old IP address;
- old OAuth clients/tokens;
- old passwords;
- old application/runtime secrets.

Deployment-specific values should be generated or supplied during install.

## Canonical portable package layout

Target package structure:

```text
jeffrey-mcp-bridge/
├── VERSION
├── README.md
├── requirements.txt
├── server.py
├── install.sh
├── uninstall.sh
├── systemd/
│   └── jeffrey-mcp.service
├── nginx/
│   └── mcp.conf.tpl
├── scripts/
│   ├── self-test.sh
│   ├── backup-portable.sh
│   ├── backup-dr.sh
│   └── restore-dr.sh
└── docs/
    ├── CHANGELOG.md
    └── SECURITY.md
```

The exact filenames may evolve, but separation of code/templates/installers/secrets/state must remain explicit.

## Portable backup

### Purpose

A portable backup is safe to use for deploying the bridge to another server/domain.

### MUST include

- `server.py` or equivalent MCP application code;
- exact dependency lock/requirements;
- systemd unit template;
- nginx template for `/mcp`, OAuth metadata, `/authorize`, `/token`, `/register`, `/revoke` as applicable;
- install/uninstall scripts;
- self-test scripts;
- VERSION;
- compatibility notes;
- audit-log directory/config creation rules;
- root/bootstrap-tool implementation if that is part of the chosen release;
- migration/restore documentation.

### MUST NOT include

- `/etc/nginx/jeffrey-mcp.htpasswd`;
- `/var/lib/jeffrey-mcp/oauth_state.json`;
- OAuth access tokens;
- OAuth refresh tokens;
- registered client secrets/state;
- bootstrap passwords;
- old bridge bearer tokens;
- Bybit/API/exchange keys;
- DATASET/Jeffrey application secrets;
- SSH private keys;
- unrelated host credentials.

### Install behavior on a new server

A portable install should:

1. install/check required system packages;
2. create a Python virtual environment;
3. install exact pinned MCP dependencies;
4. install bridge code;
5. create required state/log directories with correct ownership;
6. install systemd unit;
7. render nginx config from a supplied domain;
8. generate fresh authentication material;
9. start/reload services only after validation;
10. run self-tests;
11. print no secret into persistent logs;
12. require a new ChatGPT OAuth connection/scan on the new endpoint.

## Disaster-recovery backup

### Purpose

A DR backup is for restoring the SAME bridge identity/state after server loss or accidental corruption.

Unlike portable backup, it may contain sensitive state.

### May include

- bridge source/configuration;
- exact dependency lock;
- systemd/nginx config;
- `/var/lib/jeffrey-mcp/oauth_state.json`;
- `/etc/nginx/jeffrey-mcp.htpasswd`;
- other bridge-specific credentials required to preserve the existing identity;
- relevant audit metadata;
- checksums and restore manifest.

### Security requirement

DR backup containing secrets MUST be encrypted at rest and handled separately from normal project artifacts.

Do not place plaintext DR secret material in project docs, source repositories, chat history, or ordinary migration bundles.

### Restore invariant

After DR restore:

- file ownership/modes must be restored correctly;
- OAuth state must not become world-readable;
- nginx must pass `nginx -t` before reload;
- MCP must pass local health/auth tests before public cutover;
- duplicate active OAuth/root bridge instances must not remain unintentionally exposed.

## Versioning

The bridge must carry its own version independent from Jeffrey engine version.

Example:

```text
Jeffrey MCP Bridge 0.3.0
Jeffrey engine 2.1.0
```

These are separate products/lifecycles.

Every bridge release should record:

- MCP SDK version;
- exposed tools;
- privilege model;
- authentication model;
- data/state schema changes;
- known compatibility requirements;
- migration/rollback notes.

## Recommended release stages

### Bootstrap release

May expose temporary `root_exec` under OAuth for clean-server preparation and migration.

### Operational release

After migration stabilizes:

- remove or disable unrestricted root execution for normal use;
- replace it with dedicated tools/service-user operations/sudo allowlists;
- retain an emergency root mechanism only if deliberately approved;
- keep audit logging and OAuth.

## Self-test contract

A deployment/restore is not complete until the following are verified:

1. systemd service is active;
2. local MCP port is listening only where intended;
3. nginx config validates;
4. public OAuth authorization metadata returns HTTP 200;
5. protected-resource metadata returns HTTP 200;
6. unauthenticated `/mcp` returns HTTP 401 + `WWW-Authenticate`;
7. OAuth authorization succeeds;
8. `bridge_ping` succeeds from ChatGPT;
9. required tool inventory matches the release manifest;
10. if bootstrap root is intentionally enabled, a harmless `id`/`whoami` test verifies expected privilege;
11. audit log records administrative tool calls;
12. secrets are not printed in logs or documentation.

## Migration to another server

Preferred sequence:

1. create portable bridge backup/package from source-of-truth release;
2. provision DNS/test hostname for the target server;
3. install package on target;
4. generate new OAuth/bootstrap authentication state;
5. validate locally;
6. validate public HTTPS/OAuth metadata;
7. create/connect the new MCP application in ChatGPT;
8. scan tools;
9. authenticate;
10. run `bridge_ping`;
11. if required for bootstrap, verify `root_exec` with harmless identity commands;
12. only then use the new bridge for server configuration/migration;
13. remove/disable obsolete bridge exposure after cutover.

## Domain independence

The bridge may live under a dedicated technical hostname and does not have to share an application domain.

Current endpoint `tesh.combatsolo.info` is a bootstrap/control-plane hostname, not a hard architectural dependency.

A future deployment may use another hostname as long as:

- TLS is valid;
- OAuth issuer/resource metadata are generated for the new canonical URL;
- nginx/bridge config uses that URL consistently;
- ChatGPT connection is recreated or updated appropriately.

## Documentation invariant

Whenever bridge code, OAuth model, exposed tools, privilege model, backup format or restore procedure changes, update:

- this file;
- `docs/NEW_SERVER_BOOTSTRAP_ROOT_MCP_RUNBOOK.md` where relevant;
- `docs/SERVER_MIGRATION_ANCHOR.md` where migration behavior changes;
- `docs/NEXT_CHAT_HANDOFF.md` for active operational state.

## Immediate follow-up

After the current new-server bootstrap/migration is stable, package the verified live bridge into the canonical portable structure and produce:

1. a clean portable archive with no secrets;
2. SHA256 manifest;
3. install/self-test scripts;
4. a separately encrypted DR backup procedure;
5. a documented privilege downgrade path from bootstrap `root_exec` to operational least-privilege tools.
