@koduhai/mcp-kit 0.1.0 โ†’ 0.2.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.
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # @koduhai/mcp-kit
2
2
 
3
3
  [![CI](https://github.com/koduhai/mcp-kit/actions/workflows/ci.yml/badge.svg)](https://github.com/koduhai/mcp-kit/actions/workflows/ci.yml)
4
+ [![codecov](https://codecov.io/gh/koduhai/mcp-kit/branch/main/graph/badge.svg)](https://codecov.io/gh/koduhai/mcp-kit)
4
5
  [![npm version](https://img.shields.io/npm/v/@koduhai/mcp-kit.svg)](https://www.npmjs.com/package/@koduhai/mcp-kit)
5
6
  [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/koduhai/mcp-kit/badge)](https://scorecard.dev/viewer/?uri=github.com/koduhai/mcp-kit)
6
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)
@@ -20,6 +21,8 @@ Built on top of `@modelcontextprotocol/sdk`. Aligned to the **2025-06-18** autho
20
21
  npm install @koduhai/mcp-kit
21
22
  ```
22
23
 
24
+ ๐Ÿ“š [API reference](https://koduhai.github.io/mcp-kit/) ยท ๐Ÿ”Œ [IdP recipes](./RECIPES.md) (Auth0, Keycloak, Okta, Clerk, โ€ฆ)
25
+
23
26
  ---
24
27
 
25
28
  ## 1. Upstream auth โ€” `@koduhai/mcp-kit/upstream`
@@ -119,17 +122,41 @@ const verifier = introspectionVerifier({
119
122
 
120
123
  Introspection results are cached for a short TTL (capped by the token's own `exp`) and deduplicated while a call is in flight, so a busy server doesn't introspect the same token on every request. Caching delays revocation visibility by at most the TTL; set `cacheTtlSeconds: 0` if every request must hit the AS.
121
124
 
122
- Works with any standards-compliant IdP: Auth0, Logto, Clerk, Keycloak, Okta, Cognito, WorkOS, and friends. mcp-kit verifies tokens; it does not try to be your Authorization Server (the spec says don't, and you shouldn't).
125
+ Works with any standards-compliant IdP: Auth0, Logto, Clerk, Keycloak, Okta, Cognito, WorkOS, and friends โ€” see [RECIPES.md](./RECIPES.md) for per-provider configs. mcp-kit verifies tokens; it does not try to be your Authorization Server (the spec says don't, and you shouldn't).
123
126
 
124
127
  See [`examples/`](./examples) for a full stdio server and a full remote OAuth server.
125
128
 
129
+ ## 4. Mounting tools โ€” `@koduhai/mcp-kit/server`
130
+
131
+ `versionTool` (and your own tools) are plain, transport-agnostic [`ToolDescriptor`](./src/versioning/index.ts)s. `serveTools` wires a list of them onto a low-level MCP `Server` in one call: it registers the `tools/list` and `tools/call` handlers, JSON-encodes each result as MCP text content, and rejects unknown tool names. This is the only entry point that needs the MCP SDK at runtime.
132
+
133
+ ```ts
134
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
135
+ import { serveTools } from '@koduhai/mcp-kit/server';
136
+ import { apiVersioning, versionTool } from '@koduhai/mcp-kit/versioning';
137
+
138
+ const versioning = apiVersioning({ header: 'Api-Version', version: '2026-01-01' });
139
+ const server = new Server({ name: 'my-mcp', version: '1.0.0' }, { capabilities: { tools: {} } });
140
+
141
+ serveTools(server, [
142
+ versionTool(versioning),
143
+ {
144
+ name: 'get_widget',
145
+ description: 'Fetch a widget.',
146
+ inputSchema: { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] },
147
+ handler: (a) => api(`/widgets/${a.id}`).then((r) => r.json()),
148
+ },
149
+ ]);
150
+ // await server.connect(transport)
151
+ ```
152
+
126
153
  ---
127
154
 
128
155
  ## Design
129
156
 
130
- - **Layered, optional peers.** `/upstream` and `/versioning` have zero dependencies. `/auth` declares `@modelcontextprotocol/sdk`, `express`, and `jose` as _optional_ peers, so you only install them if you build a remote server.
131
- - **Injectable everything.** Every network call and clock is injectable, so the whole thing is tested offline (46 tests, including a real Express + token-verification integration).
132
- - **Resilient outbound calls.** Every control-plane request the library makes (token, introspection, JWKS, discovery) carries a timeout (default 10s, configurable via `timeoutMs`) so an unresponsive IdP can't hang your server.
157
+ - **Layered, optional peers.** `/upstream` and `/versioning` have zero dependencies. `/auth` and `/server` declare `@modelcontextprotocol/sdk` (and `/auth` also `express` and `jose`) as _optional_ peers, so you only install them if you build a remote or SDK-backed server.
158
+ - **Injectable everything.** Every network call and clock is injectable, so the whole thing is tested offline (57 tests, including a real Express + token-verification integration and an in-memory MCP client/server round trip).
159
+ - **Resilient outbound calls.** Every control-plane request the library makes (token, introspection, JWKS, discovery) carries a timeout (default 10s, configurable via `timeoutMs`) and optional bounded retries (`retries`) so a slow or flaky IdP can't hang your server.
133
160
  - **ESM, Node โ‰ฅ 20, TypeScript-first.**
134
161
 
135
162
  ## Compatibility
@@ -18,6 +18,10 @@ export interface IntrospectionVerifierOptions {
18
18
  maxCacheEntries?: number;
19
19
  /** Timeout (ms) for the introspection request. Default 10000. Pass 0 to disable. */
20
20
  timeoutMs?: number;
21
+ /** Retries for transient introspection failures (network, 429, 5xx). Default 0. */
22
+ retries?: number;
23
+ /** Base backoff (ms), doubled each retry. Default 200. */
24
+ retryBaseDelayMs?: number;
21
25
  /** Injectable clock (ms). */
22
26
  now?: () => number;
23
27
  /** Injectable for tests. */
@@ -1 +1 @@
1
- {"version":3,"file":"introspection-verifier.d.ts","sourceRoot":"","sources":["../../src/auth/introspection-verifier.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mDAAmD,CAAC;AAI5F,MAAM,WAAW,4BAA4B;IAC3C,6DAA6D;IAC7D,gBAAgB,EAAE,MAAM,CAAC;IACzB,kGAAkG;IAClG,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uFAAuF;IACvF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,4BAA4B,GAAG,kBAAkB,CA8F5F"}
1
+ {"version":3,"file":"introspection-verifier.d.ts","sourceRoot":"","sources":["../../src/auth/introspection-verifier.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mDAAmD,CAAC;AAI5F,MAAM,WAAW,4BAA4B;IAC3C,6DAA6D;IAC7D,gBAAgB,EAAE,MAAM,CAAC;IACzB,kGAAkG;IAClG,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uFAAuF;IACvF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,4BAA4B,GAAG,kBAAkB,CA+F5F"}
@@ -1,6 +1,6 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { InvalidTokenError } from '@modelcontextprotocol/sdk/server/auth/errors.js';
3
- import { DEFAULT_TIMEOUT_MS, fetchWithTimeout } from '../internal/http.js';
3
+ import { DEFAULT_TIMEOUT_MS, fetchWithRetry } from '../internal/http.js';
4
4
  /**
5
5
  * An {@link OAuthTokenVerifier} that validates opaque (or any) access tokens by calling the
6
6
  * Authorization Server's introspection endpoint (RFC 7662). Use this when your IdP issues
@@ -42,7 +42,7 @@ export function introspectionVerifier(opts) {
42
42
  }
43
43
  let res;
44
44
  try {
45
- res = await fetchWithTimeout(fetchImpl, opts.introspectionUrl, { method: 'POST', headers, body }, timeoutMs);
45
+ res = await fetchWithRetry(fetchImpl, opts.introspectionUrl, { method: 'POST', headers, body }, timeoutMs, { retries: opts.retries, retryBaseDelayMs: opts.retryBaseDelayMs });
46
46
  }
47
47
  catch (e) {
48
48
  throw new InvalidTokenError(`introspection request failed: ${e instanceof Error ? e.message : String(e)}`);
@@ -1 +1 @@
1
- {"version":3,"file":"introspection-verifier.js","sourceRoot":"","sources":["../../src/auth/introspection-verifier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"introspection-verifier.js","sourceRoot":"","sources":["../../src/auth/introspection-verifier.ts"],"names":[],"mappings":"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"}
@@ -12,5 +12,19 @@ type FetchInput = Parameters<typeof globalThis.fetch>[0];
12
12
  * or non-finite `timeoutMs` to disable the timeout entirely.
13
13
  */
14
14
  export declare function fetchWithTimeout(fetchImpl: typeof globalThis.fetch, input: FetchInput, init?: RequestInit, timeoutMs?: number): Promise<Response>;
15
+ export interface RetryOptions {
16
+ /** Number of retries after the first attempt. Default 0 (no retries). */
17
+ retries?: number;
18
+ /** Base backoff in ms; doubles each attempt (200, 400, 800, ...). Default 200. */
19
+ retryBaseDelayMs?: number;
20
+ /** Injectable delay, for tests. */
21
+ sleep?: (ms: number) => Promise<void>;
22
+ }
23
+ /**
24
+ * `fetchWithTimeout` plus bounded exponential-backoff retries on transient
25
+ * failures (network errors, 429, and 5xx). A timeout abort counts as a failure
26
+ * and is retried. With `retries: 0` (the default) this is exactly one attempt.
27
+ */
28
+ export declare function fetchWithRetry(fetchImpl: typeof globalThis.fetch, input: FetchInput, init: RequestInit, timeoutMs: number, retry?: RetryOptions): Promise<Response>;
15
29
  export {};
16
30
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/internal/http.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,OAAO,UAAU,CAAC,KAAK,EAClC,KAAK,EAAE,UAAU,EACjB,IAAI,GAAE,WAAgB,EACtB,SAAS,GAAE,MAA2B,GACrC,OAAO,CAAC,QAAQ,CAAC,CAWnB"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/internal/http.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEzD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,OAAO,UAAU,CAAC,KAAK,EAClC,KAAK,EAAE,UAAU,EACjB,IAAI,GAAE,WAAgB,EACtB,SAAS,GAAE,MAA2B,GACrC,OAAO,CAAC,QAAQ,CAAC,CAWnB;AAKD,MAAM,WAAW,YAAY;IAC3B,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mCAAmC;IACnC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,OAAO,UAAU,CAAC,KAAK,EAClC,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,YAAiB,GACvB,OAAO,CAAC,QAAQ,CAAC,CAqBnB"}
@@ -25,4 +25,34 @@ export async function fetchWithTimeout(fetchImpl, input, init = {}, timeoutMs =
25
25
  throw e;
26
26
  }
27
27
  }
28
+ /** HTTP status codes worth retrying: rate limiting and transient server errors. */
29
+ const RETRYABLE_STATUS = new Set([429, 500, 502, 503, 504]);
30
+ /**
31
+ * `fetchWithTimeout` plus bounded exponential-backoff retries on transient
32
+ * failures (network errors, 429, and 5xx). A timeout abort counts as a failure
33
+ * and is retried. With `retries: 0` (the default) this is exactly one attempt.
34
+ */
35
+ export async function fetchWithRetry(fetchImpl, input, init, timeoutMs, retry = {}) {
36
+ const retries = retry.retries ?? 0;
37
+ const base = retry.retryBaseDelayMs ?? 200;
38
+ const sleep = retry.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
39
+ let attempt = 0;
40
+ for (;;) {
41
+ try {
42
+ const res = await fetchWithTimeout(fetchImpl, input, init, timeoutMs);
43
+ if (RETRYABLE_STATUS.has(res.status) && attempt < retries) {
44
+ await sleep(base * 2 ** attempt);
45
+ attempt++;
46
+ continue;
47
+ }
48
+ return res;
49
+ }
50
+ catch (e) {
51
+ if (attempt >= retries)
52
+ throw e;
53
+ await sleep(base * 2 ** attempt);
54
+ attempt++;
55
+ }
56
+ }
57
+ }
28
58
  //# sourceMappingURL=http.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/internal/http.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAIzC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAkC,EAClC,KAAiB,EACjB,OAAoB,EAAE,EACtB,YAAoB,kBAAkB;IAEtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/E,IAAI,CAAC;QACH,OAAO,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,4EAA4E;QAC5E,IAAI,OAAO,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,SAAS,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7F,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/internal/http.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAIzC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAkC,EAClC,KAAiB,EACjB,OAAoB,EAAE,EACtB,YAAoB,kBAAkB;IAEtC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/E,IAAI,CAAC;QACH,OAAO,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,4EAA4E;QAC5E,IAAI,OAAO,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,SAAS,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC7F,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAED,mFAAmF;AACnF,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAW5D;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,SAAkC,EAClC,KAAiB,EACjB,IAAiB,EACjB,SAAiB,EACjB,QAAsB,EAAE;IAExB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,KAAK,CAAC,gBAAgB,IAAI,GAAG,CAAC;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAEnF,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,SAAS,CAAC;QACR,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;YACtE,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;gBAC1D,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC;gBACjC,OAAO,EAAE,CAAC;gBACV,SAAS;YACX,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,OAAO,IAAI,OAAO;gBAAE,MAAM,CAAC,CAAC;YAChC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC;YACjC,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Server glue for mounting transport-agnostic {@link ToolDescriptor}s onto an MCP
3
+ * `Server` in one call. This is the only entry point that needs the MCP SDK at
4
+ * runtime, so it lives apart from the zero-dependency `/versioning` module.
5
+ */
6
+ import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
+ import type { ToolDescriptor } from '../versioning/index.js';
8
+ /**
9
+ * Register a list of {@link ToolDescriptor}s on a low-level MCP `Server`: wires the
10
+ * `tools/list` and `tools/call` handlers, JSON-encodes each handler's return value as
11
+ * MCP text content, and answers unknown tool names with a `MethodNotFound` error. This
12
+ * replaces the boilerplate you'd otherwise hand-write per server.
13
+ *
14
+ * The server must advertise the tools capability when constructed, e.g.
15
+ * `new Server(info, { capabilities: { tools: {} } })`.
16
+ *
17
+ * @example
18
+ * const server = new Server({ name: 'x', version: '1.0.0' }, { capabilities: { tools: {} } });
19
+ * serveTools(server, [versionTool(versioning), myTool]);
20
+ * await server.connect(transport);
21
+ */
22
+ export declare function serveTools(server: Server, tools: ToolDescriptor[]): void;
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAOxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI,CAkBxE"}
@@ -0,0 +1,34 @@
1
+ import { CallToolRequestSchema, ListToolsRequestSchema, McpError, ErrorCode, } from '@modelcontextprotocol/sdk/types.js';
2
+ /**
3
+ * Register a list of {@link ToolDescriptor}s on a low-level MCP `Server`: wires the
4
+ * `tools/list` and `tools/call` handlers, JSON-encodes each handler's return value as
5
+ * MCP text content, and answers unknown tool names with a `MethodNotFound` error. This
6
+ * replaces the boilerplate you'd otherwise hand-write per server.
7
+ *
8
+ * The server must advertise the tools capability when constructed, e.g.
9
+ * `new Server(info, { capabilities: { tools: {} } })`.
10
+ *
11
+ * @example
12
+ * const server = new Server({ name: 'x', version: '1.0.0' }, { capabilities: { tools: {} } });
13
+ * serveTools(server, [versionTool(versioning), myTool]);
14
+ * await server.connect(transport);
15
+ */
16
+ export function serveTools(server, tools) {
17
+ const byName = new Map(tools.map((t) => [t.name, t]));
18
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
19
+ tools: tools.map((t) => ({
20
+ name: t.name,
21
+ description: t.description,
22
+ inputSchema: t.inputSchema,
23
+ })),
24
+ }));
25
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
26
+ const tool = byName.get(req.params.name);
27
+ if (!tool)
28
+ throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${req.params.name}`);
29
+ const result = await tool.handler((req.params.arguments ?? {}));
30
+ const text = typeof result === 'string' ? result : JSON.stringify(result, null, 2);
31
+ return { content: [{ type: 'text', text }] };
32
+ });
33
+ }
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,QAAQ,EACR,SAAS,GACV,MAAM,oCAAoC,CAAC;AAG5C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,KAAuB;IAChE,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtD,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,WAAW,EAAE,CAAC,CAAC,WAAiC;SACjD,CAAC,CAAC;KACJ,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,iBAAiB,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5F,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAA4B,CAAC,CAAC;QAC3F,MAAM,IAAI,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACnF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -3,6 +3,19 @@ export interface UpstreamAuth {
3
3
  /** Returns headers to merge into every upstream request. May refresh tokens internally. */
4
4
  headers(): Promise<Record<string, string>>;
5
5
  }
6
+ /**
7
+ * Thrown when an OAuth token endpoint responds with an error or a malformed body.
8
+ * Carries the HTTP `status` and raw `responseBody` so callers can branch on them.
9
+ */
10
+ export declare class TokenRequestError extends Error {
11
+ readonly status?: number;
12
+ readonly responseBody?: string;
13
+ constructor(message: string, opts?: {
14
+ status?: number;
15
+ responseBody?: string;
16
+ cause?: unknown;
17
+ });
18
+ }
6
19
  export interface ApiKeyAuthOptions {
7
20
  /** The API key / token value. */
8
21
  key: string;
@@ -34,6 +47,10 @@ export interface ClientCredentialsOptions {
34
47
  refreshSkewSeconds?: number;
35
48
  /** Timeout (ms) for the token request. Default 10000. Pass 0 to disable. */
36
49
  timeoutMs?: number;
50
+ /** Retries for transient token-endpoint failures (network, 429, 5xx). Default 0. */
51
+ retries?: number;
52
+ /** Base backoff (ms), doubled each retry. Default 200. */
53
+ retryBaseDelayMs?: number;
37
54
  /** Injectable for tests. */
38
55
  fetch?: typeof globalThis.fetch;
39
56
  /** Injectable clock (ms). */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/upstream/index.ts"],"names":[],"mappings":"AAMA,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,2FAA2F;IAC3F,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,iBAAiB;IAChC,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,YAAY,CAQhE;AAED,iFAAiF;AACjF,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAEpE,sFAAsF;AACtF,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,SAAkB,GAAG,YAAY,CAQrF;AAED,MAAM,WAAW,wBAAwB;IACvC,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,wBAAwB,GAAG,YAAY,CAiElF;AAED,+FAA+F;AAC/F,MAAM,MAAM,YAAY,GACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACtB,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAMrE,MAAM,WAAW,oBAAoB;IACnC,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,iFAAiF;IACjF,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,UAAU,CAAC,KAAK,CAmBvF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/upstream/index.ts"],"names":[],"mappings":"AAMA,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,2FAA2F;IAC3F,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC5C;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;gBACnB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAMhG;AAED,MAAM,WAAW,iBAAiB;IAChC,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,YAAY,CAQhE;AAED,iFAAiF;AACjF,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;AAEpE,sFAAsF;AACtF,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,SAAkB,GAAG,YAAY,CAQrF;AAED,MAAM,WAAW,wBAAwB;IACvC,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,4BAA4B;IAC5B,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAChC,6BAA6B;IAC7B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,wBAAwB,GAAG,YAAY,CAsElF;AAED,+FAA+F;AAC/F,MAAM,MAAM,YAAY,GACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACtB,CAAC,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAMrE,MAAM,WAAW,oBAAoB;IACnC,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gEAAgE;IAChE,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,iFAAiF;IACjF,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,UAAU,CAAC,KAAK,CAmBvF"}
@@ -2,7 +2,21 @@
2
2
  * Upstream auth: how your MCP server authenticates to the API/service it wraps.
3
3
  * Zero dependencies, zero transport assumptions. Works with stdio or HTTP servers.
4
4
  */
5
- import { DEFAULT_TIMEOUT_MS, fetchWithTimeout } from '../internal/http.js';
5
+ import { DEFAULT_TIMEOUT_MS, fetchWithRetry, fetchWithTimeout } from '../internal/http.js';
6
+ /**
7
+ * Thrown when an OAuth token endpoint responds with an error or a malformed body.
8
+ * Carries the HTTP `status` and raw `responseBody` so callers can branch on them.
9
+ */
10
+ export class TokenRequestError extends Error {
11
+ status;
12
+ responseBody;
13
+ constructor(message, opts) {
14
+ super(message, opts?.cause !== undefined ? { cause: opts.cause } : undefined);
15
+ this.name = 'TokenRequestError';
16
+ this.status = opts?.status;
17
+ this.responseBody = opts?.responseBody;
18
+ }
19
+ }
6
20
  /** Static API-key auth. The most common MCP-server-to-API pattern. */
7
21
  export function apiKeyAuth(opts) {
8
22
  if (!opts.key)
@@ -48,11 +62,11 @@ export function clientCredentialsAuth(opts) {
48
62
  body.set('scope', opts.scope);
49
63
  if (opts.audience)
50
64
  body.set('audience', opts.audience);
51
- const res = await fetchWithTimeout(fetchImpl, opts.tokenUrl, {
65
+ const res = await fetchWithRetry(fetchImpl, opts.tokenUrl, {
52
66
  method: 'POST',
53
67
  headers: { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' },
54
68
  body,
55
- }, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);
69
+ }, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS, { retries: opts.retries, retryBaseDelayMs: opts.retryBaseDelayMs });
56
70
  const text = await res.text();
57
71
  let json;
58
72
  try {
@@ -62,11 +76,14 @@ export function clientCredentialsAuth(opts) {
62
76
  json = {};
63
77
  }
64
78
  if (!res.ok) {
65
- throw new Error(`clientCredentialsAuth: token request failed (${res.status}): ${String(json.error ?? text)}`);
79
+ throw new TokenRequestError(`clientCredentialsAuth: token request failed (${res.status}): ${String(json.error ?? text)}`, { status: res.status, responseBody: text });
66
80
  }
67
81
  const token = json.access_token;
68
82
  if (typeof token !== 'string' || !token) {
69
- throw new Error('clientCredentialsAuth: response missing access_token');
83
+ throw new TokenRequestError('clientCredentialsAuth: response missing access_token', {
84
+ status: res.status,
85
+ responseBody: text,
86
+ });
70
87
  }
71
88
  const expiresIn = typeof json.expires_in === 'number' ? json.expires_in : 3600;
72
89
  cached = { token, expiresAtMs: now() + expiresIn * 1000 };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/upstream/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/upstream/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koduhai/mcp-kit",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Auth and versioning for MCP servers, solved. Upstream API auth (API key / bearer / OAuth client-credentials), API versioning with a get_version tool, and a one-call OAuth 2.1 Resource Server (JWKS + introspection verifiers, RFC 9728 metadata) on top of the MCP SDK.",
5
5
  "keywords": [
6
6
  "mcp",
@@ -43,6 +43,10 @@
43
43
  "./auth": {
44
44
  "types": "./dist/auth/index.d.ts",
45
45
  "import": "./dist/auth/index.js"
46
+ },
47
+ "./server": {
48
+ "types": "./dist/server/index.d.ts",
49
+ "import": "./dist/server/index.js"
46
50
  }
47
51
  },
48
52
  "files": [
@@ -50,6 +54,10 @@
50
54
  "README.md",
51
55
  "LICENSE"
52
56
  ],
57
+ "publishConfig": {
58
+ "access": "public",
59
+ "provenance": true
60
+ },
53
61
  "engines": {
54
62
  "node": ">=20"
55
63
  },
@@ -60,6 +68,9 @@
60
68
  "format": "prettier --write .",
61
69
  "format:check": "prettier --check .",
62
70
  "test": "vitest run",
71
+ "test:coverage": "vitest run --coverage",
72
+ "typecheck:examples": "tsc -p examples/tsconfig.json",
73
+ "docs": "typedoc",
63
74
  "prepublishOnly": "npm run build"
64
75
  },
65
76
  "peerDependencies": {
@@ -84,12 +95,14 @@
84
95
  "@types/express": "^5.0.0",
85
96
  "@types/node": "^25.9.3",
86
97
  "@types/supertest": "^7.2.0",
98
+ "@vitest/coverage-v8": "^4.1.8",
87
99
  "eslint": "^10.4.1",
88
100
  "eslint-config-prettier": "^10.1.8",
89
101
  "express": "^5.0.0",
90
102
  "jose": "^6.0.0",
91
103
  "prettier": "^3.8.4",
92
104
  "supertest": "^7.0.0",
105
+ "typedoc": "^0.28.19",
93
106
  "typescript": "^6.0.3",
94
107
  "typescript-eslint": "^8.61.0",
95
108
  "vitest": "^4.1.8"