diff --git a/README.md b/README.md index 8560152..4402ba7 100644 --- a/README.md +++ b/README.md @@ -511,10 +511,12 @@ sit unnoticed until it expires. That is a real limitation today, not a setting. `readonly` does not help here: it still takes screenshots. Close such a window first, or keep screenshots to one app with `app` - covering it with another window is not enough, because a capture can leave the covering window out. -- **Password managers are kept out of the picture itself.** The capture asks - macOS to leave every app on the deny list out of the image, so their pixels - never exist - hiding, moving or closing one mid-capture cannot leak it, and - one can never be photographed on its own. Redaction still runs on top. +- **Password managers are kept out of the picture itself.** In a redacted + screenshot - the default - the capture asks macOS to leave every app on the + deny list out of the image, so their pixels never exist: hiding, moving or + closing one mid-capture cannot leak it. Redaction still runs on top. An + unredacted screenshot, which only the person can allow, captures them like + any other window. What is left of the gap: a secure *field* in an ordinary app that moves while the scan runs is painted where it is now, not where it was. A field shows dots, so that reveals its length, not the password. Helper processes a diff --git a/mcp-server/README.md b/mcp-server/README.md index 2677537..fc94f53 100644 --- a/mcp-server/README.md +++ b/mcp-server/README.md @@ -509,10 +509,12 @@ sit unnoticed until it expires. That is a real limitation today, not a setting. `readonly` does not help here: it still takes screenshots. Close such a window first, or keep screenshots to one app with `app` - covering it with another window is not enough, because a capture can leave the covering window out. -- **Password managers are kept out of the picture itself.** The capture asks - macOS to leave every app on the deny list out of the image, so their pixels - never exist - hiding, moving or closing one mid-capture cannot leak it, and - one can never be photographed on its own. Redaction still runs on top. +- **Password managers are kept out of the picture itself.** In a redacted + screenshot - the default - the capture asks macOS to leave every app on the + deny list out of the image, so their pixels never exist: hiding, moving or + closing one mid-capture cannot leak it. Redaction still runs on top. An + unredacted screenshot, which only the person can allow, captures them like + any other window. What is left of the gap: a secure *field* in an ordinary app that moves while the scan runs is painted where it is now, not where it was. A field shows dots, so that reveals its length, not the password. Helper processes a diff --git a/mcp-server/index.js b/mcp-server/index.js index 39ad09b..b6dd28c 100644 --- a/mcp-server/index.js +++ b/mcp-server/index.js @@ -1158,7 +1158,7 @@ async function runTool(name, args) { url = `spotify:track:${id}`; } else if (intent === 'open_chat') { const phone = String(args.phone || '').replace(/[\s()-]/g, ''); - if (!/^\+?\d{4,15}$/.test(phone)) return errorResult('Refused: open_chat needs a phone number in international form, e.g. +4560174569. Nothing was done.'); + if (!/^\+?\d{4,15}$/.test(phone)) return errorResult('Refused: open_chat needs a phone number in international form - a plus sign, the country code and the number, digits only. Nothing was done.'); url = `whatsapp://send?phone=${encodeURIComponent(phone.replace(/^\+/, ''))}`; } else { return errorResult(`Refused: unknown intent '${intent}'. Use open_app, play_track or open_chat. Nothing was done.`); diff --git a/mcp-server/tools.js b/mcp-server/tools.js index e726959..deae660 100644 --- a/mcp-server/tools.js +++ b/mcp-server/tools.js @@ -58,7 +58,7 @@ export const TOOLS = [ description: 'open_app: bring an app up in the background (needs bundleId). play_track: start a Spotify track (needs spotifyId, 22 chars). open_chat: open a WhatsApp chat to a phone number with NO pre-filled text (needs phone).' }, bundleId: { type: 'string', description: 'For open_app: the app, e.g. com.spotify.client.' }, spotifyId: { type: 'string', description: 'For play_track: the 22-character Spotify track id.' }, - phone: { type: 'string', description: 'For open_chat: the phone number in international form, e.g. +4560174569.' } + phone: { type: 'string', description: 'For open_chat: the phone number in international form - a plus sign, the country code and the number, digits only. Use the number the user gave you; never make one up.' } } } },