- Removed all cloud-related functionalities, including login prompts and token handling. - Disabled Laxis cloud features, ensuring no data is sent to external servers. - Updated manifest to reflect the new local-only functionality. - Added a new Python server to handle transcripts locally, including WebSocket support. - Implemented storage management for transcripts, including deduplication and file writing. - Created a smoke test for the WebSocket server to simulate transcript updates. - Updated README with setup instructions and usage details for the new local server.
meet-transcripts — سرور MCP زیرنویس Google Meet
سرور پایتونی که caption های Google Meet را از افزونهی Chrome میگیرد و آنها را بهصورت transcript تمیز و SRT به Claude (از طریق MCP) میدهد. در یک پراسس دو کار میکند:
Google Meet (content script)
│ chrome.runtime.sendMessage({type:"TRANSCRIPT_UPDATE", …})
▼
افزونه: service worker (bridge.js)
│ WebSocket ws://127.0.0.1:8765
▼
ws_server.py ──▶ storage.py ──▶ transcripts/<sid>.{srt,txt,json}
▲
mcp_server.py (MCP stdio) ─────────┘ ──▶ Claude Desktop
ساختار
| فایل | کار |
|---|---|
storage.py |
مدل داده، dedup (بر اساس startedAt)، رندر SRT/TXT، خواندن/نوشتن دیسک |
ws_server.py |
سرور WebSocket؛ caption را از افزونه میگیرد و به storage میدهد |
mcp_server.py |
نقطهی ورود؛ WebSocket + MCP را با هم اجرا میکند |
_smoke_test.py |
تست بدون Chrome |
اجرا (با venv)
cd meet-transcripts
py -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
python mcp_server.py # WebSocket + MCP (حالت عادی / برای Claude Desktop)
python mcp_server.py --ws-only # فقط WebSocket
python ws_server.py # فقط WebSocket (معادلِ بالا، برای تست دستی)
همهی لاگها روی stderr اند چون stdout برای پروتکل MCP (JSON-RPC) رزرو است. برای تستِ دستیِ WebSocket از
ws_server.pyیا--ws-onlyاستفاده کن (وگرنه پراسس منتظر اتصال MCP روی stdin میماند).
تست بدون Chrome
# ترمینال ۱:
python ws_server.py
# ترمینال ۲:
python _smoke_test.py
باید PONG + چند ACK بگیری و transcripts/meeting-abc123.{srt,txt,json} ساخته شود.
اتصال به Claude Desktop (MCP)
به claude_desktop_config.json اضافه کن (مسیر را با مسیر واقعی عوض کن):
{
"mcpServers": {
"meet-transcripts": {
"command": "C:\\...\\audio-voice-converter\\meet-transcripts\\.venv\\Scripts\\python.exe",
"args": ["C:\\...\\audio-voice-converter\\meet-transcripts\\mcp_server.py"]
}
}
}
Claude Desktop خودش mcp_server.py را اجرا میکند؛ همان پراسس WebSocket را هم بالا میآورد.
اگر یک نمونهی دیگر از قبل پورت ۸۷۶۵ را گرفته باشد، این نمونه فقط MCP را سرو میکند و
transcript ها را از روی دیسک میخواند (مشکلی پیش نمیآید).
ابزارها / resourceها
| ابزار | کار |
|---|---|
list_sessions |
فهرست جلسهها + تعداد segment + آخرین خط |
get_status(session_id?) |
چک سبکِ تغییر بدون متن: latest_seq, count, updated_at |
get_updates(session_id?, after_seq) |
خواندن افزایشی: فقط segmentهای بعد از after_seq |
get_latest_transcript() |
متن تمیزِ آخرین جلسه (با [mm:ss]) |
get_transcript(session_id) |
متن تمیزِ یک جلسه |
get_latest_srt() / get_srt(session_id) |
زیرنویس SRT |
transcript://{id} , srt://{id} |
resourceها |
خواندن افزایشی (بهجای خواندن کل transcript هر بار)
هر segment یک seq یکتا دارد. برای دنبالکردن یک جلسهی زنده بدون خواندن دوبارهی همهچیز:
۱. get_status بزن (خیلی ارزان، بدون متن). اگر latest_seq/updated_at عوض شد →
۲. get_updates(after_seq=<latest_seqِ قبلی>) تا فقط موارد جدید + segmentِ درحالِتکمیل را بگیری.
dedup و SRT — چهطور کار میکند
افزونه برای هر «حرف» چند بار پیام میفرستد (snapshotِ روبهرشد) ولی startedAt ثابت میماند.
سرور با همین startedAt میفهمد اینها یک segmentاند و فقط کاملترین نسخه را نگه میدارد —
پس متن تکراری ذخیره نمیشود. چون زمان شروع/پایان داریم، برای هر segment یک بلوک SRT با
تایمکد ساخته میشود. برای هر جلسه: .srt (زیرنویس)، .txt (متن خوانا با [mm:ss])،
.json (دادهی خام برای resume).
پروتکل پیامها
افزونه → سرور:
| پیام | توضیح |
|---|---|
{type:"PING", ts} |
heartbeat هر ۲۰ ثانیه |
{type:"TRANSCRIPT_UPDATE", sessionId, speaker, text, startedAt, endedAt} |
یک caption |
سرور → افزونه:
| پیام | توضیح |
|---|---|
{type:"PONG", ts} |
پاسخ heartbeat |
{type:"ACK", ok:true} |
تأیید دریافت |