SanTech Content Engine MCP Server
Enables YouTube competitor research, signal analysis, and transcript-aware pack building for content ideation and scriptwriting.
README
SanTech Content Engine
Local-first YouTube research-to-script engine for SanTech010.
The backend performs deterministic work: YouTube fetching, storage, outlier math, pack building, validation, save/select/export, and MCP tool exposure. Connected AI clients perform creative and judgment work using backend packs as source of truth.
Current status: offline backend, MCP backbone, quota guard, resource import, recent-only outliers, early velocity signals, combined signal reports, and signal-target transcript acquisition implemented.
Important MCP rule: source files sync locally on MCP HTTP startup and before YouTube collection. get_signal_research_pack reads the current local database. It does not pull fresh YouTube data. Use get_project_status to check freshness and source-sync warnings.
Verified:
python -m pytest tests -q
python -m compileall -q src
New Laptop Setup
On a fresh Windows laptop:
git clone git@github.com:budhasantosh010/san-tech-yt-research-titles-scripts.git
Set-Location -LiteralPath ".\san-tech-yt-research-titles-scripts"
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\bootstrap-windows.ps1
Then edit .env locally and add:
YOUTUBE_API_KEYSMCP_ROUTE_SECRETALLOWED_HOSTSwith your Tailscale Funnel hostname
Do not commit .env.
Before pushing from any laptop:
powershell -NoProfile -ExecutionPolicy Bypass -File .\scripts\check-github-ready.ps1
Full reproducibility instructions live in DOCS/FUTURE_PROOF_SETUP.md.
Daily MCP Startup
Use two PowerShell terminals.
Terminal 1:
$project = "C:\Users\Lenovo\Music\Startups\YT Automations\1 San Tech Channel Research, Title & Script with Codex"
Set-Location -LiteralPath $project
.\scripts\run-mcp-http.ps1
Terminal 2:
$project = "C:\Users\Lenovo\Music\Startups\YT Automations\1 San Tech Channel Research, Title & Script with Codex"
Set-Location -LiteralPath $project
.\scripts\start-funnel.ps1
Good Funnel output should show:
proxy http://127.0.0.1:3001
ChatGPT Connector URL Format
Use this shape:
https://<machine>.<tailnet>.ts.net/mcp/YOUR_ROUTE_SECRET/
Never include brackets around route secret.
Correct:
https://desktop-fdce9ak.taila47816.ts.net/mcp/abc123.../
Wrong:
https://desktop-fdce9ak.taila47816.ts.net/mcp/<abc123...>/
Use one tool call at a time in ChatGPT. No parallel tool calls. For connection tests, call only get_project_status.
Implemented:
- SQLite schema
- config loader
- competitor storage
- video/snapshot storage
- recent-only outlier math and persistence
- early velocity signal math and persistence
- YouTube Data API adapter with fake-client tests
- viral title collection importer for CSV/XLSX
- video idea save/list/select
- title idea save/list/select
- script points save/select
- context pack builders
- transcript save/get/list-missing storage
- signal-target transcript acquisition adapters
- transcript acquisition attempt tracking
- transcript-aware outlier research packs
- script save/export
- FastMCP server wrapper
- workflow prompt templates
Still needs live/user-provided inputs:
YOUTUBE_API_KEYYOUTUBE_API_KEYSfor comma-separated multiple keys- competitor channel list
- real viral title/video collection file
- ChatGPT MCP connector/tunnel setup
Quota safety:
YOUTUBE_MAX_DAILY_QUOTA_FRACTION=0.05limits the app to 5% of each key's configured daily quota.YOUTUBE_CACHE_MAX_AGE_HOURS=24prevents refetching fresh video details/snapshots.RESEARCH_STALE_AFTER_HOURS=24controls whenget_project_statuswarns that research data is stale.AUTO_SYNC_SOURCES_ON_STARTUP=truekeeps competitor and viral sources synced locally when the MCP HTTP server starts.AUTO_SYNC_DEACTIVATE_MISSING=falsemeans startup sync repairs/reactivates source rows but does not deactivate missing competitors unless explicitly enabled.- API keys belong in
.env, which is ignored by Git.
Resource files:
- Competitors source of truth:
resources/competitors/santech_competitors.txt - Viral titles:
resources/viral titles in adjacent niches
Competitor TXT format:
- one absolute YouTube channel URL per line
- no display names
- no notes
- no commas
- no copied YouTube search/export rows
Messy CSV/XLSX/MD/TXT files can be inspected/imported, but do not use them as the canonical competitor source. If a sync source has zero files, zero rows, or zero valid YouTube channel URLs, deactivation is skipped for safety.
Signal workflow
Current deterministic workflow:
- Update
resources/competitors/santech_competitors.txtif competitor sources change. - Update viral title CSV/XLSX files if the viral title collection changes.
- Start the MCP HTTP server; backend auto-syncs sources locally.
- Refresh YouTube data and save a new snapshot row per collection run.
- Calculate recent outliers.
- Calculate early velocity.
- Dump a combined signal report.
- Fetch transcripts for selected signal targets only.
- Build transcript-aware research packs.
- Later, ChatGPT analyzes and generates ideas/titles/scripts.
MCP tool boundaries:
- Source sync is automatic on backend startup and before
collect_all_competitors. sync_competitors_from_fileandsync_viral_collectionremain admin/debug tools, but ChatGPT should not call them during normal use.scripts/sync-sources.ps1runs source sync locally without ChatGPT.scripts/run-research-refresh.ps1runs local source sync, YouTube collection, signal calculation, and project status from PowerShell.refresh_research_datacan collect YouTube stats and recalculate outlier/velocity signals. It does not fetch transcripts.get_signal_research_packis the read tool ChatGPT should use after freshness is acceptable.mark_signal_reviewedcan mark a signal asreviewed,approved,rejected,used, orsuppressed; default reports exclude reviewed/rejected/used/suppressed signals.
Recent outlier means a recent video already beat that channel's recent baseline.
Early velocity means a new video is moving unusually fast and may become an outlier.
True recent velocity requires at least two snapshots. If only one snapshot exists, the system uses lifetime velocity as a rough fallback.
Canonical competitor source sync:
python -m santech_engine.cli sync-sources
Signal commands:
python -m santech_engine.cli collect-all --limit 10
python -m santech_engine.cli calculate-outliers --recent-only --all-competitors
python -m santech_engine.cli list-outliers --limit 5
python -m santech_engine.cli dump-outlier-report --limit 20 --output exports/recent-outliers.json
python -m santech_engine.cli calculate-velocity --all-competitors
python -m santech_engine.cli list-velocity-signals --limit 10
python -m santech_engine.cli dump-velocity-report --limit 20 --output exports/early-velocity.json
python -m santech_engine.cli dump-signal-report --output exports/signal-report.json
python -m santech_engine.cli fetch-transcripts-for-signal-targets --adapter youtube_transcript_ai --limit-outliers 5 --limit-velocity 5
Transcript acquisition
This project supports transcript-aware research packs.
The system does not fetch transcripts for every competitor video.
Flow:
- Collect competitor videos.
- Calculate recent outliers and early velocity.
- Fetch transcripts only for combined signal targets.
- Cache successful transcripts.
- Mark missing/failed transcripts honestly.
- Include real transcript text in outlier packs only when available.
Default adapter:
youtube_transcript_ai
Backup adapter:
youtube_transcript_ioifYOUTUBE_TRANSCRIPT_IO_API_TOKENis set
Manual fallback:
- If automatic fetching fails for an important outlier, the user can paste transcript text into ChatGPT.
- ChatGPT can then call
save_video_transcriptthrough MCP to cache it.
Warnings:
- Transcript providers are not the official YouTube Data API.
- They may fail or change.
- Do not use aggressive scraping/proxy bypassing.
- Keep fetches low-volume and signal-first.
- The system must not infer or invent what a video said from title/metrics alone.
Useful local commands:
python -m santech_engine.cli import-competitors
python -m santech_engine.cli import-viral-collection
python -m santech_engine.cli doctor
python -m santech_engine.cli setup-env
python -m santech_engine.cli test-transcript-provider --adapter youtube_transcript_ai
python -m santech_engine.cli smoke-test
python -m santech_engine.cli collect-all --limit 5
python -m santech_engine.cli calculate-outliers --recent-only --all-competitors
python -m santech_engine.cli calculate-velocity --all-competitors
python -m santech_engine.cli dump-signal-report --output .\exports\signal-report.json
python -m santech_engine.cli fetch-transcripts-for-signal-targets --adapter youtube_transcript_ai --limit-outliers 5 --limit-velocity 5
python -m santech_engine.cli transcript-status --video-id 123
python -m santech_engine.cli list-transcript-attempts --limit 20
python -m santech_engine.cli save-transcript --video-id 123 --file .\transcript.txt
python -m santech_engine.cli dump-outlier-pack --include-transcripts --output .\exports\outlier-pack.json
python -m santech_engine.cli dump-title-pack --idea-id 1 --output .\exports\title-pack.json
python -m santech_engine.cli dump-script-pack --title-id 1 --output .\exports\script-pack.json
Run MCP server locally:
python -m santech_engine.mcp_server
ChatGPT MCP via Tailscale Funnel
Use this only after the local backend packs are truthful.
- Create local
.env:
Copy-Item .env.example .env
- Set the MCP bridge values in
.env.
MCP_HOST=127.0.0.1
MCP_PORT=3001
MCP_ROUTE_SECRET=<your-long-secret>
MCP_BEARER_TOKEN=
ALLOWED_ORIGINS=https://chatgpt.com,https://chat.openai.com
ALLOWED_HOSTS=127.0.0.1,localhost,<your-machine>.<your-tailnet>.ts.net
FUNNEL_BASE_URL=
Rules:
- At least 32 characters.
- Do not commit
.env. - Do not paste the secret into docs.
- Keep
MCP_BEARER_TOKENblank if the ChatGPT connector usesAuthentication: No Auth. - Add your real Tailscale Funnel hostname to
ALLOWED_HOSTS.
- Run the HTTP bridge doctor:
.\scripts\doctor-mcp-http.ps1
- Start the local MCP HTTP server:
.\scripts\run-mcp-http.ps1
- In another terminal, start Tailscale Funnel:
.\scripts\start-funnel.ps1
- Add this URL as the ChatGPT custom connector URL:
https://<machine>.<tailnet>.ts.net/mcp/<MCP_ROUTE_SECRET>
Use your real Tailscale Funnel hostname and your local route secret value.
- In ChatGPT, test:
get_project_status
- Then test the main research pack:
get_signal_research_pack
Expected route:
ChatGPT custom connector
-> Tailscale Funnel HTTPS URL
-> http://127.0.0.1:3001/mcp/<MCP_ROUTE_SECRET>
-> SanTech MCP tools
-> SQLite / YouTube API / transcript providers
Security notes:
- The Python server binds only to
127.0.0.1. - The default SanTech MCP HTTP port is
3001. - The MCP route is mounted under
/mcp/<MCP_ROUTE_SECRET>. - Allowed origins default to
https://chatgpt.comandhttps://chat.openai.com. - Allowed hosts default to
127.0.0.1andlocalhost; add the Tailscale Funnel hostname throughALLOWED_HOSTSorFUNNEL_BASE_URL. - If another MCP bridge, such as the X/Spectre bridge, is using the same Tailscale Funnel root hostname, run only one of them through that public root at a time unless you add a gateway/router.
- Scripts and doctor checks do not print API keys, bearer tokens, or the MCP route secret.
- Stop Funnel with:
.\scripts\stop-funnel.ps1
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。