Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
Commit58bb447

fix(mcp): resolve repo owner/name case-insensitively

fix(mcp): resolve repo owner/name case-insensitively

The owner wants repo slugs treated as lowercase "to prevent confusion".
resolveReadableRepo matched owner + name with case-sensitive eq(), so a
caller asking for ccantynz/vapron got "repo not found" when the repo is
stored ccantynz/Vapron. Match with lower(...) = lower(...) so vapron,
Vapron, and VAPRON all resolve to the same repo (GitHub-style).

This is the MCP read path only; a platform-wide case-insensitive sweep
+ lowercase-on-create normalization is planned separately.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ccantynz-alt committed on July 24, 2026Parent: 74202f0
1 file changed+9158bb447f5909ad8873f3314a9e94adb81af38258
1 changed file+9−1
Modifiedsrc/lib/mcp-tools.ts+9−1View fileUnifiedSplit
125125 repo: string,
126126 ctx: McpContext
127127): Promise<{ id: string; isPrivate: boolean }> {
128 // Case-insensitive owner/repo match — GitHub-style. Repo slugs are meant to
129 // read as lowercase, but a caller typing "Vapron", "vapron", or "VAPRON"
130 // must all resolve to the same repo instead of a confusing "not found".
128131 const [r] = await db
129132 .select({ id: repositories.id, isPrivate: repositories.isPrivate })
130133 .from(repositories)
131134 .innerJoin(users, eq(repositories.ownerId, users.id))
132 .where(and(eq(users.username, owner), eq(repositories.name, repo)))
135 .where(
136 and(
137 drizzleSql`lower(${users.username}) = lower(${owner})`,
138 drizzleSql`lower(${repositories.name}) = lower(${repo})`
139 )
140 )
133141 .limit(1);
134142 if (!r) throw new McpError(ERR_METHOD_NOT_FOUND, `repo not found: ${owner}/${repo}`);
135143 if (r.isPrivate) {
136144