Skip to content

Feature/mcp bearer token auth - #645

Merged
jonthorarna merged 44 commits into
mainfrom
feature/mcp-bearer-token-auth-2
Jun 1, 2026
Merged

Feature/mcp bearer token auth #645
jonthorarna merged 44 commits into
mainfrom
feature/mcp-bearer-token-auth-2

Conversation

@jonthorarna

@jonthorarna jonthorarna commented May 28, 2026

Copy link
Copy Markdown
Collaborator

Implements two-step OAuth-style handoff for MCP CLI authentication:

Web UI mints a short-lived single-use auth code
CLI exchanges that code for a long-lived bearer token (scbr_…)
MCP requests authenticate with Authorization: Bearer header
Token is hashed at rest and stored with the user's active league
Includes:

mcp_auth_code and mcp_token database tables
/api/mcp-auth/authorize and /api/mcp-auth/exchange endpoints
Bearer-token auth middleware for /api/mcp
Updated mcp-login page to mint exchange codes
Updated CLI to exchange codes and send Bearer tokens
File-only token storage (no keytar dependency)


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.

…sues

- Fix query_database table allowlist to use snake_case SQL names (was camelCase, causing broken queries)
- Export ai-schema from schema barrel index
- Replace manual JSON parsing with zValidator in mcp-auth-router
- Remove misleading description keyword validation in query-builder (was checking free-text, not SQL)
- Fix SELECT column quoting in query-builder
- Remove eslint-disable and any type in query-builder
- Extract shared fetchMatchPlayerRows helper to eliminate ~20 duplicate join chains
- Refactor getPlayerStats, getHeadToHead, getScoringStats, getStreaks, getFormGuide, getEloProgression, getTeamChemistry to use shared helper
- Use execFileSync with array args in install.ts to prevent command injection
- Remove redundant expiry check in mcp-auth middleware (already in WHERE clause)
- Combine duplicate import lines in mcp-schema
- Extract CLIENT_ONLY_TOOLS constant to replace render_chart magic string
- Remove drawProbability from ELO output (standard ELO has no draw model)
- Remove all inline comments
process.cwd() resolved to repo root, writing wrong dist path into agent config
@jonthorarna
jonthorarna force-pushed the feature/mcp-bearer-token-auth-2 branch from 8143c24 to df2146d Compare May 28, 2026 19:51
@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown

🚀 Preview Environment Deployed

Preview URL: https://scorebrawl-pr-645.coding-cowboys.workers.dev
Database: scorebrawl-db-pr-645
R2 Buckets: scorebrawl-user-assets-pr-645
Queues: scorebrawl-achievement-calculations-pr-645, scorebrawl-seed-queue-pr-645

Test Account:

  • Email: seed@scorebrawl.com
  • Password: Test.1234

This preview environment will be automatically cleaned up when the PR is closed.

@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown

🎭 E2E Test Results

20 passed | ❌ 0 failed | ⏱️ 45.0s

Metric Value
Passed 20
Failed 0
Skipped 0
Duration 45.0s

📊 View HTML Report
🎥 View Traces

Last updated: 2026-05-28T20:14:12.462Z

@agent-coding-cowboy agent-coding-cowboy Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR adds device authorization OAuth flow, MCP server with 40+ query tools, and device code schema. Three blocking issues: (1) N+1 queries throughout tool-executors.ts — multiple functions fetch all data then filter in-memory instead of using joins; (2) loose SQL value handling in query-builder.ts could allow injection; (3) no integration tests for device authorization OAuth flow. The MCP router and tool implementations are large (2656+ lines) and the N+1 patterns will cause CPU limit errors on Cloudflare Workers under load.


To re-request review after addressing feedback, push a new commit.

const extractStats = (stats: unknown) => {
if (!stats || typeof stats !== "object" || "error" in stats) {
return {
name: "Unknown",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uses in-memory filtering on full match player rows — N+1 anti-pattern. Cloudflare Workers have strict CPU limits. Should use database-level joins with WHERE clauses pushed down, not fetch-all-then-filter.

args: { leagueId: string; seasonSlug?: string; limit?: number }
) {
const { db } = ctx;
const limit = Math.min(args.limit ?? 5, 20);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same N+1 pattern: fetches all match players, then filters by two player names in memory to find shared matches.

.select({
score: seasonPlayer.score,
userName: user.name,
guestName: guest.displayName,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same anti-pattern: fetches all rows then filters in JavaScript instead of database-level filtering.

const params: (string | number)[] = [args.leagueId];

for (const w of args.where ?? []) {
const col = sanitizeIdentifier(w.column);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential SQL injection surface — values are string-concatenated rather than using typed parameter binding consistently.

@@ -0,0 +1,206 @@
import { Hono } from "hono";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security-critical OAuth device flow has no tRPC integration test coverage. Frontend page exists but backend endpoints are untested.

const env = c.env;
const userAssets = c.get("userAssets");

const activeOrganizationId = auth.session.activeOrganizationId;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this work for device auth?

@jonthorarna
jonthorarna merged commit 8ff97cf into main Jun 1, 2026
6 checks passed
@jonthorarna
jonthorarna deleted the feature/mcp-bearer-token-auth-2 branch June 1, 2026 16:25
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

🧹 Preview Environment Cleaned Up

The preview environment, database, R2 bucket, and queue have been deleted.

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.

2 participants