Local Review MCP
Provides read-only Git repository review for the configured workspace, including structured status and bounded diff review.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Local Review MCPsearch for TODO comments in the workspace"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Local Review MCP
Current version
V0.1 Release Candidate / Phase 5.6.1
Related MCP server: local-code-mcp
Current capabilities
MCP Streamable HTTP runtime
nineteen read-only tools, including the workspace registry, review context, and interactive Session status tools
submit_goalControl Plane entry point with asynchronous exact-current-conversation bindingbatch CLI and interactive Codex app-server Execution backends
normalized interactive Session events with read-only Session/Execution status queries
schema-validated MCP structured outputs and schema-v1 ReviewVerdict parsing
durable Extension delivery and review-completion channels with identity-bound receipts
MV3 Browser Extension/Fiber identity evidence and loopback Local Control Bridge
fixed loopback host
configurable fixed port
startup port conflict detection
Bearer-token authentication for all MCP HTTP requests
OAuth 2.1-compatible discovery, public-client registration, PKCE, and Bearer tokens
safe
GET /healthendpointCloudflare Tunnel provider with managed lifecycle
a registry of authorized workspaces with legacy single-workspace compatibility
bounded workspace metadata, directory listing, and text-file reading
bounded literal or regular-expression search with ripgrep and Node fallback
read-only structured Git status and bounded diff review
optional Windows Supervisor with health monitoring and bounded recovery
optional Windows Tray status/actions and per-user startup registration
Remote MCP protocol, authentication, workspace-review, and restart E2E tests
Architecture
The Local MCP Server keeps the MCP Data Plane and the Control Plane separate:
MCP Read-only Data Plane
Workspace / Git / Review Context / status / hash-only diagnostics
MCP Control Plane entry
submit_goal
|
v
Pending Goal identity gate -> Goal -> Phase -> Task
|
v
Controlled Actuation -> ExecutionThe MCP server exposes nineteen read-only tools and the reviewed submit_goal
entry point. Browser Extension/Fiber, Local Control Bridge, Dispatcher, Codex
execution, and Review Loop work remain Control Plane capabilities; MCP does not
provide general file-write, shell, commit, push, or agent-control operations.
Execution and review use these current paths:
batch: Task -> Execution (Codex CLI)
interactive: Task -> Session -> provider Thread -> Turn -> Execution -> normalized Events
passed Execution -> Review Request -> Conversation Routing -> Review Delivery
-> Extension Delivery -> Extension Review Completion -> ReviewResult
-> ReviewVerdict -> AutoIteration -> complete | next Execution | human requiredRequest correlation (correlation_key -> conversation_id) is identity evidence
only; ConversationRouting.conversation_id remains the authoritative Review
Delivery target.
Session is the long-lived interactive context and stores the provider Thread
ID. Turn is the provider-level unit for one interactive Execution. Batch
execution continues through codex exec --json - and does not automatically
create a Session. The Playwright Browser Worker remains an independent automation
path for explicit diagnostics and compatibility; current integrated delivery and
completion use the Extension/Bridge path, and the Worker is not an MCP Data Plane
capability.
Completed ReviewResults are parsed as schema-v1 ReviewVerdict values; the
integrated AutoIteration path handles APPROVE, ITERATE, and
HUMAN_REQUIRED outcomes.
Interactive Execution and status
submit_goal supports execution_mode: "batch" | "interactive", defaulting to
batch, plus optional provider model and reasoning_effort. Interactive
Execution uses the Codex app-server backend, discovers the provider catalog with
model/list, creates a Session and Thread, starts a Turn, and persists only
normalized LRM events. It does not silently select the first model.
The Session status model is created, starting, active, running_turn,
waiting_input, completed, failed, or terminated. The currently wired
interactive path uses created -> starting -> active -> running_turn -> completed|failed; approval, user input, pause, and resume scheduling are not
implemented. The compatible Execution status remains running, passed, or
failed.
The read-only status tools are:
get_session_statusbysession_idorgoal_id, including Session, Thread, model/effort, Goal, and current Execution status;get_execution_statusbyexecution_id, including proven Session/Thread/Turn association and bounded agent output;list_session_eventswith ordered, paginated normalized events. Provider JSON-RPC payloads are not exposed.
Default endpoint
http://127.0.0.1:12080/mcp
Start the server with:
npm install
npm start -- --workspace <path> --token <token>The port can be overridden with --port <number>. The token can also be
provided through LOCAL_REVIEW_MCP_TOKEN. Token precedence is CLI, environment,
then config file. A JSON config file can be provided with --config <path>:
{
"port": 12080,
"workspace": {
"id": "project",
"name": "Project",
"path": "C:\\path\\to\\project"
},
"workspaces": [
{
"id": "project",
"name": "Project",
"path": "C:\\path\\to\\project"
}
],
"auth": { "token": "<token>" },
"remote": { "enabled": false, "endpoint": "" },
"supervisor": {
"enabled": false,
"healthIntervalSeconds": 30,
"maxRestartAttempts": 3
}
}workspaces is optional for legacy configurations. When present, its entries
are the only workspaces that MCP can select; the top-level workspace identity
selects the active entry and is checked against the registry. A legacy string
workspace remains supported for direct single-workspace startup.
Set supervisor.enabled to true to run the MCP runtime under the Windows
Supervisor. It checks /health at the configured interval, performs at most
maxRestartAttempts automatic restarts, and exposes Start, Stop, Restart,
Open Log Folder, startup registration, and Exit from the Tray menu. Supervisor
logs are stored under the user's local application data directory and contain
only fixed lifecycle events.
Production Deployment
The supported deployment path is Windows → Local Review MCP → Cloudflare Tunnel → ChatGPT Web custom MCP connector.
Windows requirements
Windows PowerShell 5.1 or PowerShell 7.
Node.js with npm available as
node --versionandnpm --version.cloudflaredonPATHwhenremote.enabledistrue. Install it from the Cloudflare tunnel documentation.A workspace directory that already exists and is readable. The deployment scripts never create it.
From the repository root, install dependencies and build the release runtime:
npm install
npm run buildPrepare the local production configuration. The example contains no real token, endpoint, or workspace:
Copy-Item .\config.production.example.json .\config.production.jsonEdit config.production.json and set workspace to the project directory the
connector may review. Set remote.tunnelName to the existing Cloudflare Named
Tunnel name or UUID and remote.endpoint to its stable public HTTPS /mcp
endpoint. Keep config.production.json local; .gitignore excludes it.
Set the bearer token in the process environment before starting. It is not stored in the repository:
$env:LOCAL_REVIEW_MCP_TOKEN = "<long-random-review-token>"Make sure cloudflared is installed. The production Supervisor runs the
configured Named Tunnel with its local credentials file. If the installation
uses a tunnel token instead, set CLOUDFLARE_TUNNEL_TOKEN for that same
configured tunnel. Do not put either token in source control.
Run the standard startup entry point:
.\scripts\start-production.ps1 -Config ".\config.production.json"The entry point reads the configuration, runs preflight-check.ps1, then
starts the existing Local Review MCP runtime. The runtime starts the Windows
Supervisor when supervisor.enabled is true and starts the Cloudflare Tunnel
when remote.enabled is true. It prints the local health endpoint and any
ready remote endpoint without printing credentials.
The preflight check verifies Node/npm, installed dependencies, required config
sections, workspace access, and port availability. A missing cloudflared is
fatal only when remote access is enabled. It reports an occupied port and asks
you to change port; it never auto-installs dependencies, creates a workspace,
or selects another port.
Remote verification
After the tunnel reports a public endpoint, verify the deployment from a PowerShell process that has the remote URL and token:
$env:LOCAL_REVIEW_MCP_REMOTE_URL = "https://<public-hostname>/mcp"
$env:LOCAL_REVIEW_MCP_REMOTE_TOKEN = $env:LOCAL_REVIEW_MCP_TOKEN
.\scripts\verify-remote.ps1verify-remote.ps1 checks that unauthenticated and wrong-token health requests
return HTTP 401, the correct token returns status=ok, MCP initialize works,
and tools/list matches its embedded tool allowlist. The current runtime
advertises nineteen read-only tools plus submit_goal (20 registered tools);
this script still contains the older fifteen-tool allowlist, so its final
comparison is not a complete current-surface check. The remote test suite uses
the current registered-tool fixture for that check.
Remote MCP Setup
Remote access is disabled by default. Enable the Cloudflare provider with:
{
"remote": {
"enabled": true,
"provider": "cloudflare",
"tunnelName": "<tunnel-name-or-uuid>",
"endpoint": "https://<public-hostname>/mcp"
}
}Start the local runtime with an explicit workspace and token:
$env:LOCAL_REVIEW_MCP_TOKEN = "<long-random-review-token>"
npm start -- --workspace "C:\path\to\project" --config "settings.json"Install cloudflared and configure an existing Named Tunnel. remote.tunnelName
must contain its name or UUID, and remote.endpoint must contain the stable
public HTTPS /mcp URL. The Supervisor runs cloudflared tunnel run for that
tunnel and never creates a tunnel, changes DNS, or requests a temporary URL.
$env:LOCAL_REVIEW_MCP_TOKEN = "<long-random-review-token>"
# Optional when using token-based credentials for the configured Named Tunnel.
$env:CLOUDFLARE_TUNNEL_TOKEN = "<cloudflare-tunnel-token>"
npm start -- --workspace "C:\path\to\project" --config "settings.json"The Cloudflare provider invokes only the installed cloudflared executable,
does not upload configuration, and never logs credentials.
The live endpoint is returned by the provider and owned by TunnelManager;
remote.tunnelName and remote.endpoint are configuration inputs. No module
hardcodes a tunnel hostname.
ChatGPT Web connector
In ChatGPT Web, enable the workspace's developer/custom-app capability if the plan requires it, then open the Apps/Connectors settings and create a custom MCP app.
Enter the HTTPS endpoint reported by
TunnelManageror the authenticated/healthresponse, using the/mcppath.Select the connector's OAuth authentication option. The server publishes MCP protected-resource metadata, authorization-server metadata, dynamic client registration, and PKCE endpoints under the same public origin.
Scan the tools, confirm the read-only actions plus
submit_goal, save the draft app, and select it from a new chat. Ask for a code review; ChatGPT should callworkspace_listfirst, thenreview_summary,execution_output,workspace_info,git_status,git_diff,read_file, andsearch_textwith aworkspace_idwhen selecting a registered workspace.
Connector and browser readiness
For a real submit_goal handoff, keep the runtime, Tunnel (when remote access
is enabled), Bridge, and the exact ChatGPT connector available. Run the local
diagnostic after startup:
npm run diagnose:chatgpt-connector -- --config <config>If the exact connector has just been created or adopted, call workspace_info
through that exact OAuth connector and confirm it with the returned request ID:
npm run confirm:chatgpt-connector -- --config <config> --request-id <workspace_info.request_id>Continue only when the diagnostic reports ok=true, connector.status=verified,
connector.action=none, and ready remote/OAuth checks. The connector workflow
in docs/chatgpt-connector-workflow.md
covers exact-name checking, reauthorization, and adoption of an existing
ChatGPT connector. Confirmation evidence is OAuth-authenticated workspace_info
evidence for the current workspace and expires after ten minutes.
The unpacked MV3 extension is in extension/; it needs to be loaded manually
in Chrome or Edge and has no build step. After reloading the extension, refresh
the ChatGPT page so its content scripts are replaced, then use a concrete
conversation route rather than the New Chat root:
https://chatgpt.com/c/<conversation_id>
https://chatgpt.com/g/<project>/c/<conversation_id>The supported Project form is the one-segment route
/g/<project>/c/<conversation_id>. fiber.js runs in the MAIN world and emits
only bounded evidence from the current turn. For direct submit_goal, it
accepts only the exact assistant tool request for api_tool.call_tool or
Local_MCP_Connector.submit_goal whose args or arguments contains the
strict UUID v4 correlation_key. It never substitutes assistant text, tool
results, or message.metadata.request_id for that direct key. The content and
background scripts additionally require Fiber/URL conversation equality,
Chrome MessageSender.documentId, and the current navigation_epoch; stale,
conflicting, and new-chat identities produce no canonical evidence. A raw
WEB:* value is provisional and never becomes a canonical owner; only a valid
same-model serverId$() result can resolve it to a canonical conversation ID.
The Local Control Bridge is a separate loopback Control Plane server on
127.0.0.1, discovered on ports 12081 through 12085, using protocol 3.
It pairs one validated Extension Origin and authenticates protected identity,
delivery, and completion transport with a process-local bearer token.
GET /hello is discovery; protected identity evidence is posted to
/identity-evidence. If the Bridge is unavailable, the MCP Data Plane can still
start, but submit_goal cannot pass its Browser identity-channel readiness gate.
GET http://127.0.0.1:<port>/launcher/readiness is a loopback,
static-token-protected status endpoint also shown by the Launcher. ready means
the Bridge is available, the Extension is paired, and Extension presence was
seen within the ten-second presence window. Presence is only channel
readiness, not conversation proof. The Launcher may briefly retain a recent
READY display during its presentation grace period, but submit_goal still
checks live readiness and requires the exact Fiber/URL/document/epoch evidence
above.
submit_goal does not accept conversation_id. The model must generate a fresh
UUID v4 correlation_key for every call. The call first returns a durable
acceptance receipt while a PendingGoalSubmission waits for matching canonical
evidence (default TTL: two minutes); only then does Goal startup happen
asynchronously. accepted is not Goal, Session, Execution, or review
completion. If the key is not matched before expiry, no Goal is created. The
read-only get_identity_trace and get_evidence_transport_trace tools expose
hash-only, correlation-key-scoped diagnostics and never return raw payloads,
tokens, cookies, or message text.
After identity matching, Goal preflight still checks runtime readiness, the active registered workspace identity, and verified Connector/OAuth/remote readiness; Browser presence alone never authorizes a Goal.
The exact ChatGPT Web menu labels and availability depend on the workspace
plan. The MCP endpoint itself is /mcp; /health is an authenticated
readiness check. OpenAI's current MCP and Connectors guide
describes remote MCP server URLs and tool approval configuration.
At least one workspace is required. With a registry, the first entry is the
legacy active workspace unless the top-level workspace matches another
registered path. Without workspace_id, tools use that active workspace.
The current nineteen read-only tools are workspace_info, list_files,
read_file, search_text, git_status, git_diff, workspace_get_info,
workspace_list_files, workspace_read_file, workspace_search,
workspace_review_context, workspace_list, review_summary,
execution_output, get_session_status, get_execution_status,
list_session_events, get_identity_trace, and get_evidence_transport_trace.
The Control Plane tool submit_goal durably accepts a Goal and starts it after
canonical Extension evidence proves the conversation. The five explicitly
scoped workspace_* review tools require workspace_id; the other
workspace-scoped tools preserve optional active-workspace behavior, while
workspace_list has no workspace selector.
Git tools are bound to the selected registered workspace, do not expose Git
command arguments, and never perform write operations. workspace_list returns
only each workspace's stable id and display name, never its local path.
review_summary combines workspace metadata with Git status and diff counts.
execution_output only reads .review/execution_output.json and returns
{"available":false} when that file is absent; it never runs the recorded
command or accepts a file path.
submit_goal requires a fresh correlation_key and accepts an optional
workspace_id, title, goal,
requirements, acceptance_criteria, max_iterations (default 2),
execution_mode (default batch), model, and reasoning_effort. Its
conversation_id is resolved internally from the exact Extension evidence
chain; it is not caller-supplied.
The health endpoint requires the configured static Authorization: Bearer <token>
even on localhost and through Cloudflare Tunnel. MCP requests accept either that
legacy token or an OAuth access token. The health endpoint is
http://127.0.0.1:<port>/health; it returns the status, stable workspace
identifier, version, remote_status, endpoint_status, the public endpoint
only when it is ready, and an oauth_registry summary. The health summary uses
the relative oauth/clients.json location so it does not disclose local paths.
The loopback-only, static-token-protected GET /oauth/clients endpoint returns
the full registry path, load state, client count, and non-secret client summaries.
DELETE /oauth/clients/<client_id> removes one registration and
DELETE /oauth/clients clears registrations without deleting the registry file.
The health endpoint never returns tokens, credentials, local IPs, or workspace
absolute paths.
search_text accepts an optional workspace_id, query, workspace-relative
path and glob, regex, case_sensitive, and limit. Searches are
restricted to allowed text files up to 2 MiB, with at most 200 returned results
and 500 preview characters per result.
E2E verification
The remote suite uses the same Streamable HTTP MCP client flow as a remote
connector and covers initialize, tools/list, workspace registry selection,
ordered workspace review,
Bearer authentication, safe health metadata, sensitive-file denial, traversal/
absolute/drive/symlink path denial, and tunnel stop/restart. It creates a
temporary sample-project Git workspace and never commits review changes.
Run the release-candidate checks locally:
npm run typecheck
npm test
npm run buildThe Browser Worker review-submission diagnostic drives the complete local Review Delivery chain with a mock Page and does not require a ChatGPT login:
npm run diagnose:review-submissionThe live Goal E2E diagnostic exercises the Extension-based Goal, delivery, review-completion, verdict, and terminal-state path for one concrete ChatGPT conversation:
npm run diagnose:goal-e2e -- --config config.production.json --conversation-id <conversation_id>It requires the exact connector, an open target conversation, and a paired and present Extension. The automated Phase 5.6 review-loop test uses an in-process app-server test double; it verifies LRM lifecycle and verdict parsing, not live ChatGPT/browser delivery.
The interactive app-server smoke uses a temporary state root and requires the requested provider selection:
$env:CODEX_INTERACTIVE_MODEL = "gpt-5.6-luna"
$env:CODEX_INTERACTIVE_EFFORT = "max"
npm run test:interactive-goalTo probe an already deployed HTTPS endpoint with the optional remote test,
provide LOCAL_REVIEW_MCP_REMOTE_URL and
LOCAL_REVIEW_MCP_REMOTE_TOKEN only in the process environment before running
the remote test. No token or public URL is stored in the repository.
LocalReviewLauncher
LocalReviewLauncher/README.md describes the
independent PySide6 Windows launcher. start-launcher.cmd starts the existing
scripts/start-production.ps1 entry point; the launcher does not replace or
embed the MCP runtime. Its startup and status views cover Start/Stop/Refresh,
Workspace Registry, configuration validation/open/backup, OAuth client status,
MCP health, Tunnel/remote status, and Browser readiness through authenticated
local HTTP checks.
The read-only Task Dashboard lists only interactive codex_app_server Sessions
and shows Goal/Task, Session/Thread, model/effort, status, current Execution,
and last update. The Session Viewer shows the current Execution and the paginated
normalized Event Stream; adjacent agent-message deltas are aggregated for display
and the rendered stream is capped at 500 rows. It refreshes every five seconds
and provides an Open Codex Task locator using the proven Thread/Session IDs. The Launcher only
observes lifecycle state and does not submit, stop, resume, approve, or control
a Goal, Execution, Thread, or Turn. Separate cleanup actions can clear the
display or remove completed/failed/terminated persisted task records; running
Sessions are retained.
Security Notes
Local Review MCP provides read, search, review, and interactive status
capabilities through its nineteen read-only tools, plus the reviewed submit_goal Control Plane entry
point. It does not provide:
modifyorwrite_fileoperations;executeor shell operations;direct
agentor Codex/ChatGPT automation controls outsidesubmit_goal.
Keep LOCAL_REVIEW_MCP_TOKEN, CLOUDFLARE_TUNNEL_TOKEN, and
LOCAL_REVIEW_MCP_REMOTE_TOKEN in the process environment or another local
secret store. Never commit tokens, .env files, Cloudflare credentials,
private keys, or config.production.json.
This server cannot be deployed
Maintenance
Related MCP Connectors
Host your MCP tool over streamable HTTP in one command.
Read-only MCP server for the WebAssembly spec: instructions, types, sections, search, proposals.
Public MCP server for discovering open jobs. Search, filter, and get application links.
Repository knowledge graph MCP server for codebase understanding and debugging.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceA secure MCP server enabling read-only access and file search capabilities within a specified directory, while respecting .gitignore patterns.MIT
- AlicenseNot gradedqualityBmaintenanceSafe local MCP server for Windows to list, read, search, patch, backup, and verify code files in allowed folders, with Git integration and dry-run diffs.1MIT
- AlicenseNot gradedqualityBmaintenanceA local filesystem MCP server providing constrained file operations (read/write, directory management, search, metadata) within configurable directories, with read-only mode and zero runtime dependencies.2 npmMIT
- AlicenseNot gradedqualityBmaintenanceA minimal, security-focused MCP server that provides structured read/write access to exactly one local workspace, with built-in local Git checkpoints and rollback.1Apache 2.0