| name | assistant-rocky-lti-assist |
| description | Coding assistant for the Rocky-LTI project โ a Canvas LTI 1.3 integration with an AI-powered educational agent. Use when working on FastAPI endpoints, MCP server components, SQLAlchemy models, Alembic migrations, Azure Functions workers, React/TypeScript frontend, or LTI/OAuth authentication flows in this codebase. |
Rocky-LTI Coding Assistant
Provides project-aware coding guidance for the Rocky-LTI Canvas integration.
Project Overview
Rocky-LTI is a Canvas LMS integration using LTI 1.3 that exposes an AI agent (Rocky) to students and instructors. The AI agent is powered via Model Context Protocol (MCP), with Canvas course data surfaced as MCP resources and tools.
Monorepo Structure
rocky-lti/
โโโ lti/
โ โโโ backend/
โ โ โโโ agent/ # FastAPI server + MCP (PRIMARY backend)
โ โ โ โโโ src/
โ โ โ โ โโโ app.py # FastAPI entrypoint
โ โ โ โ โโโ api/ # Routes, models, services
โ โ โ โ โโโ canvas_mcp/ # MCP server (servers, services, classes, models)
โ โ โ โ โโโ env.py # Pydantic settings
โ โ โ โโโ tests/ # pytest-asyncio tests
โ โ โ โโโ alembic/ # DB migrations (agent-side)
โ โ โโโ db/ # Shared SQLAlchemy models package
โ โ โ โโโ src/canvas_lti_db/
โ โ โโโ workers/ # Azure Functions (async tasks)
โ โโโ setup/ # LTI tool registration scripts
โ โโโ web/
โ โโโ lti-frontend/ # Production React 19 + TypeScript app
โ โโโ lti-test-app/ # Dev/test Vite app
โโโ packages/
โ โโโ rocky-chat/ # Shared npm chat component
โ โโโ rocky-chat-next/ # Next.js variant
โโโ infrastructure/terraform/ # Azure IaC
Tech Stack & Conventions
Python Backend
- Runtime: Python 3.13, managed exclusively with
uv
- Framework: FastAPI with async/await throughout
- ORM: SQLAlchemy (async) + asyncpg (PostgreSQL)
- MCP: FastMCP for Canvas resource/tool/prompt exposure
- Auth: python-jose for JWT; LTI 1.3 OIDC launch flow
- Observability: OpenTelemetry + Azure Monitor
- Linting/Formatting:
ruff (replaces flake8/black/isort)
Never use pip or python -m venv. Always use:
uv add <package>
uv run <script.py>
uv sync
uv run pytest
Frontend
- Framework: React 19 + TypeScript + Vite
- State: React Query for server state
- Styling: Sass
- AI Streaming: OpenAI SDK (streaming responses)
- Package manager: npm (workspace at root)
Infrastructure
- Cloud: Azure Container Apps (deployment target)
- CI/CD: GitHub Actions (
.github/workflows/)
develop push โ test environment
- Release/RC tags โ stage environment
- IaC: Terraform under
infrastructure/terraform/
- Containers: Multi-stage Docker builds
Key Patterns
FastAPI Route Structure
Routes live under lti/backend/agent/src/api/ organized by domain (e.g., lti/, oauth/, agent/, tools/). Each domain typically has:
router.py โ FastAPI router with endpoint definitions
models.py โ Pydantic request/response models
service.py โ Business logic (called from router)
db.py โ Database access layer
MCP Components (canvas_mcp/)
servers/ โ FastMCP server instances
services/ โ Canvas API data fetching
classes/ โ Domain abstractions
models/ โ Pydantic models for MCP types
Database Models
- Shared models in
lti/backend/db/src/canvas_lti_db/
- Migrations split:
lti/backend/agent/alembic/ and lti/backend/db/alembic/
- Always use async SQLAlchemy patterns
Testing
- Framework:
pytest + pytest-asyncio
- Tests in
lti/backend/agent/tests/
- Mock Canvas OAuth server (Docker) for integration tests
- Run:
uv run pytest from lti/backend/agent/
LTI 1.3 Auth Flow
- Canvas initiates OIDC login (
/lti/login)
- App redirects back with signed JWT
- Canvas POSTs launch JWT (
/lti/launch)
- App validates JWT, creates session
Environment Config
lti/backend/agent/src/env.py โ Pydantic BaseSettings
- Secrets via environment variables (Azure Key Vault in prod)
Common Tasks
Add a new API endpoint
- Add route in appropriate
api/<domain>/router.py
- Define Pydantic models in
api/<domain>/models.py
- Implement logic in
api/<domain>/service.py
- Write async tests in
tests/
Add a new MCP resource or tool
- Implement in
canvas_mcp/services/
- Register in appropriate
canvas_mcp/servers/ file
- Add Pydantic types to
canvas_mcp/models/
Add a database model
- Add SQLAlchemy model to
lti/backend/db/src/canvas_lti_db/
- Generate migration:
uv run alembic revision --autogenerate -m "description"
- Apply:
uv run alembic upgrade head
Add a frontend feature
- Work in
lti/web/lti-frontend/src/
- Use React Query for data fetching
- Shared chat UI lives in
packages/rocky-chat/
Pydantic v2
This project uses Pydantic v2. Key differences:
- Use
model_validator, field_validator (not v1 @validator)
- Use
model_dump() not .dict()
- Use
model_config = ConfigDict(...) not class Config
- Settings via
pydantic-settings BaseSettings
Code Quality Guidelines
- Prefer async/await for all I/O
- Keep routers thin โ delegate to services
- Use dependency injection (
Depends) for DB sessions, auth
- Type-annotate all function signatures
- Write tests for new endpoints and services
- Follow existing module structure โ don't create new top-level packages without discussion
- Use
ruff for linting and formatting (configured in pyproject.toml); run uv run ruff check and uv run ruff format before committing