{"name":"Wave","description":"Wave is an AI note taker. Two MCP servers: a public one exposing Wave's developer documentation with no authentication, and an authenticated one giving a user's agent read access to their meetings, calls, lectures, transcripts, summaries, and action items, plus a narrow write surface for action items and folders.","documentation":"https://wave.co/developers","servers":[{"name":"wave-docs","title":"Wave Documentation","description":"Wave's public developer documentation over MCP: the developer portal, versioning policy, OpenAPI specification, product overview, and contact pages as resources, plus read-only search and fetch tools. No account or token required; every resource URI is also a plain HTTPS URL.","url":"https://wave.co/mcp","transport":"streamable-http","protocolVersions":["2025-11-25","2025-06-18"],"documentation":"https://wave.co/developers","authentication":{"required":false},"tools":[{"name":"search_docs","description":"Search Wave's public developer documentation: the developer portal, OpenAPI specification, versioning policy, product overview, and contact pages. Returns matching sections with the URI to read each one in full.","access":"read","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"What to look for, in plain words."},"limit":{"type":"number","default":5,"maximum":25,"description":"Maximum sections to return."}},"required":["query"]}},{"name":"read_doc","description":"Read one public Wave document in full, by the `uri` (or short slug) returned by search_docs or resources/list. Every URI also resolves as a plain HTTPS URL.","access":"read","inputSchema":{"type":"object","properties":{"uri":{"type":"string","description":"Document URI, e.g. https://wave.co/developers.md, or its slug, e.g. wave-developer-portal."}},"required":["uri"]}}],"resources":[{"uri":"https://wave.co/developers.md","name":"wave-developer-portal","title":"Wave Developer Portal","description":"Quickstart, authentication and scopes, OpenAPI specification, MCP server, CLI, rate limits, versioning and deprecation policy, and the full developer resource index.","mimeType":"text/markdown"},{"uri":"https://wave.co/openapi.json","name":"wave-openapi-specification","title":"Wave API OpenAPI 3.1 Specification","description":"Machine-readable description of every Wave Developer API endpoint: unique operationId, typed parameters, response schemas, and the token scopes each operation requires. Loadable directly into an LLM function-calling toolchain.","mimeType":"application/json"},{"uri":"https://wave.co/agents.md","name":"wave-for-agents","title":"Wave for Agents — API, CLI, and MCP","description":"The three programmatic surfaces over Wave session data, the tools an agent can call, and the boundary of what it cannot do.","mimeType":"text/markdown"},{"uri":"https://wave.co/integrations/claude.md","name":"wave-for-claude","title":"Wave for Claude","description":"Connecting Wave to Claude via the connector directory listing (Wave AI Note Taker): what Claude can do with your sessions, setup steps, scope boundaries, and the manual mcp.wave.co path.","mimeType":"text/markdown"},{"uri":"https://wave.co/integrations/chatgpt.md","name":"wave-for-chatgpt","title":"Wave for ChatGPT","description":"Installing Wave AI Note Taker from the ChatGPT app directory: how ChatGPT searches your meetings in chats, company knowledge, and Deep Research, plus setup steps and scope boundaries.","mimeType":"text/markdown"},{"uri":"https://wave.co/integrations/claude-code.md","name":"wave-for-claude-code","title":"Wave for Claude Code","description":"Connecting Wave to Claude Code with claude mcp add + claude mcp login: pulling transcripts, decisions, and action items into a coding session, and the scope boundary.","mimeType":"text/markdown"},{"uri":"https://wave.co/integrations/codex.md","name":"wave-for-codex","title":"Wave for Codex","description":"Connecting Wave to OpenAI Codex (CLI, ChatGPT desktop app, IDE extension) with codex mcp add + codex mcp login, what Codex can read and write, and the scope boundary.","mimeType":"text/markdown"},{"uri":"https://wave.co/integrations/cursor.md","name":"wave-for-cursor","title":"Wave for Cursor","description":"Adding Wave to Cursor with the one-click install link or mcp.json, signing in, what Cursor's agent can read and write, and the scope boundary.","mimeType":"text/markdown"},{"uri":"https://wave.co/integrations/grok.md","name":"wave-for-grok","title":"Wave for Grok","description":"Adding Wave as a custom connector in the Grok app (grok.com/connectors) or Grok Build, what Grok can read and write, and the scope boundary.","mimeType":"text/markdown"},{"uri":"https://wave.co/integrations/muse.md","name":"wave-for-muse","title":"Wave for Muse","description":"Connecting Wave to Muse, Meta's personal AI, via its custom-connector chat flow while the directory listing is under review, what Muse can read and write, and the scope boundary.","mimeType":"text/markdown"},{"uri":"https://wave.co/developers/versioning.md","name":"wave-api-versioning-policy","title":"Wave API Versioning and Deprecation Policy","description":"How the Wave API is versioned, what counts as a breaking change, and the Deprecation, Sunset, and Link headers a retiring endpoint carries.","mimeType":"text/markdown"},{"uri":"https://wave.co/index.md","name":"wave-overview","title":"Wave — Product Overview","description":"What Wave is, how recording and transcription work, which platforms it runs on, what it costs, and the full FAQ. The homepage as Markdown.","mimeType":"text/markdown"},{"uri":"https://wave.co/llms.txt","name":"wave-llms-txt","title":"Wave Site Overview for LLMs (llms.txt)","description":"The whole site condensed for language models: product, positioning, pricing, platform coverage, competitive context, and the index of machine-readable endpoints.","mimeType":"text/plain"},{"uri":"https://wave.co/contact.md","name":"wave-contact","title":"Contact Wave","description":"Support, sales, partnerships, privacy, security, and legal contact channels, plus company details for Wave AI, Inc.","mimeType":"text/markdown"}],"limitations":["Serves only public documentation; no user data exists on this server","All tools are read-only and closed-world (openWorldHint: false)"]},{"name":"wave","title":"Wave MCP Server","description":"Search and read the authenticated Wave user's sessions, transcripts, summaries, and action items.","url":"https://mcp.wave.co","transport":"streamable-http","protocolVersions":["2025-11-25","2025-06-18","2025-03-26"],"documentation":"https://api.wave.co/mcp","authentication":{"required":true,"schemes":["oauth2","bearer"],"oauth2":{"flow":"authorization_code","pkce":true,"authorizationServerMetadata":"https://mcp.wave.co/.well-known/oauth-authorization-server","protectedResourceMetadata":"https://mcp.wave.co/.well-known/oauth-protected-resource"},"bearer":{"description":"Manually minted wave_mcp_ token, for clients that cannot run OAuth.","tokenManagement":"https://app.wave.co/settings/integrations/mcp"}},"tools":[{"name":"search_sessions","description":"Search across your Wave sessions using semantic search. Start here for cross-session questions, then fetch only the relevant session details. Returns sessions that match the query based on meaning, not just keywords. Pass `person` to keep only sessions a given person speaks in (e.g. \"what did Sarah say about pricing\"). Sessions of type \"phone\" include a `phone` object (direction inbound/outbound, to_number, from_number, status, ongoing).","access":"read","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"The search query. Can be natural language."},"limit":{"type":"number","description":"Maximum number of results (default: 10, max: 50). Start with 10–20 for synthesis."},"folder":{"type":"string","description":"Restrict results to sessions in a folder (id or case-insensitive name). Use list_folders to discover available folders."},"tag":{"type":["string","array"],"description":"Restrict search to sessions with this tag (exact, case-sensitive). Pass a string or array of strings.","items":{"type":"string"}},"tag_mode":{"type":"string","enum":["any","all"],"description":"With multiple tags: \"any\" (default) = at least one match, \"all\" = session must have every tag."},"person":{"type":"string","description":"Only sessions this person speaks in, by Voice ID: a name (case-insensitive; a unique prefix such as a first name works) or an id from list_people. \"me\" means the user's own voice. An ambiguous name returns an error listing the candidates: ask the user which one. A name with no saved Voice ID does not fail: the results fall back to sessions whose speaker labels, title or transcript use the name, and `person_match` (voice_id_matched false, similar saved names in candidates) marks them as name matches, not voice matches."}},"required":["query"]}},{"name":"list_sessions","description":"List your recent Wave sessions. Returns session summaries with metadata. For synthesis, start with 10–20 and paginate; use 100 only for an explicitly exhaustive request. Pass `person` (plus `since`) to list the sessions a given person speaks in, e.g. \"what meetings was Sarah in this month\". Sessions of type \"phone\" include a `phone` object (direction inbound/outbound, to_number, from_number, status, ongoing — for inbound bridge calls the other party is unknown so from_number is null).","access":"read","inputSchema":{"type":"object","properties":{"limit":{"type":"number","description":"Number of sessions to return (default: 20, max: 100). Use 10–20 for an overview; use 100 only when explicitly exhaustive."},"type":{"type":"string","description":"Filter by session type","enum":["meeting","recording","youtube","phone","podcast","desktop","import"]},"since":{"type":"string","description":"Only sessions after this date (ISO 8601)"},"cursor":{"type":"string","description":"Pagination cursor from previous request"},"folder":{"type":"string","description":"Restrict results to sessions in a folder (id or case-insensitive name). Use list_folders to discover available folders."},"tag":{"type":["string","array"],"description":"Filter by tag (exact, case-sensitive). Pass a string or array of strings.","items":{"type":"string"}},"tag_mode":{"type":"string","enum":["any","all"],"description":"With multiple tags: \"any\" (default) = at least one match, \"all\" = session must have every tag."},"person":{"type":"string","description":"Only sessions this person speaks in, by Voice ID: a name (case-insensitive; a unique prefix such as a first name works) or an id from list_people. \"me\" means the user's own voice. An ambiguous name returns an error listing the candidates: ask the user which one. A name with no saved Voice ID does not fail: the results fall back to sessions whose speaker labels, title or transcript use the name, and `person_match` (voice_id_matched false, similar saved names in candidates) marks them as name matches, not voice matches."}}}},{"name":"list_folders","description":"List the user's folders. Users organize sessions into folders in the Wave app. Use this to discover folder ids/names, then pass `folder` to list_sessions or search_sessions to scope results (useful for work/personal separation on a single account). Each folder also carries `pinned`, `sort_order` (sort for the sessions inside it), `order` (manual position) and `last_opened_at` when set; absence means not pinned / newest first / no manual position / never opened. Folders are returned in display order: pinned first, then by `order` ascending (folders with an order before those without), then by name.","access":"read","inputSchema":{"type":"object","properties":{}}},{"name":"get_session","description":"Get full details for a specific Wave session, including the summary and optionally the transcript. Sessions of type \"phone\" include a `phone` object (direction inbound/outbound, to_number, from_number, status, ongoing). For a session shared with the user, pass its owner_id too; the result adds owner_id, owner_name, access \"shared\" and the share scope, and omits anything the owner did not share.","access":"read","inputSchema":{"type":"object","properties":{"session_id":{"type":"string","description":"The ID of the session to retrieve"},"include_transcript":{"type":"boolean","description":"Whether to include the full transcript (default: false)"},"owner_id":{"type":"string","description":"Only for a session someone else shared with the user: the owner_id from list_shared_sessions. Omit for the user's own sessions."}},"required":["session_id"]}},{"name":"get_transcript","description":"Get the transcript for a Wave session with speaker attribution. For a session shared with the user, pass its owner_id too.","access":"read","inputSchema":{"type":"object","properties":{"session_id":{"type":"string","description":"The ID of the session"},"format":{"type":"string","description":"Transcript format","enum":["segments","plain","speaker_labeled"]},"owner_id":{"type":"string","description":"Only for a session someone else shared with the user: the owner_id from list_shared_sessions. Omit for the user's own sessions."}},"required":["session_id"]}},{"name":"get_action_items","description":"Read the structured action items attached to a Wave session, plus the current version. Returned items have provenance: source=\"agent\" means the item was written by an AI, source=\"user\" means the user wrote or edited it. Pair with update_action_items using `expected_version` for safe round-trip edits. For a session shared with the user, pass its owner_id too; shared action items are read-only (read_only: true) and carry no provenance or version.","access":"read","inputSchema":{"type":"object","properties":{"session_id":{"type":"string","description":"The ID of the session"},"owner_id":{"type":"string","description":"Only for a session someone else shared with the user: the owner_id from list_shared_sessions. Omit for the user's own sessions."}},"required":["session_id"]}},{"name":"update_action_items","description":"Write back the structured action items for a Wave session. The array fully replaces the current list — preserve items by keeping their `id`. Items you add without an `id` get one assigned. Pass `expected_version` (from a prior get_action_items call) to reject the write if the user edited in between. Defaults `source` to \"agent\" for new items you add.","access":"write","inputSchema":{"type":"object","properties":{"session_id":{"type":"string","description":"The ID of the session"},"action_items":{"type":"array","description":"Full replacement list of action items (max 200).","items":{"type":"object","properties":{"id":{"type":"string","description":"Stable id. Preserve from get_action_items to keep an existing item. Omit for new items."},"text":{"type":"string","description":"Action item text (≤ 2000 chars)."},"completed":{"type":"boolean","description":"Whether the item is done. Default false."},"source":{"type":"string","enum":["agent","user"],"description":"Who wrote this item. Defaults to \"agent\" for new items written by the MCP client."},"assignee":{"type":"string","description":"Optional assignee name."},"due_date":{"type":"string","description":"Due date. ISO YYYY-MM-DD preferred; natural language such as \"Friday\", \"next Tuesday\" or \"April 25\" is accepted and normalized to ISO relative to today."}},"required":["text"]}},"expected_version":{"type":"number","description":"Optional: current action_items version from get_action_items. If another writer has bumped the version in the meantime, the update is rejected."}},"required":["session_id","action_items"]}},{"name":"create_folder","description":"Create a folder for organizing sessions. Folders are non-exclusive (a session can be in many folders). If a folder with the same case-insensitive name already exists, returns it instead of erroring — safe to retry.","access":"write","inputSchema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"pattern":"\\S","description":"Folder name (trimmed, 1–100 chars, not blank)."},"color":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$","description":"Optional hex color in #RRGGBB form, e.g. \"#6D28D9\"."}},"required":["name"]}},{"name":"add_session_to_folder","description":"Add a session to a folder. Non-exclusive: a session can belong to many folders simultaneously. Idempotent — calling this for a session already in the folder is a no-op.","access":"write","inputSchema":{"type":"object","properties":{"session_id":{"type":"string","description":"The ID of the session"},"folder_id":{"type":"string","description":"The folder ID (use list_folders to discover)."}},"required":["session_id","folder_id"]}},{"name":"remove_session_from_folder","description":"Remove a session from a folder. The session itself is not deleted; only the folder link is removed.","access":"write","inputSchema":{"type":"object","properties":{"session_id":{"type":"string","description":"The ID of the session"},"folder_id":{"type":"string","description":"The folder ID"}},"required":["session_id","folder_id"]}},{"name":"update_folder","description":"Rename, recolour, pin, reorder, or change the session sort of a folder. Pass any of `name` (trimmed, 1–100 chars), `color` (hex \"#RRGGBB\", or null to clear it), `pinned` (boolean; pinned folders sort first everywhere), `sort_order` (\"newest\" | \"oldest\" | \"title\" — the remembered sort for the sessions inside the folder), or `order` (integer from 0 to 2^53 - 1; manual position, folders with an order sort ascending before those without) — at least one is required; anything omitted is left unchanged. Membership is not touched: use add_session_to_folder / remove_session_from_folder for that. Use list_folders to find the folder_id.","access":"write","inputSchema":{"type":"object","properties":{"folder_id":{"type":"string","description":"The folder ID (use list_folders to discover)."},"name":{"type":"string","minLength":1,"maxLength":100,"pattern":"\\S","description":"New folder name (trimmed, 1–100 chars, not blank)."},"color":{"type":["string","null"],"pattern":"^#[0-9a-fA-F]{6}$","description":"New hex color in #RRGGBB form, e.g. \"#4D5EF6\". Pass null to remove the color."},"pinned":{"type":"boolean","description":"true to pin the folder (pinned folders sort first everywhere), false to unpin."},"sort_order":{"type":"string","enum":["newest","oldest","title"],"description":"Remembered sort for the sessions inside this folder. \"newest\" is the default when unset."},"order":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Manual position (integer from 0 to 2^53 - 1). Folders with an order sort ascending before folders without one."}},"required":["folder_id"],"anyOf":[{"required":["name"]},{"required":["color"]},{"required":["pinned"]},{"required":["sort_order"]},{"required":["order"]}]}},{"name":"delete_folder","description":"Delete a folder. Only the folder itself is removed — the sessions in it are never deleted and stay in any other folders they belong to. This cannot be undone, so confirm with the user before deleting a folder they did not explicitly ask to remove. Use list_folders to find the folder_id.","access":"write","inputSchema":{"type":"object","properties":{"folder_id":{"type":"string","description":"The folder ID (use list_folders to discover)."}},"required":["folder_id"]}},{"name":"search","description":"Search the user's Wave sessions (meetings, calls, recordings) by meaning. Returns matching sessions as citable results with id, title, and url. This is the deep-research search interface; in interactive chats prefer search_sessions, which returns richer structured data.","access":"read","inputSchema":{"type":"object","properties":{"query":{"type":"string","description":"Search query. Can be natural language."}},"required":["query"]}},{"name":"fetch","description":"Fetch the full content of a Wave session by id: summary plus speaker-labeled transcript, with metadata. Use ids returned by `search`, or a `fetch_id` (\"shared:{owner_id}:{session_id}\") from list_shared_sessions for a session someone shared with the user. This is the deep-research fetch interface; in interactive chats prefer get_session / get_transcript.","access":"read","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"Session id from a `search` result, or a `fetch_id` from list_shared_sessions."}},"required":["id"]}},{"name":"list_shared_sessions","description":"List sessions other Wave users have shared with the user, newest share first. Each row has session_id, owner_id, owner_name, title, shared_at, the share scope (which of summary / transcript / audio / action_items the owner shared) and a fetch_id. To read one, pass BOTH session_id and owner_id to get_session, get_transcript or get_action_items (or fetch_id to fetch). Shared sessions are read-only and are not covered by search_sessions or search.","access":"read","inputSchema":{"type":"object","properties":{"limit":{"type":"number","description":"Number of sessions to return (default: 20, max: 100)."},"cursor":{"type":"string","description":"Pagination cursor (next_cursor from a previous call)."}}}},{"name":"list_session_access","description":"For one of the user's own sessions, list the people who have access (recipient_id, name, email, shared_at, how they got it) and the emailed invites nobody has accepted yet. An existing share link cannot be read back; share_session without emails creates one.","access":"read","inputSchema":{"type":"object","properties":{"session_id":{"type":"string","description":"The ID of one of the user's own sessions."}},"required":["session_id"]}},{"name":"share_session","description":"Share one of the user's own sessions with other people. This grants them read access to the session, so confirm with the user before calling unless they clearly asked to share it. With `emails` (1–10 addresses, optional `message` up to 500 characters), Wave emails each person an invite and returns which addresses were sent and which were skipped (with a reason). Without `emails`, returns a share link (app.wave.co/i/…, valid 30 days) that anyone signed in to Wave can use to get access.","access":"write","inputSchema":{"type":"object","properties":{"session_id":{"type":"string","description":"The ID of one of the user's own sessions."},"emails":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":10,"description":"Email addresses to invite (1–10). Omit to get a share link instead."},"message":{"type":"string","maxLength":500,"description":"Optional personal note included in the invite email (only with emails)."}},"required":["session_id"]}},{"name":"unshare_session","description":"Remove access to one of the user's own sessions. Pass exactly one of: `recipient_id` (from list_session_access) to remove that person; `email` to cancel a pending emailed invite; or `everyone: true` to remove every person and reset the share link, so the old link stops working (a new, unsent link is returned). Confirm with the user before removing access they did not explicitly ask to remove.","access":"write","inputSchema":{"type":"object","properties":{"session_id":{"type":"string","description":"The ID of one of the user's own sessions."},"recipient_id":{"type":"string","description":"Remove this person (recipient_id from list_session_access)."},"email":{"type":"string","description":"Cancel the pending emailed invite to this address."},"everyone":{"type":"boolean","description":"true removes everyone and resets the share link."}},"required":["session_id"],"anyOf":[{"required":["recipient_id"]},{"required":["email"]},{"required":["everyone"]}]}},{"name":"list_people","description":"List the people Wave recognises by voice (the user's Voice IDs): id, name, is_me (the user's own voice), recording_count and last_heard_at. Me first, then most recently heard. Use it to find who the user records with, or to get the exact name/id for get_person_sessions or the `person` filter on list_sessions / search_sessions. Only people the user has named and saved in Wave appear; other speakers in a recording are not listed. counts_partial true means the counts only cover the newest 1,000 recordings.","access":"read","inputSchema":{"type":"object","properties":{}}},{"name":"get_person_sessions","description":"List the recordings one person (Voice ID) speaks in, newest first: session_id, title, timestamp, type, duration_seconds, talk_seconds (how long they spoke), name_in_session (the speaker label they appear under) and matched_by — how Wave identified them: \"voice_match\" (automatic voice recognition, with similarity 0–1), \"user_confirmed\" (the user named or corrected the speaker), \"user_added\" (the user saved this recording to their voice), \"suggested\", or \"legacy\" (linked before this was tracked). Use for \"what meetings was Sarah in this month\" or \"how much did Sam talk last week\". No transcripts: use get_transcript or get_session for content. `person` is a name (case-insensitive exact, then unique prefix) or an id from list_people; an ambiguous name returns an error listing the candidates. If no saved Voice ID matches the name, the result has person null, voice_id_matched false, candidates (saved Voice IDs with similar names) and a `fallback` block: label_matches (recordings whose speaker labels or title use the name) and search_results (transcript and summary search for the name). Fallback results are name matches, not voice matches; say so to the user. Paginate with next_cursor.","access":"read","inputSchema":{"type":"object","properties":{"person":{"type":"string","description":"The person: a name (e.g. \"Sarah\", \"sarah kim\") or an id from list_people. \"me\" means the user's own voice."},"from":{"type":"string","description":"Only recordings on or after this date/time (ISO 8601, e.g. 2026-10-01)."},"to":{"type":"string","description":"Only recordings on or before this date/time (ISO 8601; a bare date includes that whole day)."},"type":{"type":"string","description":"Filter by session type","enum":["meeting","recording","youtube","phone","podcast","desktop","import"]},"limit":{"type":"number","description":"Number of recordings to return (default: 20, max: 50)."},"cursor":{"type":"string","description":"Pagination cursor (next_cursor from the previous call for the same person)."}},"required":["person"]}},{"name":"import_recording_from_url","description":"Import an audio or video file into Wave from a public https:// link (for example a podcast episode, a Dropbox or Google Drive direct-download link, or a file on the web). Wave downloads it, transcribes it and writes a summary, like an import in the Wave app. This uses the user's import allowance (imports are limited per hour and day, and free accounts have limited minutes), so confirm with the user before calling unless they clearly asked to import this file. Returns the new session id with status \"fetching\"; poll get_session until processing_status is \"completed\" (or \"failed\"). Supported: MP3, M4A, WAV, AAC, FLAC, OGG, OPUS, WebM, MP4, MOV, up to 2 GiB. Links that need a login or open a web page instead of the file will fail with source_unreachable.","access":"write","inputSchema":{"type":"object","properties":{"source_url":{"type":"string","description":"Public https:// URL of the audio or video file itself."},"title":{"type":"string","description":"Optional title (max 500 characters). Without one, Wave writes a title after transcribing."},"notes":{"type":"string","description":"Optional notes or context (max 50,000 characters). Wave uses them when writing the summary."},"tags":{"type":"array","items":{"type":"string"},"description":"Optional tags (max 20)."},"language":{"type":"string","description":"Optional spoken language code such as \"en\", \"es\" or \"pt_br\". Defaults to the user's language setting."},"recorded_at":{"type":"string","description":"Optional ISO 8601 time the recording was made. Defaults to now."},"idempotency_key":{"type":"string","description":"Optional key (1-200 visible ASCII characters). The same key replays the first import instead of making a second one. Without it, a call with the same source_url and metadata replays automatically, so a retry after a timeout is safe."}},"required":["source_url"]}},{"name":"create_recording_upload","description":"Start an import of a local audio or video file: returns a signed upload URL that the client must PUT the file bytes to. Only for clients that can run an HTTP PUT with a local file, such as Claude Code, Codex or a script (for example curl -X PUT with the returned headers and --upload-file). Chat apps that cannot upload files should not use this. Wave transcribes and summarizes the file once the upload finishes; nothing else needs to be called. Uses the user's import allowance, so confirm with the user first unless they asked. The URL lasts 15 minutes and is signed with the returned headers; send all of them exactly. Each call without idempotency_key starts a new import; to retry the same file (including after a timeout or error, which also returns an idempotency_key), pass back that idempotency_key. Files up to 5 GiB. Poll get_session for processing_status.","access":"write","inputSchema":{"type":"object","properties":{"content_type":{"type":"string","description":"MIME type of the file, e.g. \"audio/mpeg\", \"audio/mp4\", \"audio/wav\", \"video/mp4\"."},"filename":{"type":"string","description":"Optional file name; its extension helps pick the format."},"size_bytes":{"type":"integer","minimum":1,"maximum":5368709120,"description":"Optional file size in bytes (at most 5 GiB)."},"title":{"type":"string","description":"Optional title (max 500 characters). Without one, Wave writes a title after transcribing."},"notes":{"type":"string","description":"Optional notes or context (max 50,000 characters). Wave uses them when writing the summary."},"tags":{"type":"array","items":{"type":"string"},"description":"Optional tags (max 20)."},"language":{"type":"string","description":"Optional spoken language code such as \"en\", \"es\" or \"pt_br\". Defaults to the user's language setting."},"recorded_at":{"type":"string","description":"Optional ISO 8601 time the recording was made. Defaults to now."},"idempotency_key":{"type":"string","description":"Only to retry an upload: pass the idempotency_key returned by an earlier create_recording_upload call to get a fresh URL for the same session. Omit for a new file; every call without it starts a separate import."}},"required":["content_type"]}},{"name":"update_session","description":"Edit one of the user's own sessions: title, notes, summary (markdown), tags or favorite. Only the fields you pass change. tags replaces the whole tag list and summary replaces the whole summary, so read the session first with get_session and send the full new value. A new title is kept even if Wave reprocesses the recording. Cannot edit transcripts, audio or sessions shared with the user. Confirm with the user before replacing a summary they did not ask to change.","access":"write","inputSchema":{"type":"object","properties":{"session_id":{"type":"string","description":"The ID of the session."},"title":{"type":"string","description":"New title (max 500 characters)."},"notes":{"type":"string","description":"New notes (max 50,000 characters). Replaces the current notes."},"summary":{"type":"string","description":"New summary in markdown (max 200,000 characters). Replaces the current summary."},"tags":{"type":"array","items":{"type":"string"},"description":"Full new tag list (max 20). Pass [] to clear."},"favorite":{"type":"boolean","description":"Mark or unmark as favorite."}},"required":["session_id"]}}],"limitations":["Cannot delete sessions, recordings, or transcripts","Cannot edit recording media or transcript text","Reads the authenticated Wave user's own sessions plus sessions other people shared with them; shared sessions are read-only","Writes only to the user's own data; sharing a session gives the people named read access, never edit access","All tools are closed-world (openWorldHint: false)","Importing recordings (import_recording_from_url, create_recording_upload) needs the separate mcp:import permission, which the user approves on its own, and uses the account's import allowance"]}],"related":[{"name":"Wave Developer API","url":"https://api.wave.co","type":"openapi","specification":"https://wave.co/openapi.json"},{"name":"Wave CLI","url":"https://www.npmjs.com/package/@waveai/cli","type":"cli","install":"npm install -g @waveai/cli"}]}