transcripts
Provides the LLM backend for the meeting minutes agent, using OpenAI models to process meeting transcripts and generate summaries and responses.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@transcriptsSummarize the latest meeting transcript and list the action items."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Meeting Minutes Agent — LangGraph + local MCP servers + Pydantic
A small, terminal-only learning project. An AI agent that is an expert at minutes of meeting (MoM) and meeting summarization. It reads meeting transcripts through a local MCP file server, does arithmetic through a local MCP math server, and asks your permission before running any tool.
What you will learn:
How to write a local MCP server with the official
mcpSDK (FastMCP), run over stdio.The tool repository pattern in LangGraph: one object that loads tools from every MCP server and hands them to the agent.
Permissions on tool execution: a LangGraph
interrupt()pauses the graph, the terminal asks youy / n / a, and the graph resumes.Pydantic for settings, tool catalog rows, permission policy, and MCP tool result schemas.
No UI. No database. Three graph nodes. That is deliberate.
Architecture
python main.py (terminal)
|
v
+---------------------------------------------------+
| LangGraph StateGraph |
| |
| START -> agent --(tool calls?)--> permission_gate |
| ^ | |
| | interrupt() |
| | y / n / a |
| | v |
| +------------------- run_tools |
| | |
| agent --(no tool calls)--> END | |
+-----------------------------------------|----------+
v
ToolRepository (agent/tool_repository.py)
+-----------+-----------+
| tool | server |
| add | math |
| read_... | transcripts
+-----------+-----------+
| |
stdio | | stdio
v v
mcp_servers/math_server.py mcp_servers/file_server.py
add, subtract, multiply, list_transcripts,
divide, average, percentage read_transcript,
search_transcripts
|
v
transcripts/*.txt, *.mdRelated MCP server: gilbert-mcp
Project layout
main.py terminal chat loop (entry point)
agent/
config.py Settings (pydantic-settings): model, paths, MCP server commands
models.py ToolSpec, PermissionRequest, PermissionMode (pydantic)
permissions.py PermissionPolicy (allow / ask / deny) + terminal prompt
tool_repository.py ToolRepository: loads MCP tools, catalog, lookup by name
graph.py build_graph(): agent -> permission_gate -> run_tools -> agent
prompts.py system prompt for the MoM expert
mcp_servers/
file_server.py FastMCP "transcripts" server (read-only file access)
math_server.py FastMCP "math" server
transcripts/ sample meeting transcripts (.txt and .md)
tests/ pytest suite, no API key neededSetup
Python 3.11 or newer.
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # then put your OpenAI key in .env.env:
OPENAI_API_KEY=sk-...
OPENAI_MODEL=gpt-4.1-miniRun
python main.pyYou will see the tool catalog first, then a prompt. Try:
List the transcripts you can read.Write the minutes for the sprint planning meeting.Summarize the Q4 budget review and tell me the total savings agreed.Across all meetings, which action items are assigned to Daniel?What percentage of this week's support tickets were about checkout?
When the agent wants to run a tool marked ask, the graph pauses:
------------------------------------------------------------
Permission required: transcripts.read_transcript
Arguments: {"filename": "2026-09-08-sprint-planning.txt"}
------------------------------------------------------------
Run this tool? [y]es / [n]o / [a]lways for this session:yruns it once.nrefuses; the LLM receives "Tool call declined by user." and adapts.aruns it and switches that tool toallowfor the rest of the session.
How it works
1. The MCP servers (mcp_servers/)
Each server is one file. FastMCP turns plain functions into MCP tools:
the type hints become the JSON schema and the docstring becomes the
description the LLM reads.
mcp = FastMCP("math")
@mcp.tool(name="add")
def add_tool(a: float, b: float) -> float:
"""Add two numbers and return a + b."""
return add(a, b)
if __name__ == "__main__":
mcp.run(transport="stdio")The file server returns pydantic models (TranscriptInfo, TranscriptContent,
SearchHit) and refuses anything outside transcripts/ or not ending in
.txt / .md. The server is the security boundary: never trust tool
arguments, even from your own agent.
Inspect a server on its own with the MCP Inspector:
npx @modelcontextprotocol/inspector python mcp_servers/math_server.py2. The tool repository (agent/tool_repository.py)
ToolRepository.from_settings() uses MultiServerMCPClient to start each
server as a subprocess, do the MCP handshake, and wrap every MCP tool as a
LangChain BaseTool. The repository remembers which server each tool came
from and what its permission is:
Tool repository
TOOL SERVER PERMISSION DESCRIPTION
list_transcripts transcripts allow List the meeting transcript files ...
read_transcript transcripts ask Read the full text of one transcript ...
add math ask Add two numbers and return a + b.The graph only ever calls repo.tools, repo.get(name) and repo.server_of(name).
Add a third server in Settings.mcp_connections() and the graph does not change.
3. The permission gate (agent/graph.py)
answer = interrupt(request.model_dump()) # graph pauses hereinterrupt() saves the graph state in the checkpointer and returns control
to main.py, which shows the request and calls
graph.ainvoke(Command(resume="yes"), config). The node re-runs from the
top and this time interrupt() returns "yes". Declined calls get a
ToolMessage so the conversation history stays valid for the LLM, and
run_tools only executes calls that have no ToolMessage yet.
4. Pydantic (agent/models.py, agent/permissions.py, agent/config.py)
PermissionMode = Literal["allow", "ask", "deny"]— a typo like"maybe"fails at construction.PermissionPolicy—rulesper tool plus adefault. EditDEFAULT_POLICYto change behaviour.PermissionRequest.model_dump()— the JSON-safe payload passed throughinterrupt().Settings(BaseSettings)— reads.envfor you.
Tests
pytest -qFile | What it proves |
| arithmetic and error cases, no MCP involved |
| listing, reading, extension and path-traversal rejection, search |
| both servers really start over stdio and answer tool calls |
| policy defaults, rules, session upgrade, terminal answer parsing |
| catalog rows and lookup |
| interrupt payload, yes / no / always / allow / deny behaviour with a scripted fake LLM |
None of the tests call OpenAI.
Exercises for students
Change the policy. In
agent/permissions.pysetread_transcripttoallowanddividetodeny. Run the agent and ask it to divide something.Add a tool. Add
word_count(filename)tofile_server.py. Restart the agent and watch it appear in the catalog with no agent code changes.Add a write tool. Add
save_minutes(filename, markdown)that writes into anoutput/folder. Keep itask. Why should write tools never beallow?Add a third server. Create
mcp_servers/datetime_server.pywith adays_between(a, b)tool and register it inSettings.mcp_connections().Swap the transport. Run a server with
mcp.run(transport="streamable-http")and change its connection to{"transport": "streamable_http", "url": ...}.
This server cannot be deployed
Maintenance
Related MCP Connectors
Securely search and manage workspace context files for AI agents and teams.
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
Zoom Meetings server for meeting search, recordings, transcripts, summaries, and meeting assets.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables AI assistants to query local Migas meeting transcripts, including searching, listing meetings, and retrieving speaker contributions, all read-only.51 npmMIT
- AlicenseAqualityDmaintenanceRead-only access to your Gilbert meetings, transcripts and summaries over MCP — list, search, and fetch transcripts and summaries.554 npm1MIT
- AlicenseNot gradedqualityAmaintenanceEnables agents to list, read, export, and derive text from local VOIVOX transcript sessions without modifying the immutable source.MIT
- AlicenseAqualityBmaintenanceProvides read-only access to finished meeting transcripts for AI assistants like Claude Code or Codex, enabling them to answer questions or draft summaries based on the transcriptions.43Apache 2.0