@miadi/connector 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/oauth.d.ts CHANGED
@@ -60,9 +60,21 @@ export declare const emptyOAuthState: () => OAuthState;
60
60
  export declare class MiadiOAuthProvider implements OAuthServerProvider {
61
61
  private readonly state;
62
62
  private readonly identify;
63
+ /**
64
+ * The issuer as the metadata states it. It goes back on every authorization
65
+ * response as `iss` (RFC 9207), which ChatGPT requires to use its stable
66
+ * callback URL.
67
+ */
68
+ private readonly issuer?;
63
69
  private readonly confirmPath;
64
70
  private readonly direct;
65
- constructor(state: JsonFile<OAuthState>, identify: Identify, confirmPath?: string);
71
+ constructor(state: JsonFile<OAuthState>, identify: Identify,
72
+ /**
73
+ * The issuer as the metadata states it. It goes back on every authorization
74
+ * response as `iss` (RFC 9207), which ChatGPT requires to use its stable
75
+ * callback URL.
76
+ */
77
+ issuer?: string | undefined, confirmPath?: string);
66
78
  get clientsStore(): OAuthRegisteredClientsStore;
67
79
  authorize(client: OAuthClientInformationFull, params: AuthorizationParams, res: Response): Promise<void>;
68
80
  /** POST from the sign-in page: the person's token, or a refusal. */
package/dist/oauth.js CHANGED
@@ -14,11 +14,19 @@ const now = () => Math.floor(Date.now() / 1000);
14
14
  export class MiadiOAuthProvider {
15
15
  state;
16
16
  identify;
17
+ issuer;
17
18
  confirmPath;
18
19
  direct = new Map();
19
- constructor(state, identify, confirmPath = "/authorize/confirm") {
20
+ constructor(state, identify,
21
+ /**
22
+ * The issuer as the metadata states it. It goes back on every authorization
23
+ * response as `iss` (RFC 9207), which ChatGPT requires to use its stable
24
+ * callback URL.
25
+ */
26
+ issuer, confirmPath = "/authorize/confirm") {
20
27
  this.state = state;
21
28
  this.identify = identify;
29
+ this.issuer = issuer;
22
30
  this.confirmPath = confirmPath;
23
31
  }
24
32
  get clientsStore() {
@@ -68,6 +76,8 @@ export class MiadiOAuthProvider {
68
76
  const redirect = new URL(pending.params.redirectUri);
69
77
  if (pending.params.state)
70
78
  redirect.searchParams.set("state", pending.params.state);
79
+ if (this.issuer)
80
+ redirect.searchParams.set("iss", this.issuer);
71
81
  if (body.decision === "deny") {
72
82
  this.state.update((st) => delete st.pending[body.request_id]);
73
83
  redirect.searchParams.set("error", "access_denied");
package/dist/server.js CHANGED
@@ -12,7 +12,7 @@
12
12
  import express from "express";
13
13
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
14
14
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
15
- import { mcpAuthRouter, getOAuthProtectedResourceMetadataUrl } from "@modelcontextprotocol/sdk/server/auth/router.js";
15
+ import { mcpAuthRouter, createOAuthMetadata, getOAuthProtectedResourceMetadataUrl } from "@modelcontextprotocol/sdk/server/auth/router.js";
16
16
  import { requireBearerAuth } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
17
17
  import { MiadiOAuthProvider, SCOPES, emptyOAuthState } from "./oauth.js";
18
18
  import { registerApprovalRoutes } from "./approve.js";
@@ -26,7 +26,9 @@ export function createConnectorApp(config, deps) {
26
26
  const paths = statePaths(config.stateDir);
27
27
  const oauthState = new JsonFile(paths.oauth, emptyOAuthState);
28
28
  const ledger = new Ledger(paths.ledger);
29
- const provider = new MiadiOAuthProvider(oauthState, deps.identify);
29
+ // The issuer string exactly as the metadata states it (URL.href, so with its trailing slash).
30
+ const issuer = new URL(config.publicUrl).href;
31
+ const provider = new MiadiOAuthProvider(oauthState, deps.identify, issuer);
30
32
  const miadi = new MiadiClient(config.miadiUrl, deps.fetchImpl);
31
33
  const reviews = new ReviewClient(config.reviewUrl, config.reviewToken, deps.fetchImpl);
32
34
  const publicUrl = new URL(config.publicUrl);
@@ -38,6 +40,21 @@ export function createConnectorApp(config, deps) {
38
40
  app.get("/health", (_req, res) => {
39
41
  res.json({ ok: true, service: "@miadi/connector", version: VERSION });
40
42
  });
43
+ // The SDK's metadata, plus RFC 9207: authorization responses carry `iss`.
44
+ // Served before the SDK router so this document is the one clients read.
45
+ const asMetadata = {
46
+ ...createOAuthMetadata({
47
+ provider,
48
+ issuerUrl: publicUrl,
49
+ baseUrl: publicUrl,
50
+ scopesSupported: SCOPES,
51
+ serviceDocumentationUrl: new URL("https://github.com/jgwill/Miadi/tree/main/packages/connector"),
52
+ }),
53
+ authorization_response_iss_parameter_supported: true,
54
+ };
55
+ app.get("/.well-known/oauth-authorization-server", (_req, res) => {
56
+ res.set("cache-control", "no-store").json(asMetadata);
57
+ });
41
58
  app.use(mcpAuthRouter({
42
59
  provider,
43
60
  issuerUrl: publicUrl,
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "0.1.0";
1
+ export declare const VERSION = "0.1.1";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "0.1.0";
1
+ export const VERSION = "0.1.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miadi/connector",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "The Miadi connector: one remote MCP service through which a person signed in with their Miadi person token, from ChatGPT or any MCP client, reads sessions, reviews, episodes and circles and records observations, inquiries, handoffs and proposals with their name on each record.",
5
5
  "license": "MIT",
6
6
  "author": "Miadi",