# Project export: Bubble

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2026
- Tagline: Block addictive in-app features at the packet-level.
- Devpost: https://devpost.com/software/bubble-5o1ztb
- GitHub: https://github.com/quinns-children/bubble
- Demo: https://youtu.be/WXeqw57qL2I
- Video: https://www.youtube.com/embed/WXeqw57qL2I?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 5 GitHub contributor(s) — Claude Opus 4.6 (16 commits), Soham Bafana (16 commits), Jonathan Lei (10 commits), kvnyng (7 commits), Arjun Melwani (1 commits)

## Devpost submission (written by the team)

No Devpost description available.

## README (from the GitHub repository)

No README available.

## Detected evidence (automated analysis)

Indexed codebase: 226 recognized source files, 1714 KB.
- CSS (language) — detected in the code
- HTML (language) — detected in the code
- Next.js (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Supabase (technology) — detected in the code
- Swift (language) — detected in the code
- TypeScript (language) — detected in the code
- AI coding agent: Claude Code — evidence: config files committed to the repository; commit authorship or trailers
- AI coding agent: Codex — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (120 of 288)

```
.env.example
.gitignore
apps/ios/.gitkeep
apps/ios/Bubble.xcodeproj/project.pbxproj
apps/ios/Bubble.xcodeproj/project.xcworkspace/contents.xcworkspacedata
apps/ios/Bubble.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
apps/ios/Bubble/Assets.xcassets/AccentColor.colorset/Contents.json
apps/ios/Bubble/Assets.xcassets/AppIcon.appiconset/Contents.json
apps/ios/Bubble/Assets.xcassets/Contents.json
apps/ios/Bubble/BubbleApp.swift
apps/ios/Bubble/BubbleConstants.swift
apps/ios/Bubble/chungus.entitlements
apps/ios/Bubble/Components/AppIconCircle.swift
apps/ios/Bubble/Components/AppOptionArcs.swift
apps/ios/Bubble/Components/BackArrowView.swift
apps/ios/Bubble/Components/BubbleButton.swift
apps/ios/Bubble/Components/HeaderBar.swift
apps/ios/Bubble/Components/HexGridOverlay.swift
apps/ios/Bubble/Components/PageIndicator.swift
apps/ios/Bubble/Components/SkyBackgroundView.swift
apps/ios/Bubble/Components/SocialMediaIcon.swift
apps/ios/Bubble/Components/SVGCache.swift
apps/ios/Bubble/Components/SVGView.swift
apps/ios/Bubble/DomainThresholdsStore.swift
apps/ios/Bubble/generate_app_icons.sh
apps/ios/Bubble/Info.plist
apps/ios/Bubble/Models/AppOptionsService.swift
apps/ios/Bubble/Models/AppStore.swift
apps/ios/Bubble/Models/AuthStore.swift
apps/ios/Bubble/Models/BlockedApp.swift
apps/ios/Bubble/Models/GridPositionStore.swift
apps/ios/Bubble/Models/HexCoordinate.swift
apps/ios/Bubble/Models/HexGridLayoutManager.swift
apps/ios/Bubble/Models/MagicSignInService.swift
apps/ios/Bubble/Models/Route.swift
apps/ios/Bubble/Models/SupabaseClient.swift
apps/ios/Bubble/Resources/app_options.json
apps/ios/Bubble/Resources/Fonts/Coolvetica Rg It.otf
apps/ios/Bubble/Resources/Fonts/Coolvetica Rg.otf
apps/ios/Bubble/Screens/BlockingOptionsScreen.swift
apps/ios/Bubble/Screens/CodeVerificationScreen.swift
apps/ios/Bubble/Screens/HomeScreen.swift
apps/ios/Bubble/Screens/LandingPage.swift
apps/ios/Bubble/Screens/MagicSignInScreen.swift
apps/ios/Bubble/Screens/SettingsScreen.swift
apps/ios/Bubble/Screens/TrafficDashboardView.swift
apps/ios/Bubble/Theme/BubbleColors.swift
apps/ios/Bubble/Theme/BubbleFonts.swift
apps/ios/Bubble/Theme/BubbleSpacing.swift
apps/ios/Bubble/TrafficMonitor.swift
apps/ios/Bubble/TrafficStats.swift
apps/ios/Bubble/VPNManager.swift
apps/ios/Bubble/Widgets/AppCluster.swift
apps/ios/Bubble/Widgets/DialSelector.swift
apps/ios/BubbleTunnel/BubbleConstants.swift
apps/ios/BubbleTunnel/chungusTunnel.entitlements
apps/ios/BubbleTunnel/Info.plist
apps/ios/BubbleTunnel/PacketTunnelProvider.swift
apps/ios/BubbleTunnel/ReelsBlockFilter.swift
apps/ios/BubbleTunnel/SOCKSProxyServer.swift
apps/ios/BubbleTunnel/TrafficStats.swift
apps/ios/BubbleTunnel/TunnelLogger.swift
apps/ios/package.json
apps/ios/project.yml
apps/ios/Secrets.xcconfig.example
apps/web/app/api/analytics/app/[slug]/route.ts
apps/web/app/api/analytics/classify/route.ts
apps/web/app/api/analytics/details/route.ts
apps/web/app/api/analytics/generate-insight/route.ts
apps/web/app/api/analytics/insights/route.ts
apps/web/app/api/analytics/rollup/route.ts
apps/web/app/api/analytics/summary/route.ts
apps/web/app/api/health/route.ts
apps/web/app/auth/callback/route.ts
apps/web/app/dashboard/[app]/client.tsx
apps/web/app/dashboard/[app]/page.tsx
apps/web/app/dashboard/client.tsx
apps/web/app/dashboard/page.tsx
apps/web/app/layout.tsx
apps/web/app/login/actions.ts
apps/web/app/login/page.tsx
apps/web/app/page.tsx
apps/web/app/sign-out-button.tsx
apps/web/components/dashboard/BandwidthCard.tsx
apps/web/components/dashboard/BubbleCluster.tsx
apps/web/components/dashboard/ContentTypeChart.tsx
apps/web/components/dashboard/DateRangeSelector.tsx
apps/web/components/dashboard/HeaderBar.tsx
apps/web/components/dashboard/HeatmapGrid.tsx
apps/web/components/dashboard/InsightCard.tsx
apps/web/components/dashboard/MethodBreakdown.tsx
apps/web/components/dashboard/SkyBackground.tsx
apps/web/components/dashboard/StatCard.tsx
apps/web/components/dashboard/TopDomainsTable.tsx
apps/web/components/dashboard/UsageChart.tsx
apps/web/eslint.config.mjs
apps/web/lib/analytics.ts
apps/web/lib/app-meta.ts
apps/web/lib/format.ts
apps/web/lib/supabase/client.ts
apps/web/lib/supabase/proxy.ts
apps/web/lib/supabase/server.ts
apps/web/lib/theme.ts
apps/web/middleware.ts
apps/web/next-env.d.ts
apps/web/next.config.ts
apps/web/package.json
apps/web/public/fonts/CoolveticaRg.otf
apps/web/public/fonts/CoolveticaRgIt.otf
apps/web/tsconfig.json
apps/web/tsconfig.tsbuildinfo
package.json
packages/assets/package.json
packages/assets/Package.swift
packages/assets/src/icons/.gitkeep
packages/assets/src/images/.gitkeep
packages/assets/src/index.ts
packages/canvas-mcp/.claude/skills/canvas-morning-check/SKILL.md
packages/canvas-mcp/.claude/skills/canvas-week-plan/SKILL.md
packages/canvas-mcp/.dockerignore
[168 more files omitted for size]
```

### Dependencies

- apps/ios/package.json: @bubble/assets@workspace:*
- apps/web/package.json: @bubble/assets@workspace:*, @eslint/eslintrc@^3, @supabase/ssr@^0.8, @supabase/supabase-js@^2, @types/node@^22, @types/react@^19, @types/react-dom@^19, eslint@^9, eslint-config-next@^15, framer-motion@^12.34.0, next@^15, react@^19, react-dom@^19, recharts@^3.7.0, typescript@^5
- package.json: turbo@^2
- packages/canvas-mcp/package.json: @types/node@^20.10.0, node-fetch@^3.3.2, ts-node@^10.9.2, tsx@^4.20.6, typescript@^5.3.3
- packages/canvas-mcp/pyproject.toml: black@>=23.0.0, fastmcp@>=2.14.0, httpx@>=0.28.1, mypy@>=1.5.0, pydantic@>=2.12.0, pytest@>=7.0.0, pytest-asyncio@>=0.21.0, python-dateutil@>=2.8.0, python-dotenv@>=1.0.0, requests@>=2.32.0, ruff@>=0.1.0
- packages/canvas-mcp/smithery-wrapper/package.json: @modelcontextprotocol/sdk@^1.25.1, @smithery/cli@^3.7.0, @types/node@^20.10.0, typescript@^5.3.3, zod@^3.23.8
- packages/mcp-server/package.json: @supabase/supabase-js@^2, @types/node@^22, fastmcp@^3, tsx@^4, typescript@^5, zod@^3.25
- quinn/requirements.txt: httpx@>=0.27.0, mitmproxy@>=10.0.0

### Recent commits (newest first)

- Merge feat/domain-classifier-dashboard: add domain classifier dashboard
- Add domain classifier dashboard with traffic analytics
- Re-add Arjun's iOS updates (chungus) under apps/ios/
- Revert "Saving before end of hackathon"
- Saving before end of hackathon
- Merge pull request #4 from quinns-children/feat/flow-logger-analytics
- Merge main: use vencode_tag blocking with analytics recording
- Fix React shorthand/non-shorthand CSS property conflict
- instagram reels update
- Working messages
- Fix get_course_code crash when course_id is int
- Fix canvas-mcp HTTP transport: pass host/port to constructor
- Merge branch 'main' of https://github.com/quinns-children/bubble
- block kalshi trades
- Merge pull request #3 from quinns-children/feat/canvas-mcp
- Merge branch 'main' of https://github.com/quinns-children/bubble
- block youtube shorts
- Add Canvas MCP server for LMS integration
- Bind to 0.0.0.0 for container deployment, add start script
- Read PORT env var for Railway compatibility

## Key source files (fetched from GitHub, selected and truncated for size)

### packages/canvas-mcp/TODO.md

```markdown
# Canvas MCP TODO

## High Priority

<!-- Add high priority items here -->

---

## Medium Priority

<!-- Add future items here -->

---

## Low Priority

<!-- Add future items here -->

---

## Completed

- **2026-01-25**: Added `update_assignment` tool - PUT /api/v1/courses/:course_id/assignments/:id
  - Parameters: course_identifier, assignment_id, name, description, submission_types, due_at, unlock_at, lock_at, points_possible, grading_type, published, assignment_group_id, peer_reviews, automatic_peer_reviews, allowed_extensions

```

### packages/canvas-mcp/SECURITY.md

```markdown
# Security Policy

## Reporting Security Vulnerabilities

We take the security of Canvas MCP seriously. If you discover a security vulnerability, please follow these guidelines:

### Reporting Process

**DO NOT** open a public GitHub issue for security vulnerabilities. Instead:

1. **Email**: Send details to the maintainer at the email listed in the repository
2. **GitHub Security Advisory**: Use [GitHub's Security Advisory feature](https://github.com/vishalsachdev/canvas-mcp/security/advisories/new) (preferred)

### What to Include

Please provide:
- Description of the vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if available)

### Response Timeline

- **Initial Response**: Within 48 hours
- **Status Update**: Within 7 days
- **Fix Timeline**: Varies based on severity
  - Critical: 1-7 days
  - High: 7-14 days
  - Medium: 14-30 days
  - Low: Best effort

---

## Security Best Practices for Users

### API Token Security

**Critical: Your Canvas API token has full access to your Canvas account**

1. **Never commit tokens to version control**
   - Always use `.env` file for token storage
   - Verify `.env` is in `.gitignore`
   - Use the provided `env.template` as a starting point

2. **Token Storage**
   - Store tokens in `.env` file with restricted permissions (`chmod 600 .env`)
   - Never share tokens via email, chat, or screenshots
   - Use environment-specific tokens (dev vs. production)

3. **Token Rotation**
   - Rotate tokens periodically (recommended: every 90 days)
   - Immediately rotate if token may have been exposed
   - Revoke tokens when no longer needed

4. **Access Scope**
   - Canvas tokens have full account access - there is no scope limitation
   - Consider using a dedicated Canvas account with limited permissions for MCP operations
   - Never use admin account tokens unless absolutely necessary

### Code Execution Security

The Canvas MCP server includes code execution capabilities (`execute_typescript` tool) for advanced operations.

**Important Security Considerations:**

1. **Review Generated Code**
   - Always review TypeScript code before execution
   - Understand what the code will do with your Canvas data
   - Be cautious of code that modifies grades, enrollments, or course settings

2. **Execution Environment**
   - Code executes locally in isolated temporary files
   - Temporary files are automatically deleted after execution
   - Environment variables are isolated (your Canvas token is still accessible)

3. **Timeout Protection**
   - Code execution has a 120-second timeout by default
   - Long-running operations are automatically terminated

4. **What Code Execution Can Access**
   - Your Canvas API token (via environment variables)
   - Your Canvas instance (via API calls)
   - Local filesystem (temporary directory only)
   - Network (can make HTTP requests)

### Data Privacy & FERPA Compliance

Canvas MCP includes built-in privacy features for educational data:

1. **Data Anonymization**
 
[truncated — 4568 more characters]
```

### package.json

```
{
  "name": "bubble",
  "private": true,
  "packageManager": "pnpm@9.15.4",
  "scripts": {
    "build": "turbo run build",
    "dev": "turbo run dev",
    "lint": "turbo run lint",
    "typecheck": "turbo run typecheck",
    "clean": "turbo run clean"
  },
  "devDependencies": {
    "turbo": "^2"
  }
}

```

### quinn/requirements.txt

```
mitmproxy>=10.0.0
httpx>=0.27.0

```

### packages/assets/package.json

```
{
  "name": "@bubble/assets",
  "version": "0.0.0",
  "private": true,
  "exports": {
    "./*": "./src/*"
  },
  "scripts": {
    "build": "echo 'No build step needed for assets'",
    "clean": "echo 'Nothing to clean'"
  }
}

```

### apps/ios/package.json

```
{
  "name": "@bubble/ios",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "build": "echo 'iOS build — use Xcode or xcodebuild'",
    "lint": "echo 'iOS lint — use SwiftLint'",
    "clean": "rm -rf build DerivedData"
  },
  "dependencies": {
    "@bubble/assets": "workspace:*"
  }
}

```

### packages/canvas-mcp/package.json

```
{
  "name": "canvas-mcp-code-api",
  "version": "1.0.6",
  "description": "TypeScript code execution API for Canvas MCP",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "exec": "node --loader ts-node/esm"
  },
  "dependencies": {
    "node-fetch": "^3.3.2"
  },
  "devDependencies": {
    "@types/node": "^20.10.0",
    "ts-node": "^10.9.2",
    "tsx": "^4.20.6",
    "typescript": "^5.3.3"
  }
}

```

### packages/mcp-server/package.json

```
{
  "name": "@bubble/mcp-server",
  "version": "0.0.0",
  "private": true,
  "type": "module",
  "main": "./dist/index.js",
  "scripts": {
    "build": "tsc",
    "dev": "node --env-file=../../.env --import=tsx src/index.ts",
    "typecheck": "tsc --noEmit",
    "start": "node dist/index.js",
    "clean": "rm -rf dist .turbo node_modules"
  },
  "dependencies": {
    "fastmcp": "^3",
    "@supabase/supabase-js": "^2",
    "zod": "^3.25"
  },
  "devDependencies": {
    "@types/node": "^22",
    "tsx": "^4",
    "typescript": "^5"
  }
}

```

### apps/web/package.json

```
{
  "name": "web",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "typecheck": "tsc --noEmit",
    "clean": "rm -rf .next .turbo node_modules"
  },
  "dependencies": {
    "@bubble/assets": "workspace:*",
    "@supabase/ssr": "^0.8",
    "@supabase/supabase-js": "^2",
    "framer-motion": "^12.34.0",
    "next": "^15",
    "react": "^19",
    "react-dom": "^19",
    "recharts": "^3.7.0"
  },
  "devDependencies": {
    "@eslint/eslintrc": "^3",
    "@types/node": "^22",
    "@types/react": "^19",
    "@types/react-dom": "^19",
    "eslint": "^9",
    "eslint-config-next": "^15",
    "typescript": "^5"
  }
}

```

### packages/canvas-mcp/Dockerfile

```
# Use Python 3.12 slim image for smaller size
FROM python:3.12-slim

# Set working directory
WORKDIR /app

# Install uv package manager for faster dependency installation
RUN pip install --no-cache-dir uv

# Copy project files
COPY pyproject.toml ./
COPY LICENSE ./
COPY README.md ./
COPY env.template ./
COPY src/ ./src/

# Install dependencies using uv
RUN uv pip install --system --no-cache -e .

# Create non-root user for security
RUN adduser --disabled-password --gecos '' mcp && \
    chown -R mcp:mcp /app

# Set environment variables (users must provide CANVAS_API_TOKEN and CANVAS_API_URL at runtime)
# Example: docker run -e CANVAS_API_TOKEN=xyz -e CANVAS_API_URL=https://... canvas-mcp
ENV MCP_SERVER_NAME="canvas-mcp" \
    MCP_TRANSPORT="http" \
    ENABLE_DATA_ANONYMIZATION="false" \
    ANONYMIZATION_DEBUG="false"

# Switch to non-root user
USER mcp

# Health check to verify installation
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD python -c "import canvas_mcp; print('OK')" || exit 1

# Run the MCP server
CMD ["canvas-mcp-server"]

```

[216 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]