Sort, search and tidy your Google Photos from chat: find photos and videos, read their details, dow…
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Add library items to an existing album.
Album key from list_albums or create_album.
Library media keys (AF1Qip...) from list_media / search_media, as a JSON array or comma-separated.
The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess.
Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http mcp-google_photos https://nova.civai.co/mcp/agents/mcp-google_photos
Add library items to an existing album.
| Argument | Type | Description |
|---|---|---|
| album_key* | string | Album key from list_albums or create_album. |
| media_keys* | string | Library media keys (AF1Qip...) from list_media / search_media, as a JSON array or comma-separated. |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [
"google_account_email",
"album_key",
"media_keys"
],
"properties": {
"album_key": {
"type": "string",
"description": "Album key from list_albums or create_album."
},
"media_keys": {
"type": "string",
"description": "Library media keys (AF1Qip...) from list_media / search_media, as a JSON array or comma-separated."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}Archive items (they leave the main photo grid but stay in albums, search and Archive), or unarchive with archive=false.
| Argument | Type | Description |
|---|---|---|
| archive | string | true (default) or false to unarchive. |
| media_keys* | string | Library media keys (AF1Qip...) from list_media / search_media, as a JSON array or comma-separated. |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [
"google_account_email",
"media_keys"
],
"properties": {
"archive": {
"type": "string",
"description": "true (default) or false to unarchive."
},
"media_keys": {
"type": "string",
"description": "Library media keys (AF1Qip...) from list_media / search_media, as a JSON array or comma-separated."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}Check that the saved Google Photos session still works and list the signed-in accounts. Read-only: it never refreshes the session. If it reports the session expired, the user reconnects with start_browser_auth.
| Argument | Type | Description |
|---|---|---|
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [],
"properties": {
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}Create a new album with a title, optionally adding library items to it straight away.
| Argument | Type | Description |
|---|---|---|
| title* | string | Album title. |
| media_keys | string | Library media keys (AF1Qip...) from list_media / search_media, as a JSON array or comma-separated. |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [
"google_account_email",
"title"
],
"properties": {
"title": {
"type": "string",
"description": "Album title."
},
"media_keys": {
"type": "string",
"description": "Library media keys (AF1Qip...) from list_media / search_media, as a JSON array or comma-separated."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}Save the bytes of a thumbnail at any size or the original file to a local folder and return the path (plus sha256, and base64 for small files when asked). The image URLs need the signed-in cookies, so always fetch through this tool.
| Argument | Type | Description |
|---|---|---|
| size | string | original for the uploaded file (photo or video, byte-exact), or a size spec such as w512-h512, s1024, w2048-h2048-no for an image/thumbnail. Default w512-h512. |
| media_key* | string | One library media key. |
| output_dir | string | Local folder to save into. Default: <tmp>/google_photos_downloads. |
| return_base64 | string | true to also inline the bytes (files up to 1.5 MB). |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [
"google_account_email",
"media_key"
],
"properties": {
"size": {
"type": "string",
"description": "original for the uploaded file (photo or video, byte-exact), or a size spec such as w512-h512, s1024, w2048-h2048-no for an image/thumbnail. Default w512-h512."
},
"media_key": {
"type": "string",
"description": "One library media key."
},
"output_dir": {
"type": "string",
"description": "Local folder to save into. Default: <tmp>/google_photos_downloads."
},
"return_base64": {
"type": "string",
"description": "true to also inline the bytes (files up to 1.5 MB)."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}Full metadata for one item: filename, taken time and timezone offset, file size, dimensions, photo/video and duration, camera make/model/aperture/ISO/exposure when present, face count and named people, favorite flag, location (latitude/longitude from the file's GPS plus Google's place name; null when the item has none), plus thumbnail and original download URLs (those need the session: use download_media for bytes).
| Argument | Type | Description |
|---|---|---|
| media_key* | string | One library media key (AF1Qip...). |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [
"google_account_email",
"media_key"
],
"properties": {
"media_key": {
"type": "string",
"description": "One library media key (AF1Qip...)."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}Where this user's requests to the site leave from (a VPN country, the server, or the app's default) and which browser they present. Read-only.
No arguments.
{
"type": "object",
"required": [],
"properties": {}
}List the Google accounts signed in to the saved session with their /u/<N>/ slot. Call first and confirm with the user which email holds their photos.
| Argument | Type | Description |
|---|---|---|
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [],
"properties": {
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}List the user's albums (album_key, title, created), or pass album_key to list the items inside that album.
| Argument | Type | Description |
|---|---|---|
| album_key | string | Optional: list the items of this album. |
| page_token | string | next_page_token from the previous call. |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [
"google_account_email"
],
"properties": {
"album_key": {
"type": "string",
"description": "Optional: list the items of this album."
},
"page_token": {
"type": "string",
"description": "next_page_token from the previous call."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}Page through the Google Photos library timeline, newest first: media key, taken/uploaded time, dimensions, photo or video (+duration), favorite flag and a thumbnail URL. Optional date range (after/before) and type filter. Pass next_page_token to continue.
| Argument | Type | Description |
|---|---|---|
| after | string | Only items taken on/after this time: YYYY-MM-DD, ISO-8601 UTC, or epoch ms. |
| before | string | Only items taken on/before this time (a bare date includes the whole day). |
| page_size | string | Target number of items, 1-500 (default 100). Google pages in its own chunk sizes, so a call can return somewhat more; keep paging with next_page_token. |
| media_type | string | Filter by type. Default all. |
| page_token | string | next_page_token from the previous list_media call. |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
Remove items from an album. The photos stay in the library; only the album membership changes.
| Argument | Type | Description |
|---|---|---|
| album_key* | string | Album key. |
| media_keys | string | Library media keys (AF1Qip...) from list_media / search_media, as a JSON array or comma-separated. |
| album_item_keys | string | Optional: album-item keys from list_albums(album_key) instead of library media keys. |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [
"google_account_email",
"album_key"
],
"properties": {
"album_key": {
"type": "string",
"description": "Album key."
},
"media_keys": {
"type": "string",
"description": "Library media keys (AF1Qip...) from list_media / search_media, as a JSON array or comma-separated."
},
"album_item_keys": {
"type": "string",
"description": "Optional: album-item keys from list_albums(album_key) instead of library media keys."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}Search the library the way the Google Photos search box does: free text (sunset, food, beach), a person's name from People, a place, or a thing. Returns the same item shape as list_media.
| Argument | Type | Description |
|---|---|---|
| query* | string | Search text, e.g. sunset, food, a named person, a city. |
| page_size | string | Max results, 1-500. Default 100. |
| page_token | string | next_page_token from the previous call. |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [
"google_account_email",
"query"
],
"properties": {
"query": {
"type": "string",
"description": "Search text, e.g. sunset, food, a named person, a city."
},
"page_size": {
"type": "string",
"description": "Max results, 1-500. Default 100."
},
"page_token": {
"type": "string",
"description": "next_page_token from the previous call."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}Mark items as favorites (favorite=true, default) or remove the favorite (favorite=false).
| Argument | Type | Description |
|---|---|---|
| favorite | string | true (default) or false. |
| media_keys* | string | Library media keys (AF1Qip...) from list_media / search_media, as a JSON array or comma-separated. |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [
"google_account_email",
"media_keys"
],
"properties": {
"favorite": {
"type": "string",
"description": "true (default) or false."
},
"media_keys": {
"type": "string",
"description": "Library media keys (AF1Qip...) from list_media / search_media, as a JSON array or comma-separated."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}Choose where this user's requests to the site leave from and which browser they present, only when the user asks (e.g. 'connect through Nigeria', 'use my own user agent'). Sites may ask the user to sign in again when this changes. reset=true goes back to how they signed in.
| Argument | Type | Description |
|---|---|---|
| reset | boolean | Clear the choice: back to how the user signed in. |
| route | string | app: the app's default; direct: the server; fixed: the always-on VPN exit; vpn_country: a VPN exit in `country`. |
| locale | string | e.g. en-NG |
| country | string | ISO country code for vpn_country, e.g. NG, GB, US. |
| timezone | string | IANA time zone, e.g. Africa/Lagos. |
| user_agent | string | The browser user agent to present. |
| impersonate | string | Connection fingerprint target (e.g. chrome145); derived from the user agent when left out. |
| accept_language | string | e.g. en-NG,en;q=0.9 |
{
"type": "object",
"required": [],
"properties": {
"reset": {
"type": "boolean",
"description": "Clear the choice: back to how the user signed in."
},
"route": {
"enum": [
"app",
"direct",
"fixed",
"vpn_country"
],
"type": "string",
"description": "app: the app's default; direct: the server; fixed: the always-on VPN exit; vpn_country: a VPN exit in `country`."
},
"locale": {
"type": "string",
"description": "e.g. en-NG"
},
"country": {
"type": "string",
"description": "ISO country code for vpn_country, e.g. NG, GB, US."
},
"timezone": {
"type": "string",
"description": "IANA time zone, e.g. Africa/Lagos."
},
"user_agent": {
"type": "string",
"description": "The browser user agent to present."
},
"impersonate": {
"type": "string",
"description": "Connection fingerprint target (e.g. chrome145); derived from the user agent when left out."
},
"accept_language": {
"type": "string",
"description": "e.g. en-NG,en;q=0.9"
}
}
}Open Google Photos sign-in only when needed. If the saved session is still valid, this tool returns success immediately and does not open the viewer. Call session_status first. Use force_reconnect only when the user explicitly wants to wipe the saved cookie and sign in again (destructive).
| Argument | Type | Description |
|---|---|---|
| force_reconnect | boolean | DESTRUCTIVE: delete the saved session cookie for this tenant, then open the viewer for a fresh sign-in. Do not set true unless the user explicitly asks to sign out / reconnect / clear session. |
{
"type": "object",
"required": [],
"properties": {
"force_reconnect": {
"type": "boolean",
"description": "DESTRUCTIVE: delete the saved session cookie for this tenant, then open the viewer for a fresh sign-in. Do not set true unless the user explicitly asks to sign out / reconnect / clear session."
}
}
}Move items to Google Photos' Trash, where they stay recoverable for 60 days. Never deletes permanently and cannot empty the Trash. Requires confirm=true; max 50 items per call. Show the user the exact items and get their yes first.
| Argument | Type | Description |
|---|---|---|
| confirm* | string | Must be true, after the user approved the exact items. |
| media_keys* | string | Up to 50 library media keys to move to Trash, JSON array or comma-separated. |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [
"google_account_email",
"media_keys",
"confirm"
],
"properties": {
"confirm": {
"type": "string",
"description": "Must be true, after the user approved the exact items."
},
"media_keys": {
"type": "string",
"description": "Up to 50 library media keys to move to Trash, JSON array or comma-separated."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}Upload a local photo or video file (up to 10 GB) into the library, optionally into an album. Sent in resumable chunks, so a dropped connection resumes instead of restarting. Returns the new item. Uploading a file that is already in the library returns the existing item.
| Argument | Type | Description |
|---|---|---|
| chunk_mb | string | Chunk size in MB, 1-256. Default 8. |
| album_key | string | Optional album to add the upload to. |
| file_name | string | Optional name to store it under (default: the file's own name). |
| file_path* | string | Absolute path of a local image or video file. |
| google_account_email* | string | The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess. |
| notification_message | string | Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names. |
{
"type": "object",
"required": [
"google_account_email",
"file_path"
],
"properties": {
"chunk_mb": {
"type": "string",
"description": "Chunk size in MB, 1-256. Default 8."
},
"album_key": {
"type": "string",
"description": "Optional album to add the upload to."
},
"file_name": {
"type": "string",
"description": "Optional name to store it under (default: the file's own name)."
},
"file_path": {
"type": "string",
"description": "Absolute path of a local image or video file."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 14, 2026.
No readOnlyHint / destructiveHint annotations, so clients can't tell a read from a write without asking.
Fix: Add annotations to each tool, e.g. { readOnlyHint: true } for tools that only read.
{
"type": "object",
"required": [
"google_account_email"
],
"properties": {
"after": {
"type": "string",
"description": "Only items taken on/after this time: YYYY-MM-DD, ISO-8601 UTC, or epoch ms."
},
"before": {
"type": "string",
"description": "Only items taken on/before this time (a bare date includes the whole day)."
},
"page_size": {
"type": "string",
"description": "Target number of items, 1-500 (default 100). Google pages in its own chunk sizes, so a call can return somewhat more; keep paging with next_page_token."
},
"media_type": {
"enum": [
"all",
"photo",
"video"
],
"type": "string",
"description": "Filter by type. Default all."
},
"page_token": {
"type": "string",
"description": "next_page_token from the previous list_media call."
},
"google_account_email": {
"type": "string",
"description": "The signed-in Google account email whose Google Photos library to use (e.g. the one at /u/1/). Call list_accounts first and confirm with the user; do not guess."
},
"notification_message": {
"type": "string",
"description": "Short user-facing sentence for this action if the follow-up reply fails. Plain text only; do not mention template syntax or variable names."
}
}
}