agentleFS
Galbaz1Galbaz1/video-research-mcp/CLAUDE.md

video-research-mcp

CLAUDE.md23 starsChanged 38 days agoMITView on GitHub

Do not import AGENTS.md (for example via @AGENTS.md or @../AGENTS.md) from this file or any .claude/rules/*.md file. AGENTS.md is Codex-specific and keeping it out of Claude memory prevents duplicate or conflicting guidance. A monorepo with three separately launched MCP servers: All servers default to ~/.config/video-research-mcp/.env for configuration; the root also accepts an installer-selected VIDEO_RESEARCH_ENV_FILE. Built with Pydantic v2 and hatchling. Python >= 3.11. Use scripts/detect_review_scope.py --json to choose the review mode from git state: Trigger this detector: - when user…

  • Reads credentials

The file

Show its rules and text

We split this CLAUDE.md into the rules it gives an agent

15 rules. About 0 are common, 2 are distinctive, and 13 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 13

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Do not import AGENTS.md (for example via @AGENTS.md or @../AGENTS.md) from this file or any .claude/rules/*.md file.

    line 5
  2. Very specific:

    All servers default to ~/.config/video-research-mcp/.env for configuration.

    line 15
  3. Very specific:

    Use scripts/detect_review_scope.py --json to choose the review mode from git state:

    line 41
  4. Very specific:

    when user asks for a review/audit/check

    line 49
  5. Distinctive:

    after major git state transitions (commit, rebase, merge, branch switch)

    line 50
  6. Very specific:

    Check /gr:recall first (already researched?).

    line 59
  7. Very specific:

    NEVER use /gr:research-deep for quick questions (costs $2-5, 10-20 min) — use /gr:search instead.

    line 60
  8. Very specific:

    Every tool MUST have: (1) ToolAnnotations decorator, (2) Annotated params with Field, (3) Google-style docstring with Args/Returns, and (4) …

    line 142
  9. Distinctive:

    When bumping a dependency:

    line 217
  10. Very specific:

    Update constraint in pyproject.toml

    line 218
  11. Very specific:

    Run uv lock, then uv sync --locked --extra dev to resolve and install

    line 219
  12. Very specific:

    Search for compatibility workarounds that may now be removable (rg '2\.x|v1|compat|shim|workaround' src/)

    line 220
  13. Very specific:

    Run full test suite: uv run --locked pytest tests/ -v

    line 221
  14. Very specific:

    All servers default to ~/.config/video-research-mcp/.env.

    line 283
  15. Very specific:

    All other config (thinking level, temperature, cache dir/TTL, session limits, retry params, YouTube API key) has sensible defaults — see …

    line 288

≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

CLAUDE.md

Memory Source Guard

Do not import AGENTS.md (for example via @AGENTS.md or @../AGENTS.md) from this file or any .claude/rules/*.md file. AGENTS.md is Codex-specific and keeping it out of Claude memory prevents duplicate or conflicting guidance.

What This Is

A monorepo with three separately launched MCP servers:

  1. video-research-mcp (root) — research, media analysis, source ingestion, knowledge retrieval, and optional provider adapters. Uses the configured Gemini model (google-genai SDK) and YouTube Data API v3.
  2. video-explainer-mcp (packages/video-explainer-mcp/) — explainer planning, generation, durable rendering, and assembly of existing materials. Wraps the video_explainer CLI and supports configured renderer routes with separate prerequisites.
  3. video-agent-mcp (packages/video-agent-mcp/) — bounded parallel scene-text generation through the Claude Agent SDK.

All servers default to ~/.config/video-research-mcp/.env for configuration; the root also accepts an installer-selected VIDEO_RESEARCH_ENV_FILE. Built with Pydantic v2 and hatchling. Python >= 3.11.

Commands

# video-research-mcp (root)
uv sync --locked --extra dev                       # install locked dependencies
uv run --locked pytest tests/ -v                   # all tests
uv run --locked ruff check src/ tests/              # lint
GEMINI_API_KEY=... uv run --locked video-research-mcp # run server

# video-explainer-mcp (packages/)
cd packages/video-explainer-mcp
uv sync --locked --extra dev                       # install locked dependencies
uv run --locked pytest tests/ -v                   # all tests
uv run --locked ruff check src/ tests/              # lint
EXPLAINER_PATH=/path/to/video_explainer uv run --locked video-explainer-mcp

cd ../..
python3 scripts/detect_review_scope.py --json       # from the root checkout

Automated Review Triggers

Use scripts/detect_review_scope.py --json to choose the review mode from git state:

  • uncommitted: there are local unstaged/staged changes (git status --porcelain not empty)
  • pr: clean working tree + branch has open PR (gh pr view resolves OPEN PR)
  • commits: clean working tree, no open PR, and branch is ahead of base (base_branch..HEAD)
  • none: nothing reviewable in current branch state

Trigger this detector:

  • when user asks for a review/audit/check
  • after major git state transitions (commit, rebase, merge, branch switch)

Priority when multiple states can apply:

  1. uncommitted
  2. pr
  3. commits

/gr Plugin Routing

Check /gr:recall first (already researched?). Unsure which /gr command? Use /gr:advisor. NEVER use /gr:research-deep for quick questions (costs $2-5, 10-20 min) — use /gr:search instead.

Architecture

server.py mounts domain servers onto a root FastMCP("video-research"). The core workflows include:

DomainSource
Video analysis, sessions, batches, and windowstools/video.py, tools/video_batch.py, tools/video_windows.py
Research, documents, web research, academic metadata, and executiontools/research.py and its deferred registration modules
Content analysis and extractiontools/content.py, tools/content_batch.py
Search and provider adapterstools/search.py, tools/search_provider.py, tools/text_provider.py
Configuration and cachetools/infra.py
YouTube metadata, comments, playlists, and channelstools/youtube.py, tools/youtube_channels.py
Knowledge retrieval and ingestiontools/knowledge/

Additional mounts cover images/vision, media preparation/perception, audio, durable jobs, memory, ingestion, live workflows, and hardware. server.py is the current mount inventory; tool discovery provides the exposed schemas. Registration alone does not establish provider or native-runtime readiness.

Key patterns:

  • Instruction-driven tools — tools accept free-text instruction + optional output_schema instead of fixed modes
  • Structured output — Gemini generation uses validated models; deterministic operations validate typed inputs/results without Gemini
  • Error handling — tools catch operational errors and use make_tool_error() within their published dictionary or native CallToolResult envelope
  • Write-through storage — selected result-producing workflows store to Weaviate when configured; store calls are non-fatal
  • Context caching — context_cache.py pre-warms Gemini caches after video_analyze; video_create_session reuses them via lookup_or_await()
  • MLflow tracing — @trace() decorator on all tools; graceful degradation when mlflow not installed
  • Reranker — Cohere reranking in knowledge_search with overfetch pattern; auto-enables when COHERE_API_KEY is set

Key singletons: GeminiClient (client.py), get_config() (config.py), session_store (sessions.py, optional SQLite via persistence.py), cache (cache.py), WeaviateClient (weaviate_client.py).

Optional dependency: the agents extra enables knowledge_ask and knowledge_query through Weaviate's QueryAgent. Its constraint lives in pyproject.toml; enable the extra in the environment that launches the server.

Deep dive: docs/ARCHITECTURE.md | docs/DIAGRAMS.md

video-explainer-mcp Architecture

packages/video-explainer-mcp/src/video_explainer_mcp/server.py mounts the following workflow groups:

Sub-serverToolsFile
projectexplainer_create, explainer_inject, explainer_status, explainer_listtools/project.py
pipeline and renderingexplainer_generate, explainer_step, explainer_short, explainer_render, explainer_render_start, explainer_render_poll, explainer_render_canceltools/pipeline.py, tools/render_jobs.py
qualityexplainer_refine, explainer_feedback, explainer_factchecktools/quality.py
audioexplainer_sound, explainer_music, explainer_narration, explainer_audio_mixtools/audio.py, tools/audio_mix.py

Other mounts provide planning, diagnostics, variants, commentary, timing, refinement, render fact-checking, and existing-material assembly. Stock-media search/download is not mounted; consult server.py for registration.

Key patterns:

  • CLI wrapping — tools invoke the upstream .venv/bin/video-explainer console script via asyncio.create_subprocess_exec (never shell=True)
  • Filesystem scanning — scanner.py inspects project directories for step completion without CLI calls
  • Background renders — start/poll/cancel use durable SQLite jobs, frozen requests, leases, and fresh artifact readback
  • Shared config — same ~/.config/video-research-mcp/.env as the parent server

Key modules: runner.py (subprocess executor), scanner.py (project inspector), jobs.py and render_worker.py (durable render lifecycle), prereqs.py (system checks), config.py (singleton from env).

Env vars: EXPLAINER_PATH for upstream CLI workflows, EXPLAINER_RENDERER_ENTRY for a configured renderer route, EXPLAINER_TTS_PROVIDER (default: mock), ELEVENLABS_API_KEY, OPENAI_API_KEY.

video-agent-mcp Architecture

packages/video-agent-mcp/ generates scene definitions through bounded SDK calls.

Sub-serverToolsFile
scenesagent_generate_scenes, agent_generate_single_scenetools/scenes.py

The SDK process has explicit budgets, isolated child configuration and no built-in tools. Results must be validated before writing scene artifacts.

Conventions

New Tools

Every tool MUST have: (1) ToolAnnotations decorator, (2) Annotated params with Field, (3) Google-style docstring with Args/Returns, and (4) an explicit result contract. Generative workflows use GeminiClient.generate_structured(); deterministic operations validate typed inputs/results directly without Gemini. Shared types live in types.py.

Native media tools may return mcp.types.CallToolResult with typed structuredContent, a JSON text block, and bounded ImageContent. Declare success/error output schemas and offer the same metadata without images. Preserve existing return contracts; this is the exception in src/AGENTS.md.

@server.tool(annotations=ToolAnnotations(readOnlyHint=True, openWorldHint=True))
async def my_tool(
    instruction: Annotated[str, Field(description="What to extract")],
    thinking_level: ThinkingLevel = "medium",
) -> dict:
    """One-line summary of what this tool does.

    Args:
        instruction: Free-text analysis instruction.

    Returns:
        Dict with structured results or error via make_tool_error().
    """

Full walkthrough: docs/tutorials/ADDING_A_TOOL.md

New Agents

Frontmatter: name (required), description (required), tools (CSV), color, memory (project/user), maxTurns, skills (preload list). Body: persona + workflow + output format. Read-only agents should restrict tools to only the MCP query tools they need.

New Skills

Frontmatter: name (required), description (required — controls auto-trigger), allowed-tools, disable-model-invocation (true for side-effect skills). Body loaded only after trigger. Description must include domain-anchor and negative qualifiers to prevent false positives. Use ${CLAUDE_SKILL_DIR} to reference bundled scripts.

New Commands

Frontmatter: description, argument-hint, allowed-tools. Body uses $ARGUMENTS for user input. Commands are explicit /gr:name invocations — always add to FILE_MAP in bin/lib/copy.js.

Docstrings

Google-style. Required on every module, public class, public function/method, and non-obvious private helpers. Be concise and factual — one-liner is enough when name + signature are self-explanatory. Args/Returns/Raises only when non-obvious. Pydantic models: document purpose and which tool uses them; don't duplicate Field(description=...). Docstrings do NOT count toward file size limits.

File Size

~300 lines of executable code per production file (docstrings/comments/blanks excluded). Split by concern, not by line count. Test files may go to 500. Reference: video.py / video_url.py split.

Dependencies

Constraint Policy

Pin to the major version we actually use. No cross-major constraints — a constraint like >=2.0 that accepts both 2.x and 3.x is forbidden when the major versions have breaking API changes. Rationale: overly broad constraints hide version-specific code and create silent compatibility debt (ref: FastMCP 2.x→3.x FunctionTool wrapping incident).

Format: >=MAJOR.MINOR where MINOR is the lowest version whose API surface we actually use. Never >=MAJOR.0 unless we've verified compatibility with the .0 release.

Verified Dependencies

pyproject.toml declares the supported API majors; each uv.lock records the exact tested versions. Use uv sync --locked --extra dev for verification. Upgrade from current PyPI metadata, then resolve all three package locks and verify the affected APIs. Do not maintain a second installed-version table here.

Known Defensive Patterns (Legitimate)

These getattr patterns protect against SDK response shape variation, not version incompatibility — do NOT remove:

  • getattr(p, "thought", False) — Gemini thinking mode parts; thought attr only present when thinking is enabled
  • getattr(cand, "grounding_metadata", None) — search grounding; only present on grounded responses
  • getattr(response, "final_answer", "") in knowledge/agent.py — weaviate-agents response shape varies by query type
  • try: from googleapiclient.errors import HttpError in tools/youtube.py — guards error formatting when google-api-python-client isn't importable

Updating Dependencies

When bumping a dependency:

  1. Update constraint in pyproject.toml
  2. Run uv lock, then uv sync --locked --extra dev to resolve and install
  3. Search for compatibility workarounds that may now be removable (rg '2\.x|v1|compat|shim|workaround' src/)
  4. Run full test suite: uv run --locked pytest tests/ -v

Agent Teams

Inherit the active configured model for agents. Use bounded, independent lanes with explicit write ownership and join them before integration.

Agent configuration: .claude/rules/ contains project-specific conventions that agents inherit automatically via path-filtered frontmatter.

Testing

Unit tests, all unit-level with mocked Gemini. asyncio_mode=auto. No test hits the real API.

Key fixtures (conftest.py): mock_gemini_client (mocks .get(), .generate(), .generate_structured(), .generate_json_validated()), clean_config (isolates config), mock_weaviate_client, mock_weaviate_disabled, _unwrap_fastmcp_tools (session-scoped, ensures tool callability), autouse GEMINI_API_KEY=test-key-not-real, _disable_tracing, _isolate_dotenv, _isolate_upload_cache, _isolate_durable_jobs.

File naming: test_<domain>_tools.py for tools, test_<module>.py for non-tool modules.

Full guide: docs/tutorials/WRITING_TESTS.md | Project-specific patterns: .claude/rules/testing.md

Plugin Installer

Two-package architecture: npm distributes plugin assets and registers the pinned core server via uvx; PyPI supplies the Python runtime. The installer supports scoped Claude and Codex layouts. Same package name, different registries.

npx video-research-mcp@0.8.0-rc.3              # install the pinned source version
npx video-research-mcp@0.8.0-rc.3 --check      # inspect installation hashes/status
npx video-research-mcp@0.8.0-rc.3 --uninstall  # remove unchanged owned assets

To add a command/skill/agent: create file, add to FILE_MAP in bin/lib/copy.js, run node bin/install.js --global.

Deep dive: docs/PLUGIN_DISTRIBUTION.md (FILE_MAP, manifest tracking, discovery mechanism, complete inventory)

Env Vars

Canonical source: config.py:ServerConfig. Key variables:

VariableDefaultNotes
GEMINI_API_KEY(required)Also used as YouTube fallback
GEMINI_MODELgemini-3.8-flash
GEMINI_FLASH_MODELgemini-3.8-flashSame default as GEMINI_MODEL; thinking_level is the dial
GEMINI_THINKING_LEVELmediumlow / medium / high; minimal is rejected for models that do not support it
DEEP_RESEARCH_AGENTdeep-research-preview-04-2026Interactions API agent ID
WEAVIATE_URL""Empty = knowledge store disabled
WEAVIATE_API_KEY""Required for Weaviate Cloud
GEMINI_SESSION_DB""Empty = in-memory only
RERANKER_ENABLED""Auto-enabled when COHERE_API_KEY set
COHERE_API_KEY""Enables Cohere reranker in knowledge_search
FLASH_SUMMARIZE"true"Use Flash model for summarization
GEMINI_TRACING_ENABLED""Enable MLflow tracing
MLFLOW_TRACKING_URI""MLflow server URI
MLFLOW_EXPERIMENT_NAME""MLflow experiment name
WEAVIATE_VECTORIZER""openai, weaviate, or ollama; selects openai when OPENAI_API_KEY is present, otherwise weaviate
WEAVIATE_AUTO_MIGRATE""Set "true" to auto-migrate collections when vector config changes
EXPLAINER_PATH""Path to cloned video_explainer repo
EXPLAINER_TTS_PROVIDER"mock"mock, elevenlabs, edge
ELEVENLABS_API_KEY""Required for elevenlabs TTS
OPENAI_API_KEY""Required for the OpenAI vectorizer and configured OpenAI provider calls

All servers default to ~/.config/video-research-mcp/.env; the root uses VIDEO_RESEARCH_ENV_FILE when selected by a local installation. Nonempty process values take precedence. Blank values and unresolved self-placeholders are treated as unset and can be filled from the selected file.

All other config (thinking level, temperature, cache dir/TTL, session limits, retry params, YouTube API key) has sensible defaults — see config.py or docs/ARCHITECTURE.md §10.

Archive

archive/ (gitignored) contains development artifacts moved out of the working tree: completed design docs, code reviews, bug reports (now in GitHub Issues), audit snapshots, and research notes. See archive/INDEX.md for a full inventory.

Developer Docs

DocumentContents
docs/ARCHITECTURE.mdTechnical guide to workflows, shared state, provider access, and companions
docs/DIAGRAMS.mdServer hierarchy, GeminiClient flow, session lifecycle, Weaviate data flow
docs/tutorials/GETTING_STARTED.mdInstall, configure, first tool call
docs/tutorials/ADDING_A_TOOL.mdStep-by-step tool creation with checklist
docs/tutorials/WRITING_TESTS.mdFixtures, patterns, running tests
docs/tutorials/KNOWLEDGE_STORE.mdWeaviate setup, collection schemas, retrieval, and QueryAgent
docs/PLUGIN_DISTRIBUTION.mdTwo-package architecture, FILE_MAP, discovery, full inventory
docs/PUBLISHING.mdDual-registry publishing guide with version sync policy
docs/RELEASE_CHECKLIST.mdCopy-paste checklist for each release
CHANGELOG.mdRelease history in Keep a Changelog format

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.