Sora Commander
Connects ChatGPT to a Windows PC through OpenAI's Secure MCP Tunnel, enabling ChatGPT to read and search allowed files, run commands, check results, and request local approval for unsafe actions.
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., "@Sora CommanderRun the tests in my project folder and tell me what failed."
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.
Sora Commander
Ask in an ordinary ChatGPT chat, and ChatGPT works on your Windows PC. You approve each step in a window on your screen.

There is no separate app or terminal to talk to. You chat with ChatGPT as usual, and it can read your files, run commands, check the results and keep going, in the same conversation:
"Run the tests in my project folder and tell me what failed."
"Find where this error message comes from, and show me the lines around it."
"Start the build, and tell me when it finishes."
To use your own project folders in these examples, first configure the allowed folders in docs/INSTALL.md. Without that file, only this checkout is allowed. The list is read at startup; restart both the Broker and its client after changing it.
It saves the usage of your other tools. The ChatGPT chat you already use does the reading, running and checking, so that work does not use up the limits of a separate coding agent. ChatGPT's own message limits still apply.
Sora Commander is an MCP server for Windows. It connects to ChatGPT through OpenAI's Secure MCP Tunnel. Commands that are not plainly safe open an approval window on your PC, and they run only if you approve them. So you need to be at the PC to approve them. Reading files and checking results need no window.
v0.1 developer preview. Not accepted for production use. In addition to the author's normal environment, a fresh Windows Sandbox trial on 2026-11-09 (administrator account) reached ChatGPT file reads and an Owner-approved command with exit code 0. Python and Git were borrowed read-only from the host; installing Python was not tested. This limited trial is not production acceptance. This software lets an AI operate your computer. Read each approval window before you click, and use it only if you can judge what a command does.
日本語の説明は下にあります。
What it does
Runs commands and reports their output, exit codes and running jobs
Reads and searches files inside the folder you allow
Creates and edits supported text files inside allowed folders, after you check the proposed content and approve it in the local window
Opens a local approval window for commands and edits. There is no remote approval
In Broker mode only, refuses to repeat a command whose outcome is unknown, even after a restart, until you clear it by hand
Fails closed when the window cannot open, the session is locked, or its records cannot be written
Related MCP server: aki-mcp-sv
Before you start
Windows 11, signed in to your own account
Python 3.13
An OpenAI account that can create a Secure MCP Tunnel and a custom MCP connection
Availability depends on your account and workspace permissions. Follow the current OpenAI help, Connecting custom MCP servers in ChatGPT, for requirements and connection steps.
The tunnel program is not included. You get it from OpenAI.
Install
See docs/INSTALL.md.
Use Broker mode by default: start tools\start-broker-mode.cmd once. It waits
for the Broker pipe to be present, then starts the tunnel. Usual mode is an
optional alternative and does not provide Broker mode's duplicate-execution
protection after a restart.
Limits
remote_ready=falseandLOCAL_DEMO_ONLYare what this version reports. They mean it is not accepted for production.The code is not signed and no installer is provided.
It runs with your own Windows rights. Another program under your account can read the key file, and can edit the launch records.
There is no automatic reconnect. If the PC restarts, you start it again by hand.
Not tested: another physical PC, a separate Windows-user setup, installing Python from scratch, paths with non-ASCII characters (including Japanese), a power loss during a job, or plans other than the author's.
Report security problems as described in SECURITY.md.
License
The code is under the GNU AGPL v3.0. You may use and change it for free. If you distribute it, or offer a changed version over a network, you must make your source available under the same license.
The Sora Commander name and character artwork are not covered. See NOTICE.md.
There is no warranty. You are responsible for what you approve.
Sora Commander is an independent project. It is not made, endorsed or supported by OpenAI. ChatGPT and Sora are products of OpenAI.
日本語
いつもの ChatGPT のチャットで頼むだけで、ChatGPT があなたの Windows PC で作業します。1 つずつ、画面の窓で承認します。

別のアプリやターミナルで話す必要はありません。普段どおり ChatGPT とチャットするだけで、同じ会話の中でファイルを読み、コマンドを実行し、結果を確かめて、次の作業に進めます。
「プロジェクトのフォルダでテストを流して、失敗したものを教えて」
「このエラーメッセージがどこから出ているか探して、前後の行を見せて」
「ビルドを始めて、終わったら教えて」
自分のプロジェクトを扱う例は、導入手順で許可フォルダを 設定した場合のものです。設定ファイルがなければ、このcheckoutだけを許可します。 変更は起動時に読み込み、反映にはBrokerとクライアント両方の再起動が必要です。
他のツールの使用量を節約できます。 読む、実行する、確かめるといった作業を、普段使っている ChatGPT のチャットが受け持つので、別のコーディング AI の使用量の上限を使わずに済みます。ChatGPT 自体のメッセージの上限はあります。
OpenAI の Secure MCP Tunnel で ChatGPT とつなぐ、Windows 用の MCP サーバーです。安全と言い切れないコマンドは PC の画面に承認窓を出して、承認したときだけ実行します。承認するときは PC の前にいる必要があります。 ファイルを読むことや結果の確認には、窓は出ません。
許可フォルダの中の対応するテキストファイルを、承認窓で提案された内容を確認して承認した後に、ChatGPT が作成・編集できます。
v0.1 開発者向けプレビューです。実用としての受入はしていません。 作者の通常環境に加え、2026-11-09に新しいWindowsサンドボックス(管理者権限のユーザー)で、ChatGPTからのファイル読取りとOwner承認付きコマンドの終了コード0まで試しました。PythonとGitはホストから読み取り専用で借りており、Pythonの導入は試していません。限定的な試行で、実用・本番の受入ではありません。AIにPCを操作させるソフトです。承認窓の内容を読んでから押してください。コマンドの意味を判断できる方だけ使ってください。
未試験:別の実PC、別のWindowsユーザーでの導入、Pythonの導入からの準備、日本語などASCII以外の文字を含むパス、ジョブ中の電源断、作者と異なるChatGPTプラン。
必要なもの: Windows 11、Python 3.13、Secure MCP Tunnel とカスタム MCP 接続を作れる OpenAI のアカウント。
利用可否はアカウントとワークスペースの権限に依存します。 接続はOpenAI公式ヘルプの最新の「ChatGPT でのカスタム MCP サーバーへの接続」に従ってください。
標準はBrokerモードです。 tools\start-broker-mode.cmdを1回起動します。
Brokerのパイプが用意できるまで待ってからトンネルを起動します。
結果が分からないコマンドを再起動後も繰り返さない機能はBrokerモードだけです。
補足の通常モードには、この二重実行の防止がありません。
導入は docs/INSTALL.ja.md を見てください。
ライセンス: コードは GNU AGPL v3.0 です。無料で使えて、変更もできます。配布するときや、変更版をネットワーク越しに提供するときは、同じライセンスでソースを公開する必要があります。Sora Commander の名前とキャラクター画像は対象外です。詳しくは NOTICE.md を見てください。
保証はありません。承認した操作の責任は、利用者にあります。
Sora Commander は個人の独立したプロジェクトで、OpenAI の製品ではありません。OpenAI が作ったり、推奨したり、サポートしたりしているものでもありません。ChatGPT と Sora は OpenAI の製品です。
Available Tools
38 toolsawait_command_resultA
Wait for an existing Owner decision/job, without another execution.
Use after an earlier run_command_wait or REVIEW when you already have pending_id. Wait for that same Owner decision and job without new execution, approval, or submission. Timeout is not permission to retry.
Inputs: pending_id (required), wait_seconds. Returns: object
await_process_outputA
Wait for an already-running JobManager session, never start another.
Use to wait on an already-started session_id for a bounded period and retrieve its result. This is observation, not a new command; do not reissue run_command on timeout.
Inputs: session_id (required), wait_seconds. Returns: object
compare_text_filesA
Compare two Owner-scoped existing files without editing either.
Use to compare two existing Owner-scoped text files as a read-only diff. before_path and after_path are files, not patches; context_lines adjusts displayed context only.
Inputs: after_path (required), before_path (required), context_lines. Returns: object
create_directoryA
DEV_ONLY: ask the local Owner GUI to create one absent directory in configured roots. Reject links, protected names and existing targets; no command/job spawn. UNKNOWN requires manual reconciliation, never retry or assumed rollback.
Inputs: path (required). Returns: object
create_fileA
DEV_ONLY: ask the local Owner GUI to create one new text file in configured roots, showing its path and complete content first. Existing targets are never overwritten; links and protected names are rejected; no command or job spawn. UNKNOWN requires manual reconciliation, never retry or assumed rollback.
Inputs: path (required), content (required). Returns: object
find_filesA
Bounded name-only discovery inside configured Owner read roots.
Use to discover filenames by name under an allowed directory within bounded depth/result count. This is path discovery, not a content search or write authorization.
Inputs: name (required), path (required), depth, max_results. Returns: object
get_configA
Read-only nonsecret DEV configuration view: reports flags, root count and rootsConfigured boolean only. No paths, credential values, identity or configuration mutation. This view grants no privileges and establishes no protected Broker acceptance.
Inputs: no named parameters. Returns: object
list_folderA
List bounded entries under Owner-approved read roots. Read-only; depth=0 preserves immediate children and the original schema. Depth 1 to 4 adds relative paths and bounded recursion, excluding private names, links and denied folders. Limit bounds output, not authorization.
Inputs: path (required), depth, limit. Returns: object
list_folder_pageA
Continue a bounded listing without widening Owner read roots.
Use to page a folder listing when list_folder's output is insufficient. Provide the same path, entry offset and limit. Read-only and confined to Owner read roots.
Inputs: path (required), limit, offset. Returns: object
list_processesA
Read-only bounded PID and executable basename listing using installed psutil or Windows Toolhelp snapshot. No command lines, environment, Owner identity, credentials or process control. Safe error on unavailable/incomplete enumeration; never starts a job or installs dependencies.
Inputs: limit. Returns: object
list_sessionsA
Use to list current Host JobManager sessions and their states for observability. Read-only; prior-process sessions instead use previous_sessions or recovery_overview.
Inputs: no named parameters. Returns: object
move_fileB
DEV_ONLY Windows: request local Owner GUI review of one exact file move in existing roots. No overwrite, directory move or job spawn. Cooperative checks are not protected CAS. UNKNOWN requires manual reconciliation; never auto-retry or assume rollback.
Inputs: source (required), destination (required). Returns: object
path_infoA
Read-only file size and bounded digest; never authorizes a write.
Use for non-mutating file or directory metadata checks on an allowed path, including size/digest when available. Not a write grant and not proof of user consent.
Inputs: path (required). Returns: object
pingA
Use for a quick, read-only health probe of the connected MCP Host. No input; does not establish that protected remote readiness, Broker acceptance, or a particular tool is exposed in ChatGPT.
Inputs: no named parameters. Returns: object
preview_source_createA
Review a proposed general source file without creating it.
Use to validate and preview creating a new source file at a permitted path. No file is created; send full proposed content only when safe, then separately seek Owner-approved creation if appropriate.
Inputs: path (required), content (required). Returns: object
preview_source_patchA
Build one literal source edit proposal; no file write or grant.
Use to preview one literal exact-text source replacement against the expected SHA-256. No write/approval. Source up to 65536 bytes; complete diff up to 16384 bytes. Returns old/new SHA-256 and the complete diff, never the whole proposed content. A generic tool failure is not an Owner rejection or a write; resolve stale or ambiguous source rather than guess.
Inputs: path (required), new_text (required), old_text (required), expected_sha256 (required). Returns: object
preview_text_editA
Use before a requested replacement edit to validate path, proposed full content and the original file SHA-256. Preview only: no write or Owner grant. Do not expose sensitive content in chat.
Inputs: path (required), content (required), expected_sha256 (required). Returns: object
previous_outputA
Read archived logs from a PREVIOUS Host invocation; never replay.
Without ID returns a bounded metadata index. With ID returns only
that old session's stored output. A local Owner opt-in is mandatory.Use to read an Owner-verified result archive from a PREVIOUS Host invocation. Omit session_id for metadata index, supply the original archived session_id for output and eligible safe-command identity. May contain sensitive stdout; never repost IDs or output without Owner verification, and never replay jobs.
Inputs: session_id. Returns: object
previous_sessionsA
Use to inspect prior Host invocation START/END journal snapshots without command replay. Read-only metadata; journal-only records are not proof of no side effects or original argv.
Inputs: no named parameters. Returns: object
read_many_text_filesB
Read up to eight bounded existing UTF-8 files in one MCP call.
Use to read up to eight existing UTF-8 files in one bounded, read-only call. Provide distinct paths in approved roots; each file has its own byte limit.
Inputs: paths (required), max_bytes_per_file. Returns: object
read_process_outputA
Use to page stdout/stderr for an existing current-process JobManager session. Reads bounded output from offset; does not start or retry commands. Use previous_output for a prior Host invocation.
Inputs: session_id (required), offset. Returns: object
read_text_chunkB
Read a bounded UTF-8 tail or resume from a previous byte cursor.
Use to read a bounded UTF-8 tail (offset -1) or resume at an explicit byte cursor. Useful for logs and evolving files; never creates or changes them.
Inputs: path (required), offset, max_bytes. Returns: object
read_text_fileA
Use for a bounded UTF-8 read of an existing file within configured Owner read roots. Never modify the file; may return sensitive text, so share only when appropriate.
Inputs: path (required), max_bytes. Returns: object
read_text_linesA
Read numbered UTF-8 source lines without creating a new grant.
Use when exact numbered source lines are needed for review. Choose 1-based start_line and a bounded max_lines; no edits or permission changes.
Inputs: path (required), max_lines, start_line. Returns: object
read_text_pageA
Read a UTF-8 page within existing Owner-configured read roots.
Use for large UTF-8 files needing byte-offset pagination within approved read roots. Reuse the returned byte cursor rather than guessing; no file modifications.
Inputs: path (required), offset, max_bytes. Returns: object
recovery_overviewA
Read-only current/prior session guidance, never automatic replay.
A production BrokerHost cannot claim this DEV_ONLY aggregation.Use after reconnect to interpret current/prior session and opt-in archive evidence in READ_ONLY_MANUAL_RECOVERY mode. No arguments, grants or auto-retry. Owner verification is required for private archive IDs/commands; ARCHIVE_ONLY remains outcome-unknown. Not protected Broker acceptance.
Inputs: no named parameters. Returns: object
request_source_patch_devA
DEV_ONLY cooperative literal source patch: reuse preview_source_patch, show the complete proposed content and diff to local Owner GUI, then recheck SHA before replacement. One exact anchor only; no fuzzy edit, job spawn or protected Broker acceptance. Never retry an UNKNOWN result.
Inputs: path (required), new_text (required), old_text (required), expected_sha256 (required). Returns: object
request_statusA
Read-only lookup by the original caller's request ID.
No new command, approval, or queue entry is created. UNKNOWN does
not prove the old request never ran and MUST NOT trigger auto-retry.Use with the original request_id to check a prior command's status without re-submission. UNKNOWN is inconclusive and must never justify an automatic retry.
Inputs: request_id (required). Returns: object
review_statusA
Read-only observation using an existing pending_id: returns the stored Owner command approval/launch result, or the DEV_ONLY send_input input outcome when the ID belongs to stdin input. Does not approve, launch, send input or rerun. For command reviews, RUNNING / LAUNCH_ACCEPTED may remain after the job has COMPLETED: this is NOT the current job state. Use request_status(request_id) or await_process_output(session_id) for the job. For send_input, observe its original pending_id, not the command launch, and never send the input again. On PENDING follow the same pending_id; UNKNOWN does not prove no job ran or no input was sent. Never resubmit to check status.
Inputs: pending_id (required). Returns: object
run_commandA
Legacy immediate-start API. REVIEW returns pending_id.
interactive=True requires background=True and the DEV_ONLY isolated
Python numeric REPL allowlist, with explicit local launch review.
Prefer run_command_wait for normal work: it observes the Owner GUI
click and returns job output without asking the Owner to type
'approved'. Do not reissue a command merely to check its result.Use only for legacy immediate command submission. A REVIEW result needs a later status/wait call; normally prefer run_command_wait. Owner approval is local to Windows. Never resubmit the same operation on timeout or UNKNOWN. ERROR OwnerReviewUnavailable (reason OWNER_SESSION_UNAVAILABLE, REVIEW_BUSY or OWNER_REVIEW_FAILED; launch_outcome NOT_STARTED) means no Owner dialog was shown and nothing ran: report it and wait for the Owner, never resubmit automatically.
Inputs: cwd (required), argv (required), executable (required), timeout, +4 more. Returns: object
run_command_waitA
Run, wait for local Owner approval, then return bounded output.
interactive=True opts into the DEV_ONLY isolated numeric Python REPL.
Use wait_seconds=0 for prompt asynchronous observation, then send_input.
Owner permission comes only from the Windows GUI, not MCP. On a
wait timeout use await_command_result(pending_id) or existing output
tools; never repeat run_command_wait to avoid duplicate execution.Preferred command submission for tasks needing Owner GUI approval and a bounded wait for output. Use once per operation. On PENDING or timeout, continue through await_command_result with the returned pending_id; never reissue this command. ERROR OwnerReviewUnavailable (reason OWNER_SESSION_UNAVAILABLE, REVIEW_BUSY or OWNER_REVIEW_FAILED; launch_outcome NOT_STARTED) means no Owner dialog was shown and nothing ran: report it and wait for the Owner, never resubmit automatically.
Inputs: cwd (required), argv (required), executable (required), timeout, +4 more. Returns: object
search_codeA
Literal UTF-8 source search; results include relative path and line.
Use for literal text search within bounded UTF-8 files under approved roots. Supply the exact search text, depth and result cap. Search results may expose sensitive lines; read-only.
Inputs: path (required), text (required), depth, max_results. Returns: object
send_inputA
DEV_ONLY: ask the local Owner GUI to send one exact numeric line ONCE to this manager's previously approved interactive Python process. Returns pending_id; observe through await_command_result or review_status only. No arbitrary code, secrets, PID attachment, input logging or retries. UNKNOWN stops the session.
Inputs: input_id (required), input_text (required), session_id (required). Returns: object
sha256_fileA
Stream a bounded file hash, with no install/execute permissions.
Use to compute the SHA-256 of an approved existing file without reading full contents into chat or changing permissions. Hash alone does not establish a trusted signature.
Inputs: path (required). Returns: object
statusA
Use for read-only diagnostic status and local tool registration fingerprint. No input. LOCAL_REGISTRATION_SNAPSHOT is not proof of ChatGPT-side tool publication, remote readiness, or security acceptance.
Inputs: no named parameters. Returns: object
stop_processA
Use only when the Owner explicitly intends to cancel an existing session_id. This modifies a running job; does not start a new one. Confirm the exact target; do not infer outcomes from missing sessions.
Inputs: session_id (required). Returns: object
stop_process_waitA
Explicitly cancel a job, then observe that SAME job to completion.
Use for explicit cancellation of the existing session_id followed by a bounded wait for its observed result. No new job or automatic replay. Only cancel when Owner intended.
Inputs: session_id (required), wait_seconds. Returns: object
tool_catalogA
Actual local SDK registration snapshot; NOT connector publication.
Use to inspect only the local FastMCP tool registration count, names and schema fingerprint. No args and no remote publication guarantee; compare against ChatGPT's visible action list for stale tool snapshots.
Inputs: no named parameters. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
TDQS
Scored across 38 tools
Several clusters of tools have overlapping purposes: run_command, run_command_wait, await_command_result, request_status, review_status, and list_sessions all concern command submission/observation, and ping, status, get_config, recovery_overview, and tool_catalog all overlap as read-only diagnostics. File reading is fragmented across read_text_file, read_text_page, read_text_lines, read_text_chunk, and read_many_text_files, and preview_text_edit vs preview_source_patch vs request_source_patch_dev are near-duplicates. The descriptions work hard to differentiate them, but the boundaries remain genuinely hard for an agent to choose correctly.
Almost all tools follow a predictable snake_case verb_noun convention (read_text_file, preview_source_patch, stop_process, create_directory). A few outliers are noun-only or vague (ping, status, get_config), but they are still readable and the overall pattern holds.
38 tools is heavy for what is essentially a local command-execution and file-access server. Many of them are redundant variants (five ways to read text, four ways to check a pending request) that could be collapsed into parameters on a smaller set of tools.
The surface covers command execution, session lifecycle, and file reads/writes extensively, but there are notable gaps: no delete file tool, no copy/rename operation, and no directory listing counterpart beyond read access. Writes are preview-first with no direct confirmed-write companion for most mutations, forcing awkward multi-step workarounds.
Maintenance
Related MCP Connectors
Connect ChatGPT, Claude, Cursor or VS Code to your Windows PC: files, terminal, browser, apps.
Use your Mac, Windows or Linux computer from ChatGPT, Claude or Codex: files, commands, documents.
Read and search folders on your own computer with explicit consent. Files are never uploaded.
Connect AI assistants to your approved computer for files, commands, browser and desktop tasks.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables ChatGPT to securely control a Windows PC via a local agent, supporting file operations, Chrome automation, and allowlisted apps with audit logging and approval workflows.MIT
- AlicenseNot gradedqualityBmaintenanceEnables Claude AI to securely access files, run shell commands, and search through a Windows computer with explicit user permission.7 npmMIT
- AlicenseAqualityCmaintenanceEnables a private ChatGPT app to remotely control a Windows PC through file operations, PowerShell, screenshots, mouse and keyboard input, clipboard, and Chrome browser automation.212MIT
- AlicenseNot gradedqualityAmaintenanceEnables ChatGPT to access approved local Windows folders, run commands, control the desktop, and manage session history through a permission-bounded MCP server.5,147MIT