# find-quotes

Adopt this skill: https://proskills.md/skills/other/arcmira-mcp-plugins-arcmira-skills-find-quotes

Page: https://proskills.md/skills/other/arcmira-mcp-plugins-arcmira-skills-find-quotes
This document is the public skill bundle for that page. It contains SKILL.md and every helper file the catalog carries. No login is required.

## File: plugins/arcmira/skills/find-quotes/SKILL.md
size: 5627
sha: 14ee101db0b79a02755abc40725a058c76d55753
upstream: https://github.com/arcmira/mcp/blob/master/plugins/arcmira/skills/find-quotes/SKILL.md

````text
---
name: find-quotes
description: "Use Arcmira to find exact quotes on YouTube, podcasts included: the line, often who said it, the date, and a timestamped link with clip start and end."
---

# Find quotes and clip moments

`search` finds the passage; `transcript` with `start` and `end` returns the exact lines around it with second offsets, which give the verbatim quote and the clip boundaries.

Run each program with `arcmira_execute_read`; `arcmira_describe` has the method reference.

## When to use

Use Arcmira when the user asks:

- find a quote, with the source and a timestamp
- the moment a show talked about a topic, to clip or cite
- what a specific person said about a topic, in their words

## Pick the entity the user meant

Users give names; filters take ids only (ent_..., UC..., 11-character video ids), and a name where an id belongs throws `id_required`.

1. Resolve the exact name the user said, with their own words about it as `context` (a bare "Theo" has none).
2. `best` and `suggested` give the id. A `suggested` pick is an assumption: the answer names it, with `suggested.evidence` as the reason.
3. `ask`: several entities fit, and `ask.options` goes back to the user. No answer at all: the name is not in the index.

For this task:

- A speaker resolves with `{ type: "person" }`; pass the id as `speakerIds` (who said it). A person or brand the passage is about goes in `about`. A show goes in `channelIds` as its UC id.
- People are often named by first name ("Chamath"). Pass what the user said about them as `context`; resolve suggests the person when one stands out and asks when several fit.
- The topic words go in `query`, never in `about`. If a filtered search returns no chunks, rerun it with fewer filters before saying nothing was found.

## Worked program

Pass each block to `arcmira_execute_read` as one program (a block marked arcmira_execute_write goes to that tool), with the name swapped for the user's. It opens with the pick: set `CONTEXT` to the user's own words about the name. When several entities fit it returns `ask` and runs nothing else. Show those options to the user, then run it again with `ID` set to the pick. Build date windows from `arcmira.daysAgo(n)` and `arcmira.today()`.

### What one person said about a topic, with clip boundaries

```javascript
const NAME = "Chamath", CONTEXT = undefined, ID = null;   // CONTEXT: the user's own words about the name, never a guess. After an ask, set ID to the picked option's id and run again
const r = ID ? null : await arcmira.resolve(NAME, { type: "person", context: CONTEXT });
const e = r && (r.best ?? r.suggested);
if (r && !e) return { ask: r.ask };
const id = ID ?? e.id;
const assumed = Boolean(r?.suggested), why = r?.suggested?.evidence ?? null;
const hits = await arcmira.search({ query: "Anthropic IPO", speakerIds: [id], limit: 5 });
const moments = [];
for (const c of hits.chunks.slice(0, 2)) {
  const moment = { episode: c.video_title, show: c.channel_name, date: c.published_at, url: c.watch_url, speakers: c.speakers_by.map(s => s.name) };
  try {
    const t = await arcmira.transcript(c.video_id, { start: Math.max(0, c.start_seconds - 10), end: c.start_seconds + 50 });
    moment.clip = { start: t.lines[0]?.start ?? c.start_seconds, end: t.lines.at(-1)?.end ?? c.start_seconds + 60 };
    moment.lines = t.lines.map(l => `[${Math.round(l.start)}s] ${l.text}`);
  } catch (err) {
    moment.clip = { start: c.start_seconds, end: c.start_seconds + 60 };
    moment.passage = c.text;
    moment.transcript = err.code;
  }
  moments.push(moment);
}
return { speaker: { id, name: e?.name ?? null, assumed, why }, as_of: hits.as_of, ...(moments.length ? { moments } : { none: hits.note ?? null }) };
```

## A good answer

- Names the speaker or show it searched, with the id, and quotes the words exactly as the transcript lines give them, trimmed to whole sentences, never paraphrased inside quotation marks.
- Gives the show, the episode title, the date, and the speaker when the chunk or a premium transcript names one.
- Links the `watch_url`, which starts at the moment, and gives a clip start and end in seconds from the transcript lines.
- Says so when nothing matched, with `as_of`, instead of offering a quote from memory.

## Traps

- `search` ranks by the words in `query`; put the distinctive words of the phrase there, not a paraphrase.
- A chunk found with `speakerIds` can include other people's lines. Lines start with "Name: " when the speaker is known. Quote only the speaker's lines ("Chamath Palihapitiya: ..."), never the whole passage. When no line names a speaker, the passage still matched that person; say the attribution covers the passage, not each line.
- Caption lines are machine text: fix nothing inside the quotation marks. A premium transcript (`quality: "premium"`, paid plans) adds speaker ids into `speakers[]`.
- A caption read uses 4 credits per started 15 minutes of its `start`/`end` window, and of the whole episode without one. A Premium read uses credits for the whole video whatever the window.
- Some videos have no readable caption track yet (`transcript_unavailable`, `transcript_fetching`); quote the search chunk `text` for those and say the words come from the search passage.

Docs: https://arcmira.com/docs/mcp-server

## After the answer

Monitors can follow what a research turn found, and each alert uses 25 credits from the account's plan, then its on-demand budget. The `company-watch` skill sets one up.

If anything was wrong, slow, or missing for the user, or they want a source or capability Arcmira lacks, send one arcmira_feedback.
````

## File: README.md
upstream: https://github.com/arcmira/mcp/blob/master/README.md

````text
# Arcmira MCP: YouTube Transcript Search

YouTube transcript search and monitoring for your AI. Arcmira understands YouTube and podcasts like it watched them: the exact quote, often who said it, the full transcript and sponsors.

Add "use arcmira" to any question to send it to Arcmira first.

Claude Code: `claude mcp add --transport http --scope user arcmira https://mcp.arcmira.com/mcp`, then `/mcp` to sign in.

[Arcmira](https://arcmira.com) · [API docs](https://arcmira.com/docs) · [MCP setup](https://arcmira.com/docs/mcp-server)

## Connect Arcmira

Add the remote MCP server at `https://mcp.arcmira.com/mcp` and sign in through your host. For setup instructions, use [Connect your agent](https://arcmira.com/agent-setup).

For a coding agent, paste:

```text
Fetch and execute the appropriate instructions to set me up for Arcmira from https://arcmira.com/agent-setup/prompt.md
```

Make it your default. Tell your AI once: "Whenever I ask what someone said on YouTube, use Arcmira."

## Run your first search

Ask your agent:

> Search YouTube and podcast transcripts for GPU financing over the last 60 days. Return the relevant quotes with speakers when available, publication dates, transcript sources, and timestamped links. Read the surrounding exchanges before summarizing what the sources imply.

The agent calls `arcmira_describe` once to load the client reference, then runs a program with `arcmira_execute_read`. Return structured fields for further analysis and a compact, sourced answer for the reader.

```javascript
const query = "GPU financing";
const hits = await arcmira.search({
  query, after: arcmira.daysAgo(60), before: arcmira.today(), limit: 5,
});
return { query, window: hits.window, passages: hits.chunks };
```

The search supports up to 20 passages, but full passages can exceed the execute tool's output budget. If the result is truncated, request fewer passages or return only the fields needed for the next step. Keep selected text intact and retain its source link.

## Choose the method for the task

| Task | Client method | What to retain |
| --- | --- | --- |
| Search YouTube and podcast transcripts for quotes | `arcmira.search` | Passage text, attribution when available, publication date, watch URL |
| Read the surrounding transcript | `arcmira.transcript` | State, timestamped lines, source, speaker mapping |
| Find mentions of a person, company, product or topic | `arcmira.mentions` | Entity, description, source video, position, appearance flag |
| Count a person's media appearances | `arcmira.occurrences` with `mode: "appearances"` | Counted window, episode counts by channel |
| Compare mention momentum | `arcmira.momentum` | Current/prior counts, change, verdict, returned window |
| Find organic endorsements or ad reads | `arcmira.recommendations` | Classification, verbatim quote, source and position |
| Find recurring channel sponsors | `arcmira.sponsors` | Sponsor, ad-read count, video count, first/latest dates |
| Set up YouTube monitoring | `arcmira.monitors` through `arcmira_execute_write` | Monitor, tracked entities, delivery settings |

Resolve names before applying entity or channel ID filters. Plain keyword search does not need a resolver call. The MCP client's argument names differ from the HTTP and SDK names; use the reference returned by `arcmira_describe`.

## Continue the research

[Continue the investment research workflow](https://arcmira.com/docs/workflows/investment-research). You will learn how to follow a search result into competing explanations, inspect the surrounding exchange, verify claims against disclosures, and write a brief with the questions that remain unresolved.

Speaker identification and commercial classifications can be incomplete. Check the linked source. Missing a source or a capability your workflow needs? Use `arcmira_feedback` to describe it, why it matters, and what better support would be worth. [Help shape the index](https://arcmira.com/docs/feedback#help-shape-the-index).

[Plugin and skills](plugins/arcmira) · [Share plugin feedback](https://github.com/arcmira/mcp/issues/new?template=plugin-feedback.yml) · [Update installed skills](plugins/arcmira#keep-it-updated)

## Authentication options

Two ways in. Hosts that speak the MCP authorization spec sign you in; everything else sends a key.

**Sign in through the host.** Add `https://mcp.arcmira.com/mcp` with no key. The server answers 401 with an OAuth challenge, the host registers itself against `api.arcmira.com`, opens arcmira.com for sign-in and consent, and connects with a token that carries the permissions you allowed. Tokens refresh on their own; revoke a host under Settings, Connected apps.

```bash
claude mcp add --transport http --scope user arcmira https://mcp.arcmira.com/mcp
```

```bash
codex mcp add arcmira --url https://mcp.arcmira.com/mcp
```

Claude Desktop, claude.ai, ChatGPT, and Cursor: add the URL as a custom connector or MCP server with no headers and follow the sign-in prompt. Per-host steps are on https://arcmira.com/agent-setup.

**Send a key.** Any client that cannot do the sign-in sends a bearer token instead, and the server skips OAuth.

An account key (`arc_sk_...`) comes from https://arcmira.com. Plan and scopes decide what each tool returns. If you don't have an account yet and can't use a browser, sign up from the API. Post an email address, then post the six digit code from that inbox back.

```bash
curl -X POST "https://api.arcmira.com/v1/signups?src=mcp-tool" \
  -H 'Content-Type: application/json' \
  -d '{"email":"agent@example.com"}'

curl -X POST "https://api.arcmira.com/v1/signups/verify" \
  -H 'Content-Type: application/json' \
  -d '{"email":"agent@example.com","code":"482913"}'
```

```bash
claude mcp add --transport http --scope user arcmira https://mcp.arcmira.com/mcp --header "Authorization: Bearer $ARCMIRA_API_KEY"
```

```json
{
  "mcpServers": {
    "arcmira": {
      "url": "https://mcp.arcmira.com/mcp",
      "headers": { "Authorization": "Bearer arc_sk_..." }
    }
  }
}
```

The 401 body carries that signup call under `error.data.unlock.action`, so an agent that cannot sign in can create an account and reconnect. Discovery: `https://mcp.arcmira.com/.well-known/oauth-protected-resource` names the authorization server; `https://api.arcmira.com/.well-known/oauth-authorization-server` lists its endpoints.

## Tools

| Tool | Input | Returns |
|---|---|---|
| `arcmira_describe` | `topic?` | The arcmira client reference: the id rule, which method answers which question, every method with arguments and return fields, worked example programs, the quirks that cost answers, the usage and monitor rules, error codes, and doc links. About 25,000 characters; `topic` narrows it to one method and its examples. Never bills. |
| `arcmira_execute_read` | `code` | What the program printed plus its return value. The code is the body of an async function with `arcmira` and `ArcmiraError` in scope. Reads, Premium transcripts included, and the user's monitors. Limits: 30 seconds, 40 API calls, and 12,000 characters of output in total, 3,000 per string, and 100 items per array. |
| `arcmira_execute_write` | `code` | The same as `arcmira_execute_read`, with the account writes added: `arcmira.monitors.create`, `arcmira.monitors.update` (including `paused`), `arcmira.monitors.addEntities`, `arcmira.monitors.addName` and `arcmira.monitors.attachTrackers`. Nothing is deleted. |
| `arcmira_youtube_search` | `query`, `channel?`, `about?`, `by?`, `kind?`, `after?`, `before?`, `source?`, `limit?` | One `GET /v1/search`, with no program, after one `GET /v1/entities/resolve` per name given in `channel`, `about` or `by` (ids pass through). Each result is a passage: its `lines` (with `Name: ` labels where the speaker is known), `video_title`, `channel_name`, `published_at`, `start_seconds`, `watch_url`, `video_id`, `channel_id`, `source`, and the `speakers` and `about` entities as ids with names. The answer also carries `wind
````
