Skip to content

feat: CLI, MCP server, Stripe Connect — agent-first course creation platform - #30

Merged
willwearing merged 10 commits into
mainfrom
feat/cli-agent-platform
Mar 22, 2026
Merged

feat: CLI, MCP server, Stripe Connect — agent-first course creation platform#30
willwearing merged 10 commits into
mainfrom
feat/cli-agent-platform

Conversation

@willwearing

Copy link
Copy Markdown
Owner

Summary

Complete implementation of the Graspful CLI and MCP server — making course creation a callable primitive for AI agents.

What's new

Packages

  • @graspful/cli — 9 commands: validate, import, publish, review, create course/brand, fill concept, describe, login
  • @graspful/mcp — MCP server with 10 agent-optimized tools
  • @graspful/shared — Zod schemas (course, academy, brand), quality gate interfaces

Backend

  • API key authentication (gsk_ prefix, SHA-256 hashed, org-scoped)
  • POST /courses/review — 10 mechanical quality checks
  • POST /courses/:id/publish — review gate + flip isPublished
  • Import --publish flag runs review gate inline
  • Stripe Connect: 70/30 revenue share, RevenueEvent tracking, onboarding flow
  • ConnectService with checkout routing, webhook handlers, payout dashboard endpoints

Frontend

  • /agents marketing page with MCP tools, workflow, pricing
  • llms.txt with behavioral instructions for AI agents
  • Fixed robots.txt — removed AI crawler blocks

Docs & Content

  • Split adding-a-course.md → creation workflow + course-review-gate.md
  • 5 brand YAML files converted from hardcoded configs
  • Full README rewrite for agent-first positioning

CI

  • GitHub Action to publish all 3 packages to npm (tag-triggered or manual dispatch)

Security fixes (from code review)

  • Webhook error responses no longer leak internal details
  • Revenue split uses single constant (no divergence)
  • CLI credentials written with 0o600 permissions
  • API key timing oracle eliminated
  • Input validation DTOs on all new endpoints
  • Stripe priceId format validation

Tests

  • 528 existing backend tests pass
  • 25 new Playwright e2e tests: API keys, billing, brands, course import, agents page

Test plan

  • bun run build — all packages compile
  • bun run test — 528 backend tests pass
  • CLI tested against real course YAML (validate, review, describe)
  • Frontend builds cleanly (npx next build)
  • Playwright tests recognized (25 tests, TypeScript compiles)
  • Manually verify npx @graspful/cli --help after npm publish
  • Manually verify MCP server connects in Claude Code
  • Set NPM_TOKEN secret in repo settings before first publish

🤖 Generated with Claude Code

willwearing and others added 10 commits March 21, 2026 23:54
…nnect

Backend changes for CLI/agent platform:

- ApiKey model + CRUD endpoints (gsk_ prefixed, SHA-256 hashed)
- ApiKeyGuard for CLI authentication (Bearer gsk_*)
- ReviewService with 10 mechanical quality checks (3 fully implemented, 7 stubs)
- POST /orgs/:orgId/courses/review — run quality checks on YAML
- POST /orgs/:orgId/courses/:courseId/publish — review + flip isPublished
- Updated import endpoint to accept publish flag with inline review gate
- Stripe Connect: stripeConnectAccountId on Organization model
- ConnectService: onboarding, revenue tracking (70/30 split), publish gating
- RevenueEvent model for marketplace revenue tracking
- Updated webhook handler for account.updated and invoice.paid

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CLI package with commander.js:
- graspful validate — offline schema + DAG validation (auto-detects course/brand/academy)
- graspful import — push YAML to API with --publish flag
- graspful publish — flip isPublished via API
- graspful review — 10 mechanical quality checks offline
- graspful create course --scaffold-only — generate course skeleton
- graspful create brand --niche — generate brand YAML with theme presets
- graspful fill concept — add KP/problem stubs to a concept
- graspful describe — course stats (concepts, KPs, problems, graph depth)
- graspful login — token-based auth, saves to ~/.graspful/credentials.json
- --format json on all commands for agent composability
- Auth: GRASPFUL_API_KEY env var (agents) or stored JWT (humans)
- API client with get/post/patch methods

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Split docs/adding-a-course.md: moved Step 8 (review-agent pass) and
  Step 11 (content quality rules) into docs/course-review-gate.md
- Added docs/cli-agent-strategy.md (full CLI/agent platform plan)
- Created content/brands/ with 5 brand YAML files converted from
  hardcoded configs: firefighter, electrician, javascript, posthog, graspful
- Added content/brands/README.md with format docs and theme presets
- Updated adding-a-course.md with CLI references and publishing section

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Created llms.txt with behavioral instructions for AI agents
- Fixed robots.txt — removed AI crawler blocks, allow public pages
- Created /agents marketing page with MCP tools, workflow, pricing
- Added /agents to sitemap

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MCP server wrapping CLI commands for AI agent consumption:
- graspful_scaffold_course, graspful_fill_concept (offline creation)
- graspful_validate, graspful_review_course, graspful_describe_course (offline checks)
- graspful_create_brand (offline generation)
- graspful_import_course, graspful_publish_course, graspful_import_brand (API calls)
- graspful_list_courses (API call)
- Tool descriptions optimized as standalone documentation
- Uses @modelcontextprotocol/sdk with JSON Schema inputs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Critical fixes:
- Webhook error response no longer leaks internal error details
- Revenue split uses single PLATFORM_FEE_PERCENT constant (no divergence)
- CLI credentials file written with 0o600 permissions (owner-only)

High fixes:
- API key lastUsedAt update is truly fire-and-forget (no timing oracle)
- ApiKeyGuard throws UnauthorizedException instead of returning false
- Added CreateApiKeyDto with validation (@IsString, @maxlength)
- Added ImportCourseDto/ReviewCourseDto with 1MB size limit on YAML
- Validate priceId format before sending to Stripe
- Replace session.url! with explicit null checks

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… agents page

25 new e2e tests:
- API key management: CRUD, auth with gsk_ key, invalid key 401
- Course import: draft import, review checks, publish gate, error handling
- Billing: subscription status, Connect status, revenue for new orgs
- Brands: list, get by slug/domain, 404 cases
- Agents page: hero, MCP tools, supported agents, pricing, CTAs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Full README covering: what Graspful is, how it works (two-YAML workflow),
quick start, tech stack, architecture, CLI commands, MCP server setup,
development instructions, 70/30 revenue model, and documentation links.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ful/shared to npm

Workflow triggers:
- Push v* tag: publishes all three packages
- Push cli@*, mcp@*, shared@* tags: publishes specific package
- Manual dispatch with package selector and dry-run option

Uses bun publish which resolves workspace:* to actual versions.
Publishes shared first (cli and mcp depend on it).
Requires NPM_TOKEN secret.

Also: make @graspful/shared publishable (remove private: true)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Mar 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
graspful Error Error Mar 22, 2026 6:26am
web Ready Ready Preview, Comment Mar 22, 2026 6:26am

@willwearing
willwearing merged commit 64b0132 into main Mar 22, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant