AppLock
Encrypts local Google Antigravity sessions out of their history and hides chosen Gemini web chats via the browser extension. Provides MCP tools to list, hide, unlock, read, and restore these hidden sessions and chats.
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., "@AppLockhide this Claude Code session and lock the vault"
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.
AppLock
Lock and hide the AI chats you choose, behind Touch ID or a password — like Locked Notes on a Mac.
Browser extension hides chosen ChatGPT, Claude.ai and Gemini chats from the sidebar and shows a lock screen if one is opened directly.
MCP server encrypts local Claude Code and Google Antigravity sessions out of their history, and lets any MCP client (Claude Code, Antigravity, ChatGPT developer mode) hide chats for you.
Website with the full guide: https://harmantaj.github.io/applock-mcp/ (source in website/).
Why two pieces
ChatGPT, Claude.ai and Gemini keep chats on their servers. An MCP server only gives a model tools; it can't change what a web page shows. So the extension does the hiding in the browser, and the MCP server handles local history plus a lock-only bridge to the extension.
Related MCP server: sieve-map
Install
npm install -g https://github.com/Harmantaj/applock-mcp/releases/download/v0.2.0/applock-mcp-0.2.0.tgz
applock-mcp setup # passphrase + optional Touch ID
applock-mcp install claude # or: antigravity | chatgptBrowser extension: download applock-extension.zip from the website (or use the extension/ folder), open chrome://extensions, enable Developer mode, Load unpacked.
ChatGPT
ChatGPT only connects to remote MCP servers:
applock-mcp serve --http --port 8787
cloudflared tunnel --url http://localhost:8787Then in ChatGPT: Settings › Apps & Connectors › Advanced › Developer mode › create a connector with https://<tunnel>/mcp/<secret> (the secret path is printed by applock-mcp install chatgpt), no authentication.
Tools
Tool | Purpose | Needs unlock |
| Vault state, hidden count, extension connection | no |
| Visible Claude Code / Antigravity sessions | no |
| Encrypt a session into the vault ( | no |
| Web chats seen by the extension | no |
| Lock a web chat ( | no |
| Touch ID prompt or local passphrase page | — |
| Lock now | no |
| Everything in the vault | yes |
| Read a hidden transcript | yes |
| Put a session back | yes |
Security model
Sessions are sealed to an X25519 public key (ephemeral ECDH + HKDF-SHA256 + AES-256-GCM), so hiding never needs the passphrase. The private key is wrapped with scrypt(passphrase); with Touch ID a copy lives in the macOS Keychain and a Swift helper releases it after
LAContextauthentication.The passphrase is never passed through the model: unlocking uses the Touch ID sheet or a one-time page on
127.0.0.1.The bridge on
127.0.0.1:47521accepts only browser-extension origins, pins the first extension that pairs, and is lock-only — nothing it sends can reveal a chat.The extension uses PBKDF2-SHA256 (600k) with lockout, and WebAuthn (platform authenticator) with local signature verification.
Locks and the password hash live in
chrome.storage.sync, so they follow your Chrome profile to your other computers; chat titles and the Touch ID key stay on each computer.Forgot the extension password? Forgot password? on the lock screen or popup resets it with Touch ID or the one-time recovery code (100 bits, stored hashed, rotated on use).
Not protected: the provider's servers, the ChatGPT/Claude/Gemini phone apps (use iOS Require Face ID on the app instead), removing the extension, malware running as you. The Claude desktop app keeps its own session title list.
Development
npm install
npm test # build + unit + MCP client tests (stdio and HTTP)
npx playwright install chromium
npm run test:e2e # extension on mocked ChatGPT/Claude/Gemini, bridge, websitedocs/REQUIREMENTS.md has the research notes and requirements.
License
MIT
Available Tools
10 toolsapplock_statusAppLock statusARead-only
Shows whether AppLock is set up, locked or unlocked, how many chats are hidden, and whether the browser extension is connected.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe, non-mutating call, so the description earns credit for going further by enumerating the specific state fields the caller will learn (setup, lock state, hidden count, extension connection). It does not discuss permissions, caching, or refresh behavior, so it falls short of full disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that lists the returned state facts with no filler or redundancy. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must convey what the call returns, and it does so completely: setup status, locked/unlocked, hidden chat count, and extension connectivity. For a zero-parameter read tool, nothing an agent needs to invoke or interpret it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, which is the baseline-4 case; there is nothing to misinterpret, and the description correctly implies the call is parameterless by framing it as a global status query.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific read verb ('Shows whether') and the exact resource and facts reported: setup state, locked/unlocked, hidden chat count, and browser-extension connectivity. This is clearly separable from siblings like hide_session, unlock_vault, or list_hidden, which mutate or enumerate sessions rather than report AppLock state.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies a status-check use case (e.g., before locking/unlocking) but never says when to call it versus alternatives such as list_hidden or unlock_vault, nor any prerequisites. Usage is inferable from the intent but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hide_browser_chatLock a ChatGPT / Claude / Gemini web chatA
Tells the AppLock browser extension to lock a web chat: it disappears from the sidebar and shows a lock screen if opened, until unlocked with Touch ID or the password. Use chat_id "current" for the chat open in the browser.
| Name | Required | Description | Default |
|---|---|---|---|
| site | No | Needed only when chat_id isn't "current" and is ambiguous | |
| chat_id | Yes | Chat id from list_browser_chats, or "current" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses the post-condition (chat is removed from the sidebar), what a user sees on access (lock screen), and the reversal path (Touch ID or password). It stops short of stating whether hiding itself requires authentication, whether it is idempotent, or any error behavior when the chat_id is unknown.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with no filler; the effect of the operation is front-loaded before the parameter hint. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter tool with no annotations and no output schema, the description covers what happens and how to reverse it, which is what an agent mainly needs. It lacks prerequisite/auth context and any pointer to the unlock/restore siblings, leaving a small but real gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented, including the 'current' sentinel and the ambiguity rule for 'site'. The description restates the 'current' usage but adds no new format, conflict, or edge-case semantics beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource (lock a web chat) plus the mechanism ('tells the AppLock browser extension') and the visible effect (disappears from sidebar, lock screen). It is clear what the tool does, though it never explicitly contrasts with the similarly-named sibling hide_session, so sibling differentiation is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives one concrete invocation hint — use chat_id "current" for the open chat — which is actionable. However, it never says when to prefer this over hide_session, nor any prerequisites (e.g., vault/password configured, chat must exist in list_browser_chats) or when-not conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hide_sessionHide a chat sessionA
Encrypts a Claude Code or Antigravity session into the vault and removes it from the app's history. Works while locked. Use id "current" for the Claude Code session you are running in; it is hidden as soon as that session ends.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Session id from list_sessions (a unique prefix of 6+ characters works), or "current" |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide idempotentHint=false and destructiveHint=false; the description adds substantial context by explaining the session is encrypted into the vault, removed from history, and functions while locked. The deferred hide of 'current' until the session ends is a non-obvious behavioral trait that is well disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences with the core operation front-loaded, followed by the locked-state capability and the 'current' special case. Every sentence carries distinct information with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the single required parameter, full schema coverage, and absence of an output schema, the description covers the operation, the special id value, and the timing edge case. It does not mention restorability, but that is handled by a sibling tool, leaving the definition essentially complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents the id format, so the baseline is 3. The description adds meaning by clarifying that id='current' targets the running session and describing the deferred hiding behavior, going modestly beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Encrypts a ... session into the vault and removes it from the app's history'), which distinguishes it clearly from sibling hide_browser_chat and the list/restore tools. An agent immediately understands this is a session-level hide-and-encrypt operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context on when to pass id='current' and notes it works while locked, which is useful for invocation timing. It does not explicitly state when-not to use it or name restore_hidden as the inverse, so it falls short of full alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_browser_chatsList web chats seen by the extensionBRead-only
Lists ChatGPT, Claude.ai and Gemini chats visible in the sidebar of the user's browser, as reported by the AppLock extension. Also says which chat is open right now.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Filter by title text |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
readOnlyHint=true already tells the agent this is a safe read. The description adds genuine context beyond the annotation: the data originates from the AppLock extension's view of the browser sidebar, and the result includes the currently-open chat. No contradiction, but nothing about freshness, sync timing, or what happens when the extension is absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with what is listed and where it comes from. The final clause about the open chat earns its place by disclosing an extra payload field, though phrasing is slightly casual.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
A simple read-only, zero-required-param tool with full schema coverage and no output schema. The description adequately conveys the data source and the notable extra field (currently open chat), so an agent can call it correctly; only the filtering behavior is left implicit.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and there is a single optional 'query' param documented as 'Filter by title text'. The description never mentions filtering, so it adds no meaning beyond the schema; the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (lists) and resource (browser chats) and names the concrete sources: ChatGPT, Claude.ai and Gemini sidebars as reported by the AppLock extension. It also distinguishes the payload by noting it includes which chat is currently open. It stops short of explicitly contrasting with nearby siblings like list_sessions or list_hidden, but the resource is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites, and no mention of when to prefer list_sessions, list_hidden, or hide_browser_chat instead. The agent must infer usage purely from the resource description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sessionsList visible chat sessionsARead-only
Lists local Claude Code and Antigravity chat sessions that are currently visible (not hidden), newest first, so you can find the one to hide.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | No | Only sessions whose title contains this text (case-insensitive) | |
| source | No | Which app's sessions to list | all |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the safety profile is covered. The description adds behavioral detail beyond the annotations: the result ordering (newest first) and the visibility filter that excludes hidden sessions. It still omits return shape/pagination behavior, but for a simple read-only list this is a modest gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the resource and scope, then the ordering, then the reason to call it. No redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and only three simple optional parameters, the description covers what an agent needs to select and call the tool. Minor omissions (how many results return by default / pagination behavior) prevent a 5.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 67%, with the query and source params documented in the schema and limit left undocumented there. The description adds no parameter-level meaning (nothing about limit, query, or source semantics), so it neither compensates for the gap nor exceeds the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (lists chat sessions), scopes it precisely (local Claude Code and Antigravity sessions that are currently visible, not hidden), and names the ordering (newest first). It implicitly distinguishes itself from the sibling list_hidden by specifying 'visible (not hidden)' and from hide_session by stating its goal ('find the one to hide').
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The trailing clause 'so you can find the one to hide' gives clear context for when the tool is used — as a discovery step before hide_session. It doesn't explicitly name siblings or state when-not to use it (e.g., use list_hidden for hidden sessions), so it falls short of full routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lock_vaultLock the vault nowAIdempotent
Forgets the vault key immediately and re-locks web chats in the browser extension.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations covering safety (readOnlyHint=false, idempotentHint=true, destructiveHint=false), the description still adds real value: it discloses that the key is 'forgotten immediately' and that web chats in the browser extension are re-locked, i.e., the session state the caller loses. It does not mention re-unlock requirements or rate limits, but coverage is solid.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with zero filler; the consequence (key forgotten) is front-loaded ahead of the secondary effect (re-locking chats). Nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, no-output-schema tool with annotations already declaring the safety profile, the description supplies the missing behavioral context of what state is lost. Only the absence of any when-to-use steering keeps it from being fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the baseline there is nothing for the description to disambiguate; schema coverage is 100% and the empty object schema is self-explanatory. No meaningful gap exists here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action (lock the vault) plus its concrete effects: the vault key is forgotten and browser-extension web chats are re-locked. An agent can distinguish this from unlock_vault by the word 're-locks', though no sibling is named outright.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains what happens but never says when to call this versus alternatives like hide_session, applock_status, or unlock_vault. The only usage signal is the tautological title 'Lock the vault now', which offers no conditional guidance or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
unlock_vaultUnlock the vaultARead-only
Unlocks hidden chats for a few minutes. Shows the Touch ID prompt on the user's Mac, or opens a local passphrase page in their browser. The user authenticates on their own device; never ask for the passphrase in chat. Waits up to 2 minutes.
| Name | Required | Description | Default |
|---|---|---|---|
| method | No | auto uses Touch ID when enabled, otherwise the passphrase page | auto |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true, so the description carries the real behavioral burden and does so well: it discloses where the auth prompt appears (Mac Touch ID prompt or local browser page), that the unlock is temporary, that the agent should never request the passphrase, and the 2-minute wait window. This is exactly the extra context annotations cannot provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the core action, followed by the authentication mechanism and the waiting constraint. No filler; every sentence carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description adequately covers the action, the auth flow, the security constraint, and the timeout. It does not say what the agent should do if authentication fails or times out, a minor gap for a single-optional-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single 'method' parameter already documents its enum and the meaning of 'auto'. The description alludes to Touch ID and passphrase flows but adds no syntax or selection guidance beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Unlocks hidden chats') plus a temporal scope ('for a few minutes'), which cleanly separates it from siblings like lock_vault, list_hidden, and applock_status. An agent can identify the operation without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear procedural context: the user authenticates on their own device and the agent must never ask for the passphrase in chat. It does not explicitly state when to prefer this over checking applock_status first or how it relates to lock_vault, so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
10 tool updates
v0.2.0- First observed
applock_status - First observed
hide_browser_chat - First observed
hide_session - First observed
list_browser_chats - First observed
list_hidden - First observed
list_sessions - First observed
lock_vault - First observed
read_hidden - First observed
restore_hidden - First observed
unlock_vault
TDQS
Scored across 10 tools
Each tool has a clearly distinct target and action: local sessions (hide_session, list_sessions), browser chats (hide_browser_chat, list_browser_chats), and vault contents (list_hidden, read_hidden, restore_hidden). The list/unlock/lock/status tools are also unambiguous, so an agent can easily select the right operation.
Names are consistently snake_case and mostly follow a verb_noun pattern (hide_session, list_browser_chats, unlock_vault). The only deviation is applock_status, which is noun_status rather than verb_noun, but it remains readable and predictable.
The 10 tools sit comfortably in the ideal 3–15 range for a focused privacy/locking utility. Each tool corresponds to a distinct operation, and there is no obvious redundancy or missing essential operation.
The set covers the full hide/list/read/restore/unlock/lock lifecycle for local sessions and browser chats, plus status reporting. Minor gaps exist: no permanent delete from vault, no search/filter for hidden items, and read_hidden appears limited to local sessions, but core workflows are covered.
Maintenance
Related MCP Connectors
Private persistent memory for Claude, ChatGPT & Gemini via MCP - semantic search, zero-code setup.
MCP-native notes and memory for ChatGPT, Claude, and other AI tools.
- mcpOAuthai.butlerbrain
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Related MCP Servers
- AlicenseAqualityDmaintenanceSecrets vault for Claude Code. Encrypt API keys, tokens and passwords with AES-256. Full audit logs, MCP access rules, and zero-knowledge mode. Secrets never appear in chat.1733 npm1MIT
- AlicenseAqualityDmaintenanceLocal MCP server for macOS that scans AI coding tool history (Claude Code, Cursor, Copilot, Cline, Codex, Gemini CLI) for leaked secrets. Finds API keys in chat transcripts, redacts with sieve:// placeholders, and runs commands with Keychain-injected secrets - no plaintext values ever returned.91MIT
- AlicenseAqualityDmaintenanceEncrypted token store for Claude Code sessions, providing MCP tools for secure secret management with macOS Keychain integration, per-project allowlists, and native dialog input.64 npm6Cryptographic Autonomy 1.0 (Combined Work Exception)
- AlicenseNot gradedqualityCmaintenanceGives ChatGPT Web hands on your Mac — files, git, terminal, browser, and windows via MCP, with outbound-only tunnel and delete protection.1MIT