Skip to main content
This page is an agent implementation spec, not the human Quickstart. Prefer @davenai/mcp daven_guidelines (topic=edu_app; use topic=submission for student work → LMS). Do not invent shapes. Dump: llms.txt · Proxy: openapi.yaml · LMS: lms-openapi.yaml · activity-submission.schema.json When hosting an existing product, keep the invariants in Host an existing app. Do not restyle the lesson UI as Hub or Vibe.

MUST

  1. Host an HTTPS (or local) web app. Hub Start opens it in a new tab.
  2. In TypeScript apps, prefer @davenai/sdk/edu. It reads the launch session and proxy and removes them from the address bar.
  3. Call Daven only through the SDK or against the {proxy} base.
  4. A raw fetch fallback must send Authorization: Bearer {session} and X-Edu-Session: {session} on every request.
  5. Parse the envelope: status === "success" | "error".
  6. Never put API keys / MCP secrets in the frontend.
  7. Use the SDK’s trusted proxy defaults. If you need a custom proxy, add it only through static app configuration in additionalTrustedProxyUrls; never copy the launch query into that allowlist.
  8. When shouldRelaunchEducationApp(error) is true, preserve saved work and tell the user to reopen the activity from Hub.

MUST NOT

  1. Call daven.ai / app.daven.ai directly from the browser.
  2. Require extra OAuth popups for the default Edu flow.
  3. Auto-overwrite student-authored text with AI output.

Defaults

Session v2 (deterministic)

New sessions are signed HS256 JWTs with version: 2, purpose, and actorId; sub === actorId. actor.id is the authenticated Hub profile. studentId is the student whose work is in context. Do not trust a decoded JWT in the app; use GET /api/session/context. Use the student/teacher actorId from context as the stable app identity; never match by name or student code. Only teacher_manage may call GET /api/session/roster, whose response excludes email, access codes, balances, and payer data. When the app provides a teacher-specific workspace, enable supportsTeacherManage in the Master-approved catalog so the Hub shows this launch. The server normalizes signed v1 JWTs during migration but rejects unsigned base64 sessions.

Submission v2 (deterministic)

  • Final submission POST accepts only a student_activity Edu session.
  • externalArtifactId is optional and contains 1–128 [A-Za-z0-9._:-] characters.
  • Omitting it uses __default__, preserving the legacy behavior of updating one default row.
  • Identity is (activityId, studentId, appSlug, externalArtifactId). Stable IDs support multiple artifacts and per-artifact resubmission.
  • Submission URLs must be permanent public HTTPS. Reject localhost, IP literals, internal hostnames, and credential-bearing URLs.
  • Submission list GET is not an education-app session API. It requires the normal Hub teacher bearer and ownership of the activity’s classroom. Never list anonymously.

Endpoints (complete)

Use the launch {proxy} as the base for proxy paths below. Student submission uses the Edu API base that the SDK derives from {proxy}. Follow the OpenAPI and submission schema for request bodies. AI body fields are model-specific (additionalProperties in OpenAPI).

Canonical SDK client

Use @davenai/sdk/server with explicit session, proxy, and expectedAppSlug in a Node BFF. The SDK stops when expectedAppSlug does not match the verified session context. Implement the raw fetch fallback in llms.txt only when the SDK is unavailable.

Acceptance (binary)

Report “integration complete” only when all are true:
  • daven.billing.getAccount() succeeds
  • Without session headers → 401
  • Each SDK AI user action creates an operation ID and reuses it only when retrying the same request
  • Final submit runs only for student_activity and reuses a stable externalArtifactId per artifact
  • Session expiry/401 shows relaunch UI without discarding saved work
  • DevTools Network shows Edu proxy host only
  • Core flow works as a top-level page (new tab)
  • Catalog Approve only after student Start returns one text and one image. Pitfalls: hosted-app

Reference paths

  • App: dv_mcp/apps/sihwa_project
  • Proxy: dv-edu/apps/api/src/mcp-proxy/mcp-proxy.controller.ts