@haikit/mcp 0.33.0 → 0.34.0

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.
Files changed (51) hide show
  1. package/README.md +46 -7
  2. package/dist/auth.d.ts +107 -36
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +252 -37
  5. package/dist/auth.js.map +1 -1
  6. package/dist/credential.d.ts +55 -0
  7. package/dist/credential.d.ts.map +1 -0
  8. package/dist/credential.js +62 -0
  9. package/dist/credential.js.map +1 -0
  10. package/dist/errors.d.ts +7 -0
  11. package/dist/errors.d.ts.map +1 -1
  12. package/dist/errors.js.map +1 -1
  13. package/dist/index.d.ts +6 -4
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +66 -9
  16. package/dist/index.js.map +1 -1
  17. package/dist/oauth.d.ts +193 -0
  18. package/dist/oauth.d.ts.map +1 -0
  19. package/dist/oauth.js +558 -0
  20. package/dist/oauth.js.map +1 -0
  21. package/dist/postgres.d.ts +25 -0
  22. package/dist/postgres.d.ts.map +1 -0
  23. package/dist/postgres.js +97 -0
  24. package/dist/postgres.js.map +1 -0
  25. package/dist/routes.d.ts +17 -0
  26. package/dist/routes.d.ts.map +1 -0
  27. package/dist/routes.js +228 -0
  28. package/dist/routes.js.map +1 -0
  29. package/dist/seal.d.ts +25 -0
  30. package/dist/seal.d.ts.map +1 -0
  31. package/dist/seal.js +60 -0
  32. package/dist/seal.js.map +1 -0
  33. package/dist/store.d.ts +50 -0
  34. package/dist/store.d.ts.map +1 -0
  35. package/dist/store.js +83 -0
  36. package/dist/store.js.map +1 -0
  37. package/dist/transports.d.ts +5 -1
  38. package/dist/transports.d.ts.map +1 -1
  39. package/dist/transports.js +2 -0
  40. package/dist/transports.js.map +1 -1
  41. package/package.json +6 -2
  42. package/src/auth.ts +354 -48
  43. package/src/credential.ts +78 -0
  44. package/src/errors.ts +7 -0
  45. package/src/index.ts +75 -12
  46. package/src/oauth.ts +659 -0
  47. package/src/postgres.ts +127 -0
  48. package/src/routes.ts +243 -0
  49. package/src/seal.ts +62 -0
  50. package/src/store.ts +118 -0
  51. package/src/transports.ts +7 -0
@@ -0,0 +1,193 @@
1
+ import { type AuthorizationServerMetadata, type FetchLike, type OAuthClientMetadata, type OAuthDiscoveryState, type StoredOAuthClientInformation, type StoredOAuthTokens } from "@modelcontextprotocol/client";
2
+ import { type Credential } from "./credential.js";
3
+ import { type Sealer } from "./seal.js";
4
+ import type { CredentialStore } from "./store.js";
5
+ /** How long a connect flow lasts: from the connect route to the callback. */
6
+ export declare const FLOW_MS = 600000;
7
+ export interface OAuthServerOptions {
8
+ /**
9
+ * The authorization server this server must use, as its metadata's
10
+ * `issuer`. Strongly advised for a third party's server: a server names its
11
+ * own authorization server, and one compromised could send users to a fake
12
+ * sign-in page.
13
+ */
14
+ issuer?: string;
15
+ /** Asked for when connecting. Default: what the server's metadata asks for. */
16
+ scopes?: string[];
17
+ /**
18
+ * A client the app registered with the authorization server. Needs
19
+ * `issuer`. Without it, one is registered for the app: by its metadata
20
+ * document's URL where the authorization server takes one, else by dynamic
21
+ * client registration.
22
+ */
23
+ client?: {
24
+ id: string;
25
+ secret?: string;
26
+ };
27
+ }
28
+ /** What every `oauth()` server of one `createMcpAuth` shares. */
29
+ export interface OAuthCore {
30
+ readonly store: CredentialStore;
31
+ readonly sealer: Sealer;
32
+ readonly redirectUri: string;
33
+ /** What a client is registered with, and the metadata document says. */
34
+ readonly clientMetadata: OAuthClientMetadata;
35
+ /** The metadata document's URL, when the redirect URI is https: an OAuth client can then be identified by it. */
36
+ readonly clientMetadataUrl: string | undefined;
37
+ }
38
+ /** What a user's credential holds, sealed. */
39
+ interface Kept {
40
+ /** As the authorization server issued them, stamped with its `issuer`. */
41
+ tokens: StoredOAuthTokens & {
42
+ issuer: string;
43
+ };
44
+ /** The client they were issued to: refreshed and revoked as it, whatever the store keeps for new connects. */
45
+ client: StoredOAuthClientInformation;
46
+ /** The scope granted, or asked for when the authorization server didn't say. */
47
+ scope: string | null;
48
+ /** When the user connected, epoch ms. A refresh keeps it. */
49
+ connectedAt: number;
50
+ }
51
+ /** A credential as the store holds it: the sealed value, and what it opened to. */
52
+ interface Held {
53
+ sealed: string;
54
+ kept: Kept;
55
+ }
56
+ /** A connect flow on its way, sealed in the store under its `state`. */
57
+ export interface Flow {
58
+ user: string;
59
+ server: string;
60
+ /** The conversation it came from, if the user owns it: `onConnected` is told. */
61
+ conversation: string | null;
62
+ /** The PKCE verifier. */
63
+ verifier: string;
64
+ /** The client the code is issued to: exchanged as it, though another connect replaced the one the store keeps. */
65
+ client: StoredOAuthClientInformation;
66
+ /** The SDK's discovery state, from the connect route: the callback is bound to its authorization server. */
67
+ discovery: OAuthDiscoveryState;
68
+ /** The scope asked for. */
69
+ scope: string | null;
70
+ expiresAt: number;
71
+ }
72
+ /** A server's authorization server, as discovered and checked. */
73
+ interface Where {
74
+ url: string;
75
+ issuer: string;
76
+ metadata: AuthorizationServerMetadata | undefined;
77
+ /** The RFC 8707 resource indicator: tokens are bound to this server. */
78
+ resource: string | undefined;
79
+ }
80
+ /** Loopback hosts, exempt from https: what the SDK exempts, and RFC 8252 does. */
81
+ export declare const isLoopback: (host: string) => boolean;
82
+ /** https, or http on this machine. */
83
+ export declare const isSecure: (url: string | URL) => boolean;
84
+ /** The connect flow a `state` names, once: null if there's none, it has expired, or it doesn't open. */
85
+ export declare function takeFlow(core: OAuthCore, state: string): Promise<Flow | null>;
86
+ /**
87
+ * One server's OAuth: its connect route and callback, each user's
88
+ * credential, refreshing, and revoking on disconnect.
89
+ */
90
+ export declare class OAuthServer {
91
+ readonly core: OAuthCore;
92
+ private readonly options;
93
+ readonly name: string;
94
+ private readonly url;
95
+ private readonly baseFetch;
96
+ readonly timeoutMs: number;
97
+ /** Closes the user's connection to this server, so their next call dials with what's stored now. */
98
+ readonly forget: (userId: string) => Promise<void>;
99
+ /** The authorization server, discovered on the first refresh or revocation, or seeded by a callback. */
100
+ private found;
101
+ /** Each user's refresh on its way, which every 401 of theirs shares until it settles. */
102
+ private readonly refreshing;
103
+ constructor(core: OAuthCore, options: OAuthServerOptions, name: string, url: URL, baseFetch: FetchLike, timeoutMs: number,
104
+ /** Closes the user's connection to this server, so their next call dials with what's stored now. */
105
+ forget: (userId: string) => Promise<void>);
106
+ /** Every request to the authorization server, bounded by `timeoutMs`. */
107
+ readonly fetch: FetchLike;
108
+ credential(user: string): Credential;
109
+ /** A user's credential as the store holds it, or null if there's none, or none that opens. `known` is given back as it is if the store still holds it. */
110
+ read(user: string, known?: Held | null): Promise<Held | null>;
111
+ seal(user: string, kept: Kept): string;
112
+ /** The client configured, stamped with the pinned issuer: the SDK refuses it for any other. */
113
+ private configured;
114
+ /**
115
+ * The client to connect with at an authorization server: the one
116
+ * configured, or the one registered for the app. One registered for
117
+ * another redirect URI or metadata document, or that doesn't open, is no
118
+ * use, and is registered again.
119
+ */
120
+ private client;
121
+ /** The client a flow or credential was issued to, as it's sent: the configured one with its secret as configured now. */
122
+ issuedTo(client: StoredOAuthClientInformation): StoredOAuthClientInformation;
123
+ private saveClient;
124
+ /**
125
+ * Checks what discovery found: the pinned issuer, and an authorization
126
+ * endpoint the browser can be sent to. Called by the SDK straight after
127
+ * discovery, before it looks up or registers a client, so a server that
128
+ * names another authorization server gets nothing from the app.
129
+ */
130
+ check(state: OAuthDiscoveryState): Promise<Where>;
131
+ /**
132
+ * The authorization server, which must be the one that issued a credential:
133
+ * found again once if it isn't, in case the server moved since.
134
+ */
135
+ where(issuer: string, resourceMetadataUrl?: URL): Promise<Where>;
136
+ /**
137
+ * The connect route: where to send the browser, with the flow stored under
138
+ * its `state` meanwhile. The SDK's `auth()` discovers the authorization
139
+ * server, registers a client if none is kept, and makes the PKCE challenge.
140
+ */
141
+ start(user: string, conversation: string | null, asked: string | undefined): Promise<URL>;
142
+ /**
143
+ * The callback: exchanges the code with the authorization server and as
144
+ * the client the flow was started with, which checks `iss` (RFC 9207)
145
+ * before it asks for any token, stores the credential, and closes the
146
+ * user's connection.
147
+ */
148
+ finish(flow: Flow, code: string, iss: string | undefined): Promise<void>;
149
+ /** Revokes the user's tokens where the authorization server takes it, then deletes them and closes the connection. */
150
+ disconnect(user: string): Promise<void>;
151
+ /** RFC 7009, at the authorization server's revocation endpoint, if it has one. */
152
+ private revoke;
153
+ /**
154
+ * After a 401: the credential to use instead of `before`. One refresh for
155
+ * each user at a time, shared until it settles, however long that takes,
156
+ * on whichever connection of theirs: a second would spend a refresh token
157
+ * the first may have spent already, and delete the credential when it's
158
+ * refused. Across processes, the store's lease does the same.
159
+ */
160
+ refresh(user: string, before: Held, resourceMetadataUrl: URL | undefined): Promise<Held>;
161
+ /**
162
+ * The store's newer credential if another refresh wrote one, else a
163
+ * refresh of `before`, under the store's lease. A refusal deletes it,
164
+ * unless another write came first; an outage keeps it.
165
+ */
166
+ private renew;
167
+ /**
168
+ * Writes a refresh's credential onto `before`, tried again while the
169
+ * store fails: the old refresh token is spent, so this is the only copy,
170
+ * and the lease is still held. False if another write or a delete came
171
+ * first. A try that landed, though its answer was lost, is written.
172
+ */
173
+ private write;
174
+ /**
175
+ * Revokes the tokens a refresh got but couldn't store: its refresh token
176
+ * if the authorization server rotated it, else only its access token, as
177
+ * the one refresh token may be what the store holds now.
178
+ */
179
+ private orphaned;
180
+ /**
181
+ * Takes the refresh lease of the user's credential, so one process at a
182
+ * time spends its refresh token. While another holds it: the credential
183
+ * that one writes, which is then the one to use, or the lease once it
184
+ * lapses, as it does when that process is gone.
185
+ */
186
+ private lease;
187
+ /** The store's credential if it's newer than `before`, or null if it's still `before`. With none, the server's refusal stands. */
188
+ private newer;
189
+ /** Deletes the credential, if the store still holds `before`: never a newer one. */
190
+ private drop;
191
+ }
192
+ export {};
193
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}