feat(mcp): Week 3-ready — cohort defaults, transcripts, update_profile, retire stdio bridge - #45
Merged
Merged
Conversation
…e, retire stdio bridge Tonight's Cohort 1 Week 3 session is on Connectors. The teaching artifact is the LVB MCP itself — students drop it into their Claude.ai and play. This sharpens the MCP for that demo: ## Retire stdio bridge Delete mcp-server/ entirely. The HTTP MCP at /mcp + Claude.ai's browser-OAuth integration is the standard path; stdio (npm install + env var) was a parallel surface that kept drifting from the HTTP tool names. One canonical surface, one set of names. ## Smart cohort defaults list_lessons and get_lesson previously required cohortSlug. Now both fall back to the caller's "active enrolled cohort" when omitted — new resolveActiveCohortSlug() helper picks the latest non-dropped enrollment. Demo-ergonomic: students can ask "what did we cover in weeks 1 and 2" without naming a cohort, and Claude doesn't need to chain through get_my_profile first. Tool descriptions tightened to make the chain obvious to Claude: list_lessons returns titles/dates and a hasTranscript flag; the description points at get_lesson(weekNumber=N) as the natural follow-up for deep content. ## Surface transcripts on get_lesson Previously get_lesson returned contentMarkdown only — recordingUrl and transcriptMarkdown columns existed but the tool didn't expose them. Now both are in the response. This is what makes the lesson into living context (the recording is what *actually happened* versus the lesson plan), and is what makes "summarize what I missed from week 2" land well. ## update_my_profile (new tool) Lets students fill out name/bio/location/website/github via MCP. A lot of folks haven't set names yet; this becomes a natural Week 3 "try it on your own data" moment. Email and role are read-only (email = Clerk source-of-truth; role = admin-only). Pass only the fields you want to change; empty string clears, undefined leaves alone. Returns the updated profile + which fields changed. Closes the Week 3 readiness work. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Sharpens the LVB MCP for tonight's Week 3 (Connectors) session. Students will drop the MCP into Claude.ai via the browser-OAuth flow and play with it — this PR makes that landing soft.
Changes
Retire stdio bridge (
mcp-server/directory deleted)The HTTP MCP at
/mcp+ Claude.ai's browser-OAuth integration is the standard path; stdio (npm install @learnvibe/mcp-server+ env var) was a parallel surface whose tool names had drifted from the HTTP MCP (get_lessonsvslist_lessons,read_lessonvsget_lesson, etc.). One canonical surface now, one set of names.Smart cohort defaults on
list_lessons+get_lessonNew
resolveActiveCohortSlug(db, userId)helper picks the latest non-dropped enrollment. Demo-ergonomic: a student can ask "what did we cover in weeks 1 and 2" without naming a cohort, and Claude doesn't need to chain throughget_my_profilefirst. Tool descriptions tightened to make the natural chain obvious (list → get).list_lessonsnow also returns ahasTranscriptflag per lesson so Claude can know up-front whetherget_lessonwill give it transcript content for that week.Surface transcripts on
get_lessonBug catch.
get_lessonpreviously returnedcontentMarkdownonly — therecordingUrlandtranscriptMarkdowncolumns existed (populated by thetranscribe-week.shpipeline from #20) but the tool didn't expose them. Now both are in the response. This is what makes lessons into living context (the recording is what actually happened in the room, not just the plan), and makes queries like "summarize what I missed from week 2" land well.update_my_profile(new tool)Lets students fill out name/bio/location/website/github via MCP. A lot of folks haven't set names yet; this becomes a natural Week 3 "try it on your own data" moment.
Demo questions for tonight (curated set)
These exercise the new behavior end-to-end:
Test plan
npx tsc --noEmitclean (CI runs too)enrollmentsfor cohort-1 since he's a facilitator; if so, the resolver returns null and the tool errors with a clear "pass cohortSlug explicitly" message — that's the right fallback. Worth verifying as a test of the error path.)Notes
usersrow may not have an enrollments record for cohort-1 (he's the facilitator). If the cohort-default returns null on his account, the tool prompts for cohortSlug explicitly. Easy demo flow either way: passcohortSlug: 'cohort-1'once at the start and Claude will reuse it.Setup-guide block for Week 3 lesson body
Aaron — drop this into the Week 3 lesson markdown via the admin UI. Adjust copy to taste:
🤖 Generated with Claude Code