Skip to main content
Glama

๐Ÿ“š study-mcp

A Model Context Protocol (MCP) server that turns video transcripts and study materials into a searchable, AI-powered knowledge base โ€” directly inside Claude Desktop.

CI Python Coverage License


โœจ What it does

Paste a video transcript or point to a PDF, slide deck, DOCX, or image and instantly:

  • ๐ŸŽฌ Ingest video transcripts โ€” paste raw text or load .srt/.vtt caption files; timestamps are preserved so you can jump back to the exact moment in the video

  • ๐Ÿ” Search semantically โ€” ask questions in natural language across all your materials, powered by local embeddings (no API cost)

  • ๐ŸŽฏ Generate quizzes โ€” sample representative context from any material so Claude can quiz you on it

  • ๐Ÿง  Summarize & create flashcards โ€” saved directly to Notion

  • ๐Ÿ“Š Track your library โ€” list materials, inspect overviews, view stats, delete what you no longer need

Everything runs locally by default (ChromaDB + HuggingFace embeddings). Set a single environment variable to switch to pgvector on Supabase/Postgres.


Related MCP server: Personal Research Assistant MCP

๐Ÿงฐ Tech Stack

Layer

Technology

Language

Python 3.13

MCP server

MCP Python SDK (FastMCP)

Embeddings

sentence-transformers + HuggingFace models (local inference, PyTorch)

Vector stores

ChromaDB (local) ยท pgvector on Supabase/Postgres (cloud)

Document parsing

Docling (PDF, DOCX, PPTX, HTML, images) + native SRT/VTT parser

Integrations

Notion API (notion-client)

Configuration

pydantic-settings (typed, env-based)

Tooling

Poetry ยท pytest (+coverage) ยท ruff ยท mypy --strict ยท pre-commit ยท commitizen

CI

GitHub Actions (lint, type check, tests on every push/PR)


๐Ÿ—๏ธ Architecture

study-mcp/
โ”œโ”€โ”€ src/study_mcp/
โ”‚   โ”œโ”€โ”€ core/
โ”‚   โ”‚   โ”œโ”€โ”€ config.py       # Settings via environment variables (pydantic-settings)
โ”‚   โ”‚   โ”œโ”€โ”€ embeddings.py   # sentence-transformers, local inference, E5 prefixing
โ”‚   โ”‚   โ”œโ”€โ”€ chunker.py      # Heading โ†’ paragraph โ†’ sentence-aware chunking
โ”‚   โ”‚   โ””โ”€โ”€ transcript.py   # SRT/VTT parser with timestamp preservation
โ”‚   โ”œโ”€โ”€ db/
โ”‚   โ”‚   โ”œโ”€โ”€ __init__.py     # VectorRepository protocol + backend auto-detection
โ”‚   โ”‚   โ”œโ”€โ”€ chroma.py       # Local vector store (ChromaDB, zero setup)
โ”‚   โ”‚   โ””โ”€โ”€ pgvector.py     # Cloud vector store (Supabase/Postgres, HNSW index)
โ”‚   โ”œโ”€โ”€ tools/
โ”‚   โ”‚   โ”œโ”€โ”€ ingest.py       # File & raw-text ingestion (Docling + native parsers)
โ”‚   โ”‚   โ”œโ”€โ”€ search.py       # Semantic search
โ”‚   โ”‚   โ”œโ”€โ”€ materials.py    # Overview, quiz context, stats, deletion
โ”‚   โ”‚   โ”œโ”€โ”€ list_materials.py
โ”‚   โ”‚   โ””โ”€โ”€ notion.py       # Notion integration (summaries & flashcards)
โ”‚   โ””โ”€โ”€ server.py           # FastMCP server: tools, resource, prompt, lifespan
โ”œโ”€โ”€ tests/                  # 60 tests, ~96% coverage, no model download needed
โ””โ”€โ”€ docs/
    โ””โ”€โ”€ claude_desktop_config.json

Design highlights:

  • Repository pattern โ€” both vector backends implement the same VectorRepository protocol; the backend is chosen at startup from DATABASE_URL with no code changes.

  • E5 query/passage prefixing โ€” intfloat/multilingual-e5-* models are trained with query: / passage: prefixes; applying them measurably improves retrieval quality. Applied automatically when an E5 model is configured.

  • Sentence-aware chunking โ€” text is split by heading, then paragraph, then grouped by whole sentences with sentence-level overlap. Chunks never cut a word or sentence in half.

  • Idempotent ingestion โ€” material_id is a SHA-256 content hash, so re-ingesting the same material is a no-op (already_indexed) instead of a duplicate.

  • Timestamp-aware transcripts โ€” SRT/VTT cues are grouped into paragraphs by speech pauses; search results on transcripts carry a start_time so you can jump back into the video.


๐Ÿ› ๏ธ Available Tools

Tool

Description

ingest_text_tool

Ingest raw text โ€” e.g. a pasted video transcript โ€” into the vector store

ingest_file_tool

Convert and index a file: PDF, DOCX, PPTX, HTML, images, .txt, .md, .srt, .vtt

search_tool

Semantic search across all indexed materials (optionally scoped to one)

list_materials_tool

List all indexed materials

get_material_overview_tool

Preview the first chunks of a material before summarizing or quizzing

generate_quiz_context_tool

Sample chunks spread across a material so Claude can write quiz questions

study_stats_tool

Totals: materials, chunks, chunks per material

delete_material_tool

Remove a material and all of its chunks

save_summary_tool

Save a summary to Notion

save_flashcards_tool

Save Q&A flashcards to Notion

create_quiz_tool

Create an interactive quiz page in Notion (open or multiple-choice, answer in Notion then paste back for checking)

The three Notion tools also accept related_pages (a list of notion_url values from earlier saves in the same conversation) to link a new page to related materials via Notion's native mentions - see docs/NOTION_SETUP.md.

The server also exposes an MCP resource (study://materials, the current library as JSON) and a prompt (study_prompt, a ready-made study-plan workflow for any material).


๐Ÿš€ Quick Start

1. Clone and install

git clone https://github.com/italoo97/study-mcp.git
cd study-mcp
poetry install

2. Configure environment

cp .env.example .env

All variables have sensible defaults โ€” the server works out of the box with ChromaDB and no external services. See .env.example for every option.

3. Configure Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (see docs/claude_desktop_config.json for a full example):

{
  "mcpServers": {
    "study-mcp": {
      "command": "poetry",
      "args": [
        "--directory", "/absolute/path/to/study-mcp",
        "run", "python", "-m", "study_mcp.server"
      ],
      "env": {
        "CHROMA_PATH": "/absolute/path/to/study-mcp/chroma_db"
      }
    }
  }
}

โš ๏ธ Claude Desktop launches the server from its own working directory, so relative paths (like the .env file or the default ./chroma_db) won't resolve to the project folder. Set CHROMA_PATH to an absolute path as above, and pass any other variables (NOTION_TOKEN, DATABASE_URL, ...) in the env block โ€” see docs/claude_desktop_config.json for a complete example.

Vector backend is auto-detected:

  • DATABASE_URL empty โ†’ ChromaDB locally (zero setup)

  • DATABASE_URL set โ†’ pgvector on Supabase/Postgres (free tier works; table and HNSW index are created automatically)

4. Restart Claude Desktop

The tools appear automatically.


๐ŸŽฌ Ingesting video transcripts

The main workflow this server was built for:

  1. Open a video (YouTube, a recorded lecture, a course platform) and copy its transcript โ€” or download the captions as .srt/.vtt.

  2. Paste it into Claude: "Ingest this transcript as 'Linear Algebra โ€” Lecture 3': ..." โ†’ Claude calls ingest_text_tool.

  3. Ask anything: "According to my lecture, what is an eigenvector?" โ†’ search_tool returns the most relevant passages, each with a start_time when available, so you can jump back to that moment in the video.

  4. Study actively: "Quiz me on this lecture" โ†’ generate_quiz_context_tool samples passages spread across the whole material and Claude writes the questions.

.srt/.vtt files are parsed natively: cue numbers and markup are stripped, consecutive cues are merged into paragraphs at natural speech pauses, and paragraph start times are preserved as metadata.


๐Ÿง  Embedding Models

Set EMBEDDING_MODEL to any sentence-transformers compatible model:

Model

Languages

Dims

intfloat/multilingual-e5-small (default)

PT + EN + 90 more

384

intfloat/multilingual-e5-base

PT + EN + 90 more

768

BAAI/bge-small-en-v1.5

EN only

384

Update EMBEDDING_DIM to match โ€” the server validates the dimension at startup and fails fast on a mismatch.


๐Ÿ“‹ Notion Setup (optional)

Only needed for save_summary_tool and save_flashcards_tool. Full walkthrough (including a script that creates the database for you) in docs/NOTION_SETUP.md.

Quick version:

  1. Create an integration at notion.so/my-integrations

  2. Create the database โ€” either run poetry run python scripts/create_notion_database.py <parent_page_id> (creates it with the right schema and shares it automatically), or create it by hand with these properties: Name (Title), Type (Select), Material (Rich text), Tags (Multi-select) โ€” then share it with your integration manually.

  3. Set NOTION_TOKEN and NOTION_DATABASE_ID in the env block of your Claude Desktop config (not .env โ€” see docs/claude_desktop_config.json).


๐Ÿ’ก Example usage in Claude

"Ingest this transcript as 'ML Course โ€” Gradient Descent': [pasted transcript]"

"Ingest this file: /Users/me/Downloads/algorithms_lecture.pdf"

"Search my materials: what is dynamic programming?"

"Give me an overview of material a1b2c3d4"

"Quiz me with 10 questions about my gradient descent lecture"

"Summarize it and save to Notion with tags: ML, optimization"

"Show my study stats"

๐Ÿ”ง Development

poetry install

poetry run task lint        # ruff check
poetry run task format      # ruff format
poetry run task type_check  # mypy --strict
poetry run task test        # pytest (60 tests, coverage gate at 80%)

The test suite runs without downloading any embedding model โ€” embeddings are faked with deterministic vectors and the repository layer is tested against an in-memory double plus a real ChromaDB instance in a temp directory.

CI (GitHub Actions) runs lint, strict type checking, and the full test suite on every push and PR.


๐Ÿ“„ License

MIT

Related MCP Connectors

Related MCP Servers