{"name":"multi-repository-code-workspace","version":"1.2.0","status":"ok","workspace_model":{"type":"multi_repository","description":"One deployment holds all projects. Each direct child directory of /workspace containing non-symlink Git metadata is one repository.","repository_selection":"Use the exact top-level folder name as repo_id.","patch_scope":"Each ZIP patch targets exactly one repository. Use separate ZIPs for separate repositories."},"repositories":[{"repo_id":"Dark-Star-Solutions","display_name":"Dark-Star-Solutions"},{"repo_id":"fourbears-website","display_name":"fourbears-website"},{"repo_id":"OpenAllasso","display_name":"OpenAllasso"},{"repo_id":"Restaurant-POS","display_name":"Restaurant-POS"}],"mcp_endpoint":"/mcp","http_endpoints":{"guide":"GET /","health":"GET /healthz","raw_zip_patch":"POST /v1/patch with streamed Content-Type application/zip and required X-Repo-ID header","command":"POST /v1/command with JSON"},"tools":[{"name":"apply_patch_zip","persistent":true,"repository_scope":"exactly_one","destructive":true,"preferred_input":"patch_file","compatibility_input":"patch_zip_base64","description":"The only persistent source mutation mechanism. Accepts a real ZIP file from ChatGPT, with Base64 retained only as a size-limited fallback."},{"name":"run_command","persistent":false,"repository_scope":"exactly_one","description":"Runs an arbitrary shell command in a disposable copy of one repository."}],"patch_transport":{"preferred_for_chatgpt":{"input_field":"patch_file","shape":{"download_url":"required temporary HTTPS URL supplied by ChatGPT","file_id":"required ChatGPT file ID","mime_type":"optional","file_name":"optional"},"instruction":"Create a real ZIP artifact and pass it as patch_file. Do not manually generate Base64."},"compatibility_fallback":{"input_field":"patch_zip_base64","max_compressed_bytes":7000000,"instruction":"Use only when the MCP host cannot pass a file."},"direct_http":{"endpoint":"POST /v1/patch","content_type":"application/zip","streamed":true}},"deletion_policy":{"enabled":true,"authentication_required_by_default":true,"insecure_noauth_override_enabled":true,"regular_files_only":true,"max_files_per_patch":500,"max_backup_bytes_per_patch":500000000,"unsupported":["directories","recursive deletion","globs","symlinks","repositories",".git","protected MCP metadata","rename","move"]},"rules":["No direct source-reading, source-search, individual file-writing, replacement, movement, copying, or standalone deletion MCP tools are exposed.","The user supplies project structure and relevant code to the AI and may be asked for it again at any time.","One ZIP can apply to one repository only.","Pass the same exact repo_id in the tool request and in mcp-patch.json.","Use separate ZIPs when changing separate repositories.","Create and pass a real ZIP file through patch_file; do not manually generate Base64 when file input is available.","Only a validated ZIP patch may persistently create, replace, or explicitly delete regular repository files.","Schema version 1 supports upsert only. Schema version 2 supports upsert and regular-file delete.","Delete entries require before_sha256 and no payload bytes.","Commands run against disposable repository copies and cannot modify persistent repositories.","Repository names and Git repositories are discovered dynamically without redeploying the server."],"accepted_zip_layouts":{"flat":{"description":"Extracting the ZIP directly reveals mcp-patch.json and repository-relative upsert payload paths.","example":["mcp-patch.json","package.json","src/app.ts"]},"single_wrapper":{"description":"Extracting the ZIP reveals one folder containing mcp-patch.json and repository-relative upsert payload paths. The server strips that one wrapper.","example":["patch-bundle/mcp-patch.json","patch-bundle/package.json","patch-bundle/src/app.ts"]},"delete_only_examples":["mcp-patch.json","patch-bundle/mcp-patch.json"],"rejected":["Mixed root files and wrapped files","More than one top-level wrapper folder","Nested files/<repo_id>/ payload layout","Content for more than one repository","Files not declared by upsert operations","Payload bytes for delete operations"]},"patch_format":{"format":"mcp-code-patch","supported_schema_versions":[1,2],"repository_scope":"exactly_one","manifest_path_after_normalization":"mcp-patch.json","payload_layout_after_normalization":"<exact final repository-relative path for upsert operations>","supported_operations":["upsert","delete"],"protected_paths":[".git",".git/**",".mcp",".mcp/**",".mcp-project.json",".mcp-*"],"manifest_example":{"format":"mcp-code-patch","schema_version":2,"patch_id":"unique-patch-id","repo_id":"example-repository","summary":"Replace one file and remove one stale file.","expected_head":"optional-current-git-head","files":[{"operation":"upsert","path":"src/example.ts","before_sha256":"64-lowercase-hex-for-existing-file-or-null-for-new-file","after_sha256":"64-lowercase-hex-for-payload","mode":"0644"},{"operation":"delete","path":"src/stale-example.ts","before_sha256":"64-lowercase-hex-for-current-file","reason":"No longer referenced."}]}},"command_model":{"repository_scoped":true,"retained_sandboxes_supported":true,"persistent_workspace_writable":false,"note":"A command can destroy its disposable copy, but it cannot create, replace, or delete files in the durable repository."},"ai_instructions":"This is one shared development server containing multiple independent Git repositories under one workspace.\n\nThe MCP intentionally exposes exactly two tools: apply_patch_zip and run_command. It does not expose direct source-reading, source-search, individual file-writing, replacement, movement, copying, or standalone deletion tools.\n\nThe user supplies project structure and relevant source code in the conversation. Ask the user for the current project structure, complete files, or newer versions of affected files whenever the available context is incomplete, ambiguous, or stale. The user may provide them again at any time. Never invent the current bytes of an existing file.\n\nRepository binding rules:\n- Use the exact immediate top-level repository folder name as repo_id.\n- Every apply_patch_zip call targets exactly one repository.\n- One ZIP must never contain a patch for more than one repository.\n- Pass repo_id explicitly to apply_patch_zip, and put the same repo_id in mcp-patch.json.\n- If changes are required in two repositories, create and apply two separate ZIP files, one ZIP per repository.\n- The ZIP wrapper-folder name never selects the repository.\n\nPreferred ZIP transport:\n- Create a real .zip artifact using code execution or an artifact/file creation environment.\n- Pass that real ZIP through the apply_patch_zip patch_file argument.\n- Do not manually write, reason over, paste, or synthesize a large base64 string when patch_file is available.\n- patch_zip_base64 is only a size-limited compatibility fallback for MCP hosts that cannot pass files.\n- Do not pass both patch_file and patch_zip_base64.\n\nZIP layout rules:\nThe server accepts exactly two archive layouts and normalizes them before validation.\n\nLayout A — flat ZIP root. Extracting the ZIP directly reveals mcp-patch.json and the patched code paths:\n  mcp-patch.json\n  package.json\n  src/app.ts\n  src/routes/users.ts\n\nLayout B — one enclosing folder. Extracting the ZIP reveals exactly one folder, and that folder contains mcp-patch.json and the patched code paths:\n  any-wrapper-name/\n    mcp-patch.json\n    package.json\n    src/app.ts\n    src/routes/users.ts\n\nFor Layout B, the server automatically removes exactly one common top-level wrapper directory. The wrapper name is ignored and does not select the repository. repo_id selects the repository.\n\nDo not create mixed layouts. Do not put some files at the ZIP root and others under a wrapper. Do not create multiple top-level wrapper folders. Do not use files/<repo_id>/... or any repository-name prefix inside the normalized patch root. After optional wrapper removal, every upsert payload file must be stored at its exact final repository-relative path.\n\nPatch manifest rules:\n- mcp-patch.json must be at the normalized patch root.\n- The manifest contains repo_id, optional expected_head, and a files array.\n- Include only payload files declared by upsert operations. Undeclared files cause rejection.\n- Include complete final bytes for every changed or new file.\n- Every existing upsert requires its exact current SHA-256 in before_sha256.\n- Use before_sha256: null only for a genuinely new file.\n- Include after_sha256 for each upsert payload.\n- Schema version 1 supports upsert only.\n- Schema version 2 supports upsert and explicit regular-file delete operations.\n\nDelete rules for schema version 2:\n- Use operation: \"delete\" only for a specific stale regular file that must be removed.\n- Every delete requires the exact current before_sha256.\n- A delete entry may include a short reason.\n- A delete entry must not include after_sha256, mode, source, or payload bytes.\n- Do not put a deleted file into the ZIP. A delete-only ZIP contains only mcp-patch.json, optionally under one wrapper folder.\n- Never delete directories, use globs, delete recursively, delete repositories, delete symlinks, delete Git metadata, or delete protected MCP metadata.\n- Never represent rename or move as an implicit delete without also creating the intended replacement path explicitly and explaining the change.\n- Deletion may be disabled by deployment policy. If FILE_DELETE_DISABLED is returned, do not bypass it through run_command; report that the administrator must enable deletion.\n\nOnly apply_patch_zip can persistently create, replace, or delete files. Never claim persistent changes unless apply_patch_zip returns ok=true with dry_run=false.\n\nrun_command accepts arbitrary shell commands, but commands execute only in disposable copies of one selected repository. Command filesystem changes are temporary and cannot modify persistent repositories. Do not use run_command as a substitute for reading source code or as a persistent editing or deletion mechanism. If generated output must persist, place its intended final files and delete declarations into a new single-repository ZIP patch.\n\nRecommended workflow:\n1. Confirm the exact repo_id from the ChatGPT Project instructions or the user.\n2. Work from user-supplied source and structure.\n3. Build mcp-patch.json with schema version 2 when any deletion is needed; otherwise version 1 or 2 is valid.\n4. Put complete final bytes only for upsert entries into the ZIP.\n5. Create an actual ZIP file artifact.\n6. Call apply_patch_zip with repo_id and patch_file.\n7. If the patch conflicts, ask for the latest affected files; never guess current hashes or bytes.\n8. After patching, run relevant tests, builds, linting, type checks, Git status, or Git diff in the disposable sandbox.\n9. Report the selected repository, created/replaced/deleted paths, detected ZIP layout, patch source, command outcomes, conflicts, skipped checks, truncated output, and uncertainty honestly."}