Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

well-known.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

well-known.tsBlame119 lines · 2 contributors
369ad65ccanty labs1/**
2 * OAuth / agent discovery metadata under `/.well-known/*`.
3 *
4 * These endpoints let an AI agent (claude.ai remote connectors, Cursor,
5 * Copilot, etc.) auto-discover how to authenticate against Gluecron without
6 * any manual configuration. They advertise ONLY endpoints that actually
7 * exist today:
8 *
9 * - RFC 8414 Authorization Server Metadata
10 * GET /.well-known/oauth-authorization-server
11 * - RFC 9728 Protected Resource Metadata
12 * GET /.well-known/oauth-protected-resource
13 * GET /.well-known/oauth-protected-resource/mcp (resource-specific)
14 *
4c27627ccanty labs15 * `registration_endpoint` (RFC 7591 dynamic client registration) is now live
16 * at POST /oauth/register and advertised below. `introspection_endpoint`
17 * (RFC 7662) is still omitted until it ships — advertising a 404 would break
18 * clients that probe it. Add it here in the same change that builds it.
369ad65ccanty labs19 *
20 * Pure/read-only, no auth, no DB. Safe to serve to anyone.
21 */
22
23import { Hono } from "hono";
8ed88f2ccantynz-alt24import type { Context } from "hono";
369ad65ccanty labs25import { config } from "../lib/config";
26import { SUPPORTED_SCOPES } from "../lib/oauth";
27
28const wellKnown = new Hono();
29
30/** Absolute URL on this deployment's public origin (no trailing slash). */
31function base(): string {
32 // config.appBaseUrl already strips a trailing slash.
33 return config.appBaseUrl;
34}
35
36/**
37 * RFC 8414 — OAuth 2.0 Authorization Server Metadata.
38 * The document a client reads to learn where /authorize and /token live,
39 * which PKCE methods are supported, and which scopes exist.
40 */
41wellKnown.get("/.well-known/oauth-authorization-server", (c) => {
42 const b = base();
43 return c.json(
44 {
45 issuer: b,
46 authorization_endpoint: `${b}/oauth/authorize`,
47 token_endpoint: `${b}/oauth/token`,
48 revocation_endpoint: `${b}/oauth/revoke`,
4c27627ccanty labs49 // RFC 7591 dynamic client registration — lets agents self-register.
50 registration_endpoint: `${b}/oauth/register`,
369ad65ccanty labs51 scopes_supported: SUPPORTED_SCOPES,
52 response_types_supported: ["code"],
53 grant_types_supported: ["authorization_code", "refresh_token"],
54 // PKCE (RFC 7636) — the provider verifies S256 and plain.
55 code_challenge_methods_supported: ["S256", "plain"],
56 token_endpoint_auth_methods_supported: [
57 "client_secret_basic",
58 "client_secret_post",
59 "none", // public clients (PKCE, no secret)
60 ],
61 revocation_endpoint_auth_methods_supported: [
62 "client_secret_basic",
63 "client_secret_post",
64 "none",
65 ],
66 service_documentation: `${b}/api/docs`,
67 },
68 200,
69 { "cache-control": "public, max-age=3600" }
70 );
71});
72
73/**
74 * RFC 9728 — OAuth 2.0 Protected Resource Metadata.
75 *
76 * Served both at the root path and at `/mcp` (resource-specific). A remote
77 * MCP connector reads this to learn which authorization server guards the
78 * `/mcp` resource and which scopes it accepts.
79 */
8ed88f2ccantynz-alt80function protectedResourceDoc(c: Context) {
369ad65ccanty labs81 const b = base();
82 return c.json(
83 {
84 resource: `${b}/mcp`,
85 authorization_servers: [b],
86 scopes_supported: SUPPORTED_SCOPES,
87 bearer_methods_supported: ["header"],
88 resource_documentation: `${b}/api/docs`,
89 },
90 200,
91 { "cache-control": "public, max-age=3600" }
92 );
93}
94
95wellKnown.get("/.well-known/oauth-protected-resource", protectedResourceDoc);
96// Resource-specific form (RFC 9728 §3.1) — some clients append the resource
97// path when the WWW-Authenticate challenge points at `<origin>/mcp`.
98wellKnown.get("/.well-known/oauth-protected-resource/mcp", protectedResourceDoc);
99
cb65da8ccanty labs100/**
101 * Official MCP Registry domain verification (HTTP method).
102 *
103 * registry.modelcontextprotocol.io verifies control of the `com.gluecron`
104 * namespace by fetching this file and checking the signature made with the
105 * matching PRIVATE key during `mcp-publisher login http`. The value below is
106 * the PUBLIC half of the publishing keypair — safe to serve to anyone.
107 * Override via MCP_REGISTRY_AUTH env when the keypair is rotated.
108 * Registry entry lives in ./server.json at the repo root.
109 */
110wellKnown.get("/.well-known/mcp-registry-auth", (c) =>
111 c.text(
112 process.env.MCP_REGISTRY_AUTH ||
113 "v=MCPv1; k=ed25519; p=7a15jFzQv2INI1Lc9Yg8+v2Dv3QNK+r83ZfpotOOOdw=",
114 200,
115 { "cache-control": "public, max-age=300" }
116 )
117);
118
369ad65ccanty labs119export default wellKnown;