Pro and Lifetime

Meetings for your AI agent

Ask Claude, Cursor, or any MCP client about your meetings: what a customer asked for, which action items you agreed to, what was said on Tuesday. Your agent searches and reads your ViewFraming summaries and transcripts directly, so you never paste or share them by hand.

Get started

  1. Turn on meeting syncIn the ViewFraming app, open Settings and turn on Sync meetings for AI agents. Meetings you finish from then on are uploaded, and you can upload the last 7 days.
  2. Create an API keySign in at viewframing.com/account#api-keys and create a key. Copy it right away: it is shown only once.
  3. Add ViewFraming to your agentPaste the key into your agent's settings, as shown below for each client.
Synced meetings are kept for 7 days Each meeting is deleted from ViewFraming's servers 7 days after it was first uploaded. Your agent can't read it after that, and uploading it again doesn't extend the date. Meetings on your device are not affected. Audio is never uploaded.

Connect your agent

ViewFraming is a remote MCP server. Every client needs the same two things:

Server URLhttps://api.viewframing.com/mcp
HeaderAuthorization: Bearer vf_key_…

Run once in a terminal, with your key in place of vf_key_YOUR_KEY:

claude mcp add --transport http viewframing https://api.viewframing.com/mcp \
  --header "Authorization: Bearer vf_key_YOUR_KEY"

Add --scope user to use it in every project. Check it with /mcp inside Claude Code.

claude.ai and ChatGPT Connectors added on the web sign in with OAuth, which ViewFraming doesn't support yet. Use one of the clients above, or any MCP client that can send a custom header.

Try it

Once connected, just ask:

Tools

The server has two read-only tools. Your agent picks them on its own; you only need these details to call them yourself.

list_meetings

Your meetings, newest first, with an optional full-text search.

ArgumentTypeDescription
querystringWords to match in titles, summaries and transcripts. Supports "quoted phrases", OR, and -excluded words. Up to 200 characters.
fromRFC 3339 timeOnly meetings that started at or after this time.
toRFC 3339 timeOnly meetings that started before this time.
limitinteger1 to 50. Default 20.
cursorstringThe next_cursor of the previous page.

Each item has id, title, mode, started_at, ended_at, expires_at, and summary, the first 500 characters of the meeting summary. With a query, each item also has a snippet with the matches in **bold**. next_cursor is null on the last page.

Result
{
  "meetings": [
    {
      "id": "6f1c2a9e-4b7d-4e15-9a3c-0d2f8b6e1a44",
      "title": "Pricing sync with Acme",
      "mode": "sales_calls",
      "started_at": "2026-10-27T15:00:00Z",
      "ended_at": "2026-10-27T15:32:00Z",
      "expires_at": "2026-11-03T15:40:12Z",
      "summary": "Acme wants a volume discount before renewing...",
      "snippet": "We need a **discount** on the enterprise plan before Friday"
    }
  ],
  "next_cursor": null
}

get_meeting

One meeting in full.

ArgumentTypeDescription
idstring, requiredA meeting id from list_meetings.
include_transcriptbooleanDefault true. Set false for the summary sections only.

The result has title, mode, started_at, ended_at, and sections. Each section has a heading, a kind such as summary or action_items, and a body or items. It also has the transcript as turns with speaker, role (me, others, unknown), and text. Transcripts over 200 KB of text are cut at a whole turn, with transcript_truncated: true.

Result
{
  "id": "6f1c2a9e-4b7d-4e15-9a3c-0d2f8b6e1a44",
  "title": "Pricing sync with Acme",
  "mode": "sales_calls",
  "started_at": "2026-10-27T15:00:00Z",
  "ended_at": "2026-10-27T15:32:00Z",
  "expires_at": "2026-11-03T15:40:12Z",
  "sections": [
    { "heading": "Summary", "kind": "summary", "body": "Acme wants a volume discount..." },
    { "heading": "Action items", "kind": "action_items", "items": ["Send revised quote by Thursday"] }
  ],
  "transcript": [
    { "speaker": "Me", "role": "me", "text": "Thanks for making time. Where did you land on the renewal?" },
    { "speaker": "Others", "role": "others", "text": "We need a discount on the enterprise plan before Friday." }
  ],
  "transcript_truncated": false
}

Call it over HTTP

MCP is JSON-RPC 2.0 over HTTPS, so you can call the tools from a script without an MCP client. Send one JSON-RPC message per POST; the answer is plain JSON.

curl https://api.viewframing.com/mcp \
  -H "Authorization: Bearer $VIEWFRAMING_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "list_meetings",
      "arguments": { "query": "pricing", "limit": 5 }
    }
  }'

The tool's output is in result.structuredContent, and the same JSON is in result.content[0].text:

Response
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [{ "type": "text", "text": "{\"meetings\":[...],\"next_cursor\":null}" }],
    "structuredContent": { "meetings": [ ... ], "next_cursor": null },
    "isError": false,
    "resultType": "complete"
  }
}

The server is stateless: no session id, no event stream. It also answers initialize (protocol versions 2025-03-26 to 2025-11-25), server/discover (2026-07-28), tools/list, and ping.

API keys

Limits and errors

LimitValue
Requests60 per minute per account, across all keys and the app's uploads
Meeting retention7 days from first upload
Synced meetings300 at a time
Results per page50
Transcript per meeting200 KB of text
AnswerMeaning
401Missing, mistyped, or revoked key.
403The request came from a web page (it had an Origin header), or the account is disabled.
429Over the rate limit. Wait the number of seconds in Retry-After.
plan_requiredA tool error (isError: true) when the account isn't on Pro or Lifetime. Connecting still works.
not_foundA tool error: no meeting with that id, or it has expired.
-32602JSON-RPC invalid params, such as a bad limit, time, or cursor. The message says which.

Your data

Questions: hello@viewframing.com.