Lenny Wisdom MCP
MCP(模型上下文协议)服务器,允许克劳德访问300多集 Lenny的播客 --面向产品经理的领先播客。向它索取框架、真实的公司示例、决策指导和词汇指导,所有这些都以客人实际说的话为基础。
基于Cloudflare Workers与D1和Vectorize构建。传输:可流式传输HTTP。新剧集会自动从Dropbox同步。自助令牌注册——无需批准。
______________________________________________________________________
它做什么
服务器公开了两类9个工具:
检索 --直接搜索索引转录语料库 推理 --检索相关智慧并将其综合为结构化指导
search_wisdom("how do great PMs prioritize ruthlessly?")
coach_me("we're deciding whether to gate AI features behind enterprise licensing")
challenge_decision("we should kill the free tier to focus on enterprise")
teach_framework("Jobs to be Done")
sharpen_language("we need to move fast" audience="executive")______________________________________________________________________
快速入门
无需批准。注册一个令牌并在一分钟内连接。
1.获得代币
curl -X POST https://lenny-wisdom-mcp.vsman-dev.workers.dev/register \
-H "Content-Type: application/json" \
-d '{"label": "my project"}'答复:
{
"token": "lw_abc123...",
"tier": "free",
"daily_vector_limit": 20,
"setup_command": "claude mcp add lenny-wisdom --transport http --url https://lenny-wisdom-mcp.vsman-dev.workers.dev/mcp --header \"Authorization: Bearer lw_abc123...\""
}2.从克劳德代码连接
复制粘贴 setup_command 从回复中:
claude mcp add lenny-wisdom --transport http \
--url https://lenny-wisdom-mcp.vsman-dev.workers.dev/mcp \
--header "Authorization: Bearer lw_abc123..."重新启动克劳德代码。你完了,试试看 search_wisdom, coach_me,或9种工具中的任何一种。
替代方案:手动配置
添加 ~/.claude/mcp_servers.json (全球)或 .mcp.json (项目范围):
{
"lenny-wisdom": {
"type": "http",
"url": "https://lenny-wisdom-mcp.vsman-dev.workers.dev/mcp",
"headers": {
"Authorization": "Bearer lw_abc123..."
}
}
}______________________________________________________________________
访问层
| 层级 | 矢量搜索/天 | 如何获取 |
|---|---|---|
| 自由 | 20 | POST /register 带有标签 |
| BYOK | 无限制 | POST /register 使用您自己的Voyage AI密钥 |
| 管理员 | 无限制 | 已配置服务器 MCP_AUTH_TOKEN 秘密 |
什么是利率限制
只有5个调用Voyage AI进行矢量搜索的工具是限速的: search_wisdom, coach_me, challenge_decision, teach_framework, sharpen_language
4个仅D1的工具对所有层都是无限的: find_frameworks, find_examples, get_episode_context, list_guests
自带钥匙(BYOK)
如果你有 Voyage AI API密钥,使用该密钥注册以获得无限访问权限。您的密钥仅用于您自己的查询。
curl -X POST https://lenny-wisdom-mcp.vsman-dev.workers.dev/register \
-H "Content-Type: application/json" \
-d '{"label": "my project", "voyage_api_key": "pa-..."}'______________________________________________________________________
建筑
┌──────────────────────────────────────┐
│ Claude Code / MCP Client │
└────────────────┬─────────────────────┘
│ HTTPS + Bearer token
│ streamable-http transport
┌────────────────▼─────────────────────┐
│ Cloudflare Worker (TypeScript) │
│ │
│ POST /register → token (no auth) │
│ POST /mcp → authenticate() │
│ │ ↓ │
│ │ admin token? → fast path │
│ │ lw_ token? → D1 lookup │
│ │ ↓ │
│ │ rate limit check (free tier) │
│ │ BYOK key swap (byok tier) │
│ ↓ │
│ ┌─────────────────────────────────┐ │
│ │ LennyWisdomMCP (McpAgent DO) │ │
│ │ 9 tools registered via MCP SDK│ │
│ └────────────┬────────────────────┘ │
└──────────────┬┴───────────────────────┘
│
┌────────────────────┼──────────────────────┐
│ │ │
┌─────────▼──────┐ ┌──────────▼───────┐ ┌──────────▼──────┐
│ Cloudflare D1 │ │ CF Vectorize │ │ Voyage AI │
│ (11 tables) │ │ 1024-dim cosine │ │ voyage-3 │
│ structured data│ │ segment vectors │ │ query embeds │
└────────────────┘ └──────────────────┘ └─────────────────┘
Indexing pipeline (runs once per episode, cached to disk):
Transcript .md or .txt files
│
▼
Parse metadata (YAML frontmatter or guest name from filename)
│
▼
Haiku — segment into topic-coherent blocks (300–2000 tokens, 75-token overlap)
│
▼
Haiku — extract guest profile from intro (role, companies, expertise)
│
▼
Sonnet — extract per segment: frameworks, heuristics, examples,
communication_patterns, tags (55-tag PM taxonomy), key_quote
│
▼
Voyage AI — 1024-dim embedding per segment
│
▼
Save .extraction.json cache to disk (crash-safe — survives upload failures)
│
▼
Upload → D1 (structured rows) + Vectorize (vectors)______________________________________________________________________
D1架构
| 表 | 目的 | 关键列 |
|---|---|---|
episodes | 每集播客一行 | title, guest, date, topics (JSON) |
guests | 结构化的客户资料 | current_role, current_company, notable_companies, domain_expertise |
segments | 主题连贯的转录块 | topic, speakers, content, token_count |
frameworks | 命名心智模型 | name, description, source_attribution, verbatim_definition |
heuristics | 经验法则 | statement, context |
examples | 公司案例研究 | company, situation, outcome |
communication_patterns | 如何表达建议 | technique, audience, example |
tags | 每段PM分类标签 | 55个标签: pricing, growth, hiring等等。 |
quotes | 每个细分市场的关键报价 | quote, speaker |
api_tokens | 自助式API令牌 | token_hash, tier, voyage_api_key, daily_limit |
rate_limits | 每日矢量搜索计数器 | token_id, date, vector_search_count |
______________________________________________________________________
工具参考
检索工具
search_wisdom
跨所有播客智慧的语义搜索。使用Voyage AI嵌入查询,查询Vectorize,可选按PM分类标签过滤,丰富D1的结果。
| 参数 | 类型 | 必填 | 说明 | |
|---|---|---|---|---|
query | string | yes | 自然语言搜索查询 | |
tag_filter | string | no | PM分类标签(例如。 pricing, growth) | |
max_results | 整数1–20 | 否 | 结果数(默认值5) | |
format | concise | detailed | no | 响应冗长(默认 concise) |
find_frameworks
按名称或主题搜索命名框架和心智模型。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
query | string | yes | 框架名称或主题 |
max_results | 整数1–20 | 否 | 结果数(默认值5) |
find_examples
寻找真实的公司案例研究。至少一个 company 或 topic 应该提供。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
company | string | no | 公司名称(例如。 Notion, Figma) |
topic | string | 否 | 要筛选的PM主题 |
max_results | 整数1–20 | 否 | 结果数(默认值5) |
get_episode_context
检索特定剧集的所有提取数据。至少需要一个标识符。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
guest | string | no | 客人姓名 |
episode_number | integer | 否 | 剧集号 |
title | string | 否 | 剧集标题(部分匹配) |
list_guests
使用剧集计数浏览访客,可选择按PM主题过滤。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
topic | string | no | 要筛选的PM分类主题 |
max_results | 整数1–50 | 否 | 结果数 |
推理工具
这些工具从语料库中检索相关智慧,并合成结构化的响应。
coach_me
使用播客中的相关框架浏览产品决策。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
situation | string | 是 | 你的产品情况或决定(1-3句话) |
goal | string | no | 你想要达到的结果 |
role | string | no | 您的角色(例如。 PM, founder, designer) |
max_sources | 整数1–10 | 否 | 要从中提取的源段 |
challenge_decision
红队使用播客嘉宾的反驳意见做出了决定。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
decision | string | 是 | 你计划做出的决定 |
context | string | no | 上下文和推理 |
alternatives | string\[\] | 否 | 考虑了其他选项 |
max_sources | 整数1–10 | 否 | 要从中提取的源段 |
teach_framework
使用播客作为源代码深入学习PM框架。
| 参数 | 类型 | 必填 | 说明 | ||
|---|---|---|---|---|---|
framework | string | yes | 学习框架(例如。 Jobs to be Done, LNO Framework) | ||
depth | overview | detailed | masterclass | 否 | 学习深度(默认值 overview) |
sharpen_language
产品沟通的词汇和受众意识重构。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
message | string | 是的 | 你对这个概念的粗略措辞 |
audience | string | yes | 目标受众: executive, engineering, customer, peer-pm, investor |
context | string | no | 其他上下文 |
max_sources | 整数1–10 | 否 | 要从中提取的源段 |
______________________________________________________________________
设置
两个独立的组成部分: 工人 (服务于MCP端点)和 索引器 (填充数据库)。
先决条件
- 18+
- 牧马人CLI (
wrangler login) - 紫外线 用于Python依赖管理
- 具有Workers、D1和Vectorize访问权限的Cloudflare帐户
- 的API密钥 Anthropic → 安thropic(音译)或 人类中心(意译) 和 Voyage AI
1.克隆仓库
git clone https://github.com/svmanohar/lenny-wisdom-mcp.git
cd lenny-wisdom-mcp2.工人设置
cd worker
npm install创建Cloudflare资源
# Create D1 database
wrangler d1 create lenny-wisdom-db
# Create Vectorize index
wrangler vectorize create lenny-wisdom-vectors --dimensions=1024 --metric=cosine更新 wrangler.toml 随着 database_id 从D1创建输出。
运行迁移
npm run db:migrate设置秘密
wrangler secret put MCP_AUTH_TOKEN # Bearer token for MCP clients
wrangler secret put VOYAGE_API_KEY # Voyage AI key for query-time embeddings部署
npm run deploy验证: curl https://lenny-wisdom-mcp..workers.dev/health
3.索引器设置
cd indexer
uv syncPython 3.14不受支持。 这voyageai和anthropic包裹在3.14破裂。总是使用uv run--它自动选择3.13。
环境变量
export ANTHROPIC_API_KEY="sk-ant-..."
export VOYAGE_API_KEY="pa-..."
export CF_ACCOUNT_ID=""
export CF_DB_ID=""
export CF_API_TOKEN=""重要提示: CF API令牌必须在 dash.cloudflare.com/profile/api-tokes。OAuth令牌来自 wrangler login 无法通过REST API写入D1。使用“编辑Cloudflare Workers”模板并添加D1编辑+矢量化编辑权限。运行管道
# Dry run (no upload, saves cache files)
uv run python -m indexer.run --transcripts /path/to/episodes --limit 5 --dry-run
# Live run on 5 episodes
uv run python -m indexer.run --transcripts /path/to/episodes --limit 5
# Full corpus (~10-15 min with default concurrency)
uv run python -m indexer.run --transcripts /path/to/episodes
# Upload from cache only — zero API cost (reuses saved extractions + embeddings)
uv run python -m indexer.run --transcripts /path/to/episodes --upload-only
# Force re-process even if cache exists
uv run python -m indexer.run --transcripts /path/to/episodes --force缓存
每个成功处理的剧集都会保存到 .extraction.json 记录旁边的文件。在随后的运行中,从磁盘加载具有有效缓存文件的剧集,跳过所有AI API调用。这意味着:
- 崩溃恢复 --如果上传在运行过程中失败,请重新运行,只重复上传
- 增量运行 --处理新剧集,跳过缓存的剧集
--upload-only-重新部署从缓存到API成本为0美元的所有内容- 迁移便携 --JSON文件包含所有结构化数据+嵌入,独立于D1/Vectorize
管道接受两者 .md 文件(带YAML frontmatter)和 .txt 文件(原始转录文本,从文件名推断出的访客名称)。
并发调优
管道同时处理事件。通过CLI标志或环境变量进行调整:
| 标志 | 环境变量 | 默认值 | 描述 |
|---|---|---|---|
--episode-concurrency | LENNY_EPISODE_CONCURRENCY | 10 | 一次最多处理10集 |
--sonnet-concurrency | LENNY_SONNET_CONCURRENCY | 50 | 最多并发Sonnet API调用 |
--voyage-concurrency | LENNY_VOYAGE_CONCURRENCY | 5 | 最大并发Voyage API调用 |
如果您达到API费率限制,请降低 --episode-concurrency 第一。
4.配置克劳德代码
请参阅 快速入门 section--通过注册令牌 POST /register 并运行 setup_command 从回应中。无需手动配置。
5.自动同步新剧集(可选)
新剧集将发布到共享的Dropbox文件夹中。同步脚本轮询新的 .txt 文件、下载它们并运行索引管道——所有缓存的剧集都会自动跳过。
一次性Dropbox身份验证
cd indexer
DROPBOX_APP_KEY=xxx DROPBOX_APP_SECRET=xxx uv run python dropbox_auth.py这将打开您的浏览器以授权Dropbox应用程序。将代码粘贴回终端。刷新令牌保存到 ~/.lenny-wisdom/dropbox_token.json --访问令牌从此处自动刷新(刷新令牌永不过期)。
手动同步
# Check what's new (no downloads, no cost)
uv run python sync_dropbox.py --dry-run
# Sync and index new episodes (~$0.25 per new episode)
ANTHROPIC_API_KEY=xxx VOYAGE_API_KEY=xxx CF_ACCOUNT_ID=xxx CF_DB_ID=xxx CF_API_TOKEN=xxx \
uv run python sync_dropbox.py通过cron自动同步
复制 sync-cron.sh.example 并填写您的API密钥:
cp sync-cron.sh.example sync-cron.sh
# Edit sync-cron.sh with your keys — this file is gitignored然后添加到crontab:
crontab -e
# Runs every Monday at 8am. Logs to ~/.lenny-wisdom/sync.log
0 8 * * 1 /path/to/lenny-wisdom-mcp/indexer/sync-cron.shcron脚本处理PATH设置、日志轮换和自动刷新Dropbox令牌。只有当有新的剧集需要处理时,才需要花钱。
______________________________________________________________________
本地开发
cd worker
npm run dev # Starts wrangler dev server
npm test # 31 vitest tests
cd ../indexer
uv run pytest # 49 pytest tests (all API clients mocked)注: wrangler dev --local 无法模拟Vectorize或Workers AI。矢量搜索路径在本地无法工作。D1被模拟并运行良好。______________________________________________________________________
已知陷阱
- Python 3.14打破了voyageai/anthropic --始终使用
uv run - CF OAuth令牌!=API令牌 —
wrangler login令牌不能进行D1 REST写入;创建单独的API令牌 - Auth返回403,而不是401 --401触发MCP SDK OAuth流;承载令牌身份验证使用403
nodejs_compat必需的 --theagents包中需要此兼容性标志wrangler.tomlExtractedExample.company可为空 --Sonnet偶尔会为company字段返回null- Dropbox访问令牌将在4小时后过期 --同步脚本通过存储的刷新令牌自动刷新;重演
dropbox_auth.py仅当应用程序被撤销时 - API令牌显示一次 —
POST /register返回原始令牌;D1中仅存储SHA-256哈希。如果你丢了,注册一个新的 challenge_decision成本2个费率限制单位 --它每次调用运行2次并行向量搜索(反参数+上下文)
______________________________________________________________________
项目结构
lenny-wisdom-mcp/
├── worker/ # Cloudflare Worker
│ ├── src/
│ │ ├── index.ts # MCP handler + fetch handler + auth middleware
│ │ ├── db/
│ │ │ ├── queries.ts # D1 queries
│ │ │ └── schema.sql # 11-table schema
│ │ ├── lib/
│ │ │ ├── types.ts # TypeScript interfaces
│ │ │ ├── auth.ts # Token auth (SHA-256 hash, D1 lookup)
│ │ │ ├── rate-limit.ts # Daily vector search counter
│ │ │ ├── register.ts # POST /register handler
│ │ │ ├── guarded-vector-query.ts # Rate-limited vector search wrapper
│ │ │ ├── format.ts # Markdown formatters
│ │ │ └── vector-search.ts # Voyage query embedding + Vectorize search
│ │ └── tools/ # One file per MCP tool
│ ├── migrations/
│ │ └── 0001_add_auth_tables.sql
│ ├── wrangler.toml
│ └── package.json
├── indexer/ # Python indexing pipeline
│ ├── indexer/
│ │ ├── run.py # CLI entrypoint (click) with caching
│ │ ├── parse.py # Transcript parser (.md + .txt)
│ │ ├── segment.py # Haiku segmentation
│ │ ├── extract.py # Sonnet extraction
│ │ ├── embed.py # Voyage AI embeddings
│ │ ├── upload.py # D1 + Vectorize upload (retry + concurrency)
│ │ ├── guest.py # Guest profile extraction
│ │ ├── models.py # Pydantic models
│ │ └── taxonomy.py # 55 PM taxonomy tags
│ ├── sync_dropbox.py # Dropbox sync + pipeline trigger
│ ├── dropbox_auth.py # One-time OAuth setup
│ ├── sync-cron.sh.example # Cron wrapper template (copy + add keys)
│ └── pyproject.toml
└── HANDOVER.md