@novorb/mcp-core 2.1.1 → 3.0.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 (240) hide show
  1. package/README.md +82 -161
  2. package/bin/mcp-core-jest.mjs +112 -0
  3. package/dist/auth.d.ts +57 -0
  4. package/dist/auth.d.ts.map +1 -0
  5. package/dist/auth.js +74 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/bootstrap.d.ts +129 -0
  8. package/dist/bootstrap.d.ts.map +1 -0
  9. package/dist/bootstrap.js +206 -0
  10. package/dist/bootstrap.js.map +1 -0
  11. package/dist/client-input.d.ts +72 -0
  12. package/dist/client-input.d.ts.map +1 -0
  13. package/dist/client-input.js +109 -0
  14. package/dist/client-input.js.map +1 -0
  15. package/dist/credential-checks.d.ts +80 -0
  16. package/dist/credential-checks.d.ts.map +1 -0
  17. package/dist/credential-checks.js +189 -0
  18. package/dist/credential-checks.js.map +1 -0
  19. package/dist/credential-health.d.ts +12 -0
  20. package/dist/credential-health.d.ts.map +1 -0
  21. package/dist/credential-health.js +12 -0
  22. package/dist/credential-health.js.map +1 -0
  23. package/dist/credential-report.d.ts +46 -0
  24. package/dist/credential-report.d.ts.map +1 -0
  25. package/dist/credential-report.js +135 -0
  26. package/dist/credential-report.js.map +1 -0
  27. package/dist/credential-status-tool.d.ts +20 -0
  28. package/dist/credential-status-tool.d.ts.map +1 -0
  29. package/dist/credential-status-tool.js +33 -0
  30. package/dist/credential-status-tool.js.map +1 -0
  31. package/dist/credentials.d.ts +288 -0
  32. package/dist/credentials.d.ts.map +1 -0
  33. package/dist/credentials.js +652 -0
  34. package/dist/credentials.js.map +1 -0
  35. package/dist/express-peers.d.ts +29 -0
  36. package/dist/express-peers.d.ts.map +1 -0
  37. package/dist/express-peers.js +36 -0
  38. package/dist/express-peers.js.map +1 -0
  39. package/dist/express.d.ts +74 -0
  40. package/dist/express.d.ts.map +1 -0
  41. package/dist/express.js +164 -0
  42. package/dist/express.js.map +1 -0
  43. package/dist/http-client.d.ts +278 -43
  44. package/dist/http-client.d.ts.map +1 -1
  45. package/dist/http-client.js +620 -182
  46. package/dist/http-client.js.map +1 -1
  47. package/dist/index.d.ts +27 -6
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +49 -10
  50. package/dist/index.js.map +1 -1
  51. package/dist/limits.d.ts +28 -0
  52. package/dist/limits.d.ts.map +1 -0
  53. package/dist/limits.js +37 -0
  54. package/dist/limits.js.map +1 -0
  55. package/dist/list-pagination.d.ts +41 -0
  56. package/dist/list-pagination.d.ts.map +1 -0
  57. package/dist/list-pagination.js +104 -0
  58. package/dist/list-pagination.js.map +1 -0
  59. package/dist/net.d.ts +112 -0
  60. package/dist/net.d.ts.map +1 -0
  61. package/dist/net.js +490 -0
  62. package/dist/net.js.map +1 -0
  63. package/dist/notifications.d.ts +78 -0
  64. package/dist/notifications.d.ts.map +1 -0
  65. package/dist/notifications.js +173 -0
  66. package/dist/notifications.js.map +1 -0
  67. package/dist/pagination.d.ts +236 -5
  68. package/dist/pagination.d.ts.map +1 -1
  69. package/dist/pagination.js +393 -6
  70. package/dist/pagination.js.map +1 -1
  71. package/dist/prompts.d.ts +70 -0
  72. package/dist/prompts.d.ts.map +1 -0
  73. package/dist/prompts.js +109 -0
  74. package/dist/prompts.js.map +1 -0
  75. package/dist/protocol-errors.d.ts +15 -0
  76. package/dist/protocol-errors.d.ts.map +1 -0
  77. package/dist/protocol-errors.js +28 -0
  78. package/dist/protocol-errors.js.map +1 -0
  79. package/dist/protocol-logging.d.ts +37 -0
  80. package/dist/protocol-logging.d.ts.map +1 -0
  81. package/dist/protocol-logging.js +77 -0
  82. package/dist/protocol-logging.js.map +1 -0
  83. package/dist/rate-limiter.d.ts +36 -0
  84. package/dist/rate-limiter.d.ts.map +1 -0
  85. package/dist/rate-limiter.js +79 -0
  86. package/dist/rate-limiter.js.map +1 -0
  87. package/dist/request-state.d.ts +74 -0
  88. package/dist/request-state.d.ts.map +1 -0
  89. package/dist/request-state.js +190 -0
  90. package/dist/request-state.js.map +1 -0
  91. package/dist/resources.d.ts +181 -0
  92. package/dist/resources.d.ts.map +1 -0
  93. package/dist/resources.js +302 -0
  94. package/dist/resources.js.map +1 -0
  95. package/dist/result-limits.d.ts +80 -0
  96. package/dist/result-limits.d.ts.map +1 -0
  97. package/dist/result-limits.js +248 -0
  98. package/dist/result-limits.js.map +1 -0
  99. package/dist/retry.d.ts +79 -23
  100. package/dist/retry.d.ts.map +1 -1
  101. package/dist/retry.js +170 -57
  102. package/dist/retry.js.map +1 -1
  103. package/dist/sdk/client-stdio.d.ts +6 -0
  104. package/dist/sdk/client-stdio.d.ts.map +1 -0
  105. package/dist/sdk/client-stdio.js +6 -0
  106. package/dist/sdk/client-stdio.js.map +1 -0
  107. package/dist/sdk/client.d.ts +6 -0
  108. package/dist/sdk/client.d.ts.map +1 -0
  109. package/dist/sdk/client.js +6 -0
  110. package/dist/sdk/client.js.map +1 -0
  111. package/dist/sdk/express.d.ts +3 -0
  112. package/dist/sdk/express.d.ts.map +1 -0
  113. package/dist/sdk/express.js +11 -0
  114. package/dist/sdk/express.js.map +1 -0
  115. package/dist/sdk/node.d.ts +6 -0
  116. package/dist/sdk/node.d.ts.map +1 -0
  117. package/dist/sdk/node.js +6 -0
  118. package/dist/sdk/node.js.map +1 -0
  119. package/dist/sdk/server-stdio.d.ts +6 -0
  120. package/dist/sdk/server-stdio.d.ts.map +1 -0
  121. package/dist/sdk/server-stdio.js +6 -0
  122. package/dist/sdk/server-stdio.js.map +1 -0
  123. package/dist/sdk/server.d.ts +6 -0
  124. package/dist/sdk/server.d.ts.map +1 -0
  125. package/dist/sdk/server.js +6 -0
  126. package/dist/sdk/server.js.map +1 -0
  127. package/dist/server.d.ts +88 -36
  128. package/dist/server.d.ts.map +1 -1
  129. package/dist/server.js +98 -44
  130. package/dist/server.js.map +1 -1
  131. package/dist/task-request.d.ts +20 -0
  132. package/dist/task-request.d.ts.map +1 -0
  133. package/dist/task-request.js +43 -0
  134. package/dist/task-request.js.map +1 -0
  135. package/dist/task-store.d.ts +230 -0
  136. package/dist/task-store.d.ts.map +1 -0
  137. package/dist/task-store.js +459 -0
  138. package/dist/task-store.js.map +1 -0
  139. package/dist/task-tools.d.ts +115 -0
  140. package/dist/task-tools.d.ts.map +1 -0
  141. package/dist/task-tools.js +397 -0
  142. package/dist/task-tools.js.map +1 -0
  143. package/dist/testing/client.d.ts +25 -0
  144. package/dist/testing/client.d.ts.map +1 -0
  145. package/dist/testing/client.js +11 -0
  146. package/dist/testing/client.js.map +1 -0
  147. package/dist/testing/in-memory.d.ts +26 -0
  148. package/dist/testing/in-memory.d.ts.map +1 -0
  149. package/dist/testing/in-memory.js +41 -0
  150. package/dist/testing/in-memory.js.map +1 -0
  151. package/dist/testing/index.d.ts +20 -0
  152. package/dist/testing/index.d.ts.map +1 -0
  153. package/dist/testing/index.js +20 -0
  154. package/dist/testing/index.js.map +1 -0
  155. package/dist/testing/isolated-dirs.d.ts +27 -0
  156. package/dist/testing/isolated-dirs.d.ts.map +1 -0
  157. package/dist/testing/isolated-dirs.js +67 -0
  158. package/dist/testing/isolated-dirs.js.map +1 -0
  159. package/dist/testing/logs.d.ts +61 -0
  160. package/dist/testing/logs.d.ts.map +1 -0
  161. package/dist/testing/logs.js +113 -0
  162. package/dist/testing/logs.js.map +1 -0
  163. package/dist/testing/raw-http.d.ts +25 -0
  164. package/dist/testing/raw-http.d.ts.map +1 -0
  165. package/dist/testing/raw-http.js +41 -0
  166. package/dist/testing/raw-http.js.map +1 -0
  167. package/dist/testing/raw-peer.d.ts +43 -0
  168. package/dist/testing/raw-peer.d.ts.map +1 -0
  169. package/dist/testing/raw-peer.js +101 -0
  170. package/dist/testing/raw-peer.js.map +1 -0
  171. package/dist/testing/recording-server.d.ts +38 -0
  172. package/dist/testing/recording-server.d.ts.map +1 -0
  173. package/dist/testing/recording-server.js +38 -0
  174. package/dist/testing/recording-server.js.map +1 -0
  175. package/dist/testing/server-process.d.ts +76 -0
  176. package/dist/testing/server-process.d.ts.map +1 -0
  177. package/dist/testing/server-process.js +241 -0
  178. package/dist/testing/server-process.js.map +1 -0
  179. package/dist/testing/tools.d.ts +53 -0
  180. package/dist/testing/tools.d.ts.map +1 -0
  181. package/dist/testing/tools.js +98 -0
  182. package/dist/testing/tools.js.map +1 -0
  183. package/dist/testing/unit.d.ts +52 -0
  184. package/dist/testing/unit.d.ts.map +1 -0
  185. package/dist/testing/unit.js +95 -0
  186. package/dist/testing/unit.js.map +1 -0
  187. package/dist/tools.d.ts +205 -0
  188. package/dist/tools.d.ts.map +1 -0
  189. package/dist/tools.js +370 -0
  190. package/dist/tools.js.map +1 -0
  191. package/dist/transport.d.ts +144 -53
  192. package/dist/transport.d.ts.map +1 -1
  193. package/dist/transport.js +305 -122
  194. package/dist/transport.js.map +1 -1
  195. package/dist/url-path.d.ts +49 -0
  196. package/dist/url-path.d.ts.map +1 -0
  197. package/dist/url-path.js +165 -0
  198. package/dist/url-path.js.map +1 -0
  199. package/dist/utils/dataStore.d.ts +143 -0
  200. package/dist/utils/dataStore.d.ts.map +1 -0
  201. package/dist/utils/dataStore.js +429 -0
  202. package/dist/utils/dataStore.js.map +1 -0
  203. package/dist/utils/envLoader.d.ts +129 -0
  204. package/dist/utils/envLoader.d.ts.map +1 -0
  205. package/dist/utils/envLoader.js +399 -0
  206. package/dist/utils/envLoader.js.map +1 -0
  207. package/dist/utils/logger.d.ts +181 -0
  208. package/dist/utils/logger.d.ts.map +1 -0
  209. package/dist/utils/logger.js +664 -0
  210. package/dist/utils/logger.js.map +1 -0
  211. package/dist/utils/redact.d.ts +50 -0
  212. package/dist/utils/redact.d.ts.map +1 -0
  213. package/dist/utils/redact.js +318 -0
  214. package/dist/utils/redact.js.map +1 -0
  215. package/docs/api-reference.md +29 -0
  216. package/docs/building-a-server.md +63 -0
  217. package/docs/credentials.md +131 -0
  218. package/docs/data-store.md +37 -0
  219. package/docs/env.md +38 -0
  220. package/docs/features.md +28 -0
  221. package/docs/http-client.md +116 -0
  222. package/docs/logger.md +100 -0
  223. package/docs/migrating-to-v3.md +45 -0
  224. package/docs/outbound-urls.md +104 -0
  225. package/docs/pagination.md +45 -0
  226. package/docs/protocol-features.md +62 -0
  227. package/docs/resources-prompts-tasks.md +95 -0
  228. package/docs/sdk.md +33 -0
  229. package/docs/server.md +68 -0
  230. package/docs/testing-harness.md +139 -0
  231. package/docs/testing.md +151 -0
  232. package/docs/tools.md +88 -0
  233. package/docs/transport.md +85 -0
  234. package/examples/testing/tools.integration.test.example.ts +312 -0
  235. package/examples/testing/tools.unit.test.example.ts +149 -0
  236. package/package.json +140 -18
  237. package/dist/logger.d.ts +0 -80
  238. package/dist/logger.d.ts.map +0 -1
  239. package/dist/logger.js +0 -236
  240. package/dist/logger.js.map +0 -1
@@ -0,0 +1,181 @@
1
+ /**
2
+ * @novorb/mcp-core - Resources (static resources and URI templates), resource links, subscriptions
3
+ *
4
+ * `registerResources` mirrors `registerTools`: definitions go onto the SDK's own
5
+ * `McpServer.registerResource` (so `resources/list`, `resources/templates/list`, `resources/read`,
6
+ * template matching, completion of template variables and the `ResourceNotFoundError` are the SDK's),
7
+ * and mcp-core adds only what the SDK lacks:
8
+ *
9
+ * - one wrapper per resource: `Resource read: <uri or uri template>` / `Resource result: ...` log
10
+ * lines (name, template, duration, size; never the content and never the filled-in URI);
11
+ * - thrown errors become JSON-RPC errors through `mapError` (masked, never a stack);
12
+ * - degraded mode: a resource whose `requires` env keys are missing is still listed and answers the
13
+ * uniform `<server> is not configured: set <KEYS>`;
14
+ * - a size cap on every read (default `MCP_MAX_RESULT_BYTES`, per resource `maxBytes`): an oversized
15
+ * read is an actionable error, never a truncated document;
16
+ * - shorthand results (a string is text, bytes are a blob, both with the definition's `mimeType`);
17
+ * - `resources/subscribe` / `resources/unsubscribe` for 2025-era clients (`subscribe: true`); updates
18
+ * are published with `notify.resourceUpdated(uri)` (see `notifications.ts`);
19
+ * - the list pagination of `resources/list` and `resources/templates/list` (C1, `createMcpServer`).
20
+ *
21
+ * registerResources(server, [
22
+ * defineResource({ name: 'readme', uri: 'repo://readme', mimeType: 'text/markdown',
23
+ * read: async () => readme }),
24
+ * defineResourceTemplate({ name: 'file', uriTemplate: 'repo://files/{path}', mimeType: 'text/plain',
25
+ * complete: { path: (prefix) => paths.filter((p) => p.startsWith(prefix)) },
26
+ * read: async ({ variables }) => readFile(String(variables.path)) }),
27
+ * ], { env, serverName: 'repo-mcp', subscribe: true });
28
+ *
29
+ * Tools point at resources instead of inlining large payloads with `resourceLink(...)` /
30
+ * `embeddedResource(...)`, and `createResultSpill()` connects the tool result byte cap (`onOversize`)
31
+ * to a resource link automatically.
32
+ */
33
+ import { type AuthInfo, type CacheHint, type CallToolResult, type CompleteResourceTemplateCallback, type EmbeddedResource, type Icon, type InputRequiredResult, type ListResourcesResult, type ReadResourceResult, type RegisteredResource, type RegisteredResourceTemplate, type Resource, type ResourceLink, type ScopeChallengeHandler, type ServerContext, type Variables } from '@modelcontextprotocol/server';
34
+ import { type RequestEra } from './client-input.js';
35
+ import { type RuntimeSurface } from './notifications.js';
36
+ import { type MapError } from './protocol-errors.js';
37
+ import type { OversizeInfo } from './result-limits.js';
38
+ import type { McpServer } from './server.js';
39
+ import type { RequestContext } from './transport.js';
40
+ import type { LoadedEnv } from './utils/envLoader.js';
41
+ import { type Logger } from './utils/logger.js';
42
+ /** What a resource read handler may return: a result, an input-required result, text, or bytes. */
43
+ export type ResourceReadOutcome = ReadResourceResult | InputRequiredResult | string | Uint8Array;
44
+ /** Per-read context. */
45
+ export interface ResourceContext {
46
+ /** The definition name. */
47
+ name: string;
48
+ /** The URI being read (the filled-in template for a template). */
49
+ uri: URL;
50
+ /** The template variables (empty for a static resource). */
51
+ variables: Variables;
52
+ /** Aborted when the client cancels or disconnects. */
53
+ signal: AbortSignal;
54
+ /** Caller identity when the transport supplies one. */
55
+ authInfo?: AuthInfo;
56
+ /** The protocol era (undefined when invoked directly). */
57
+ era?: RequestEra;
58
+ logger: Logger;
59
+ /** The raw SDK context (undefined when invoked directly). */
60
+ sdk?: ServerContext;
61
+ }
62
+ interface ResourceBase {
63
+ name: string;
64
+ title?: string;
65
+ description?: string;
66
+ /** Applied to shorthand results and to contents that carry no `mimeType`. */
67
+ mimeType?: string;
68
+ /** Size in bytes, when known (advertised in `resources/list`). */
69
+ size?: number;
70
+ annotations?: Resource['annotations'];
71
+ icons?: Icon[];
72
+ _meta?: Record<string, unknown>;
73
+ /** 2026-07-28 cache hint for this resource's reads. */
74
+ cacheHint?: CacheHint;
75
+ /** SDK scope gate (for example `requireScopes('files:read')`). */
76
+ scopeChallenge?: ScopeChallengeHandler;
77
+ /** Env keys that must be configured; otherwise reads answer the uniform "not configured" error. */
78
+ requires?: readonly string[];
79
+ /** Max serialized bytes of one read (default MCP_MAX_RESULT_BYTES / the `maxBytes` option). */
80
+ maxBytes?: number;
81
+ }
82
+ /** A resource at a fixed URI. */
83
+ export interface ResourceDefinition extends ResourceBase {
84
+ uri: string;
85
+ read: (ctx: ResourceContext) => Promise<ResourceReadOutcome>;
86
+ }
87
+ /** A family of resources under an RFC 6570 URI template (`repo://files/{path}`). */
88
+ export interface ResourceTemplateDefinition extends ResourceBase {
89
+ uriTemplate: string;
90
+ /** Enumerate concrete resources for `resources/list` (omit when the family is not enumerable). */
91
+ list?: (ctx: ServerContext) => Promise<Resource[] | ListResourcesResult>;
92
+ /** Completion per template variable (`completion/complete` with a `ref/resource`). */
93
+ complete?: Record<string, CompleteResourceTemplateCallback>;
94
+ read: (ctx: ResourceContext) => Promise<ResourceReadOutcome>;
95
+ }
96
+ export type AnyResourceDefinition = ResourceDefinition | ResourceTemplateDefinition;
97
+ /** Identity helper for a static resource definition. */
98
+ export declare function defineResource(definition: ResourceDefinition): ResourceDefinition;
99
+ /** Identity helper for a resource template definition. */
100
+ export declare function defineResourceTemplate(definition: ResourceTemplateDefinition): ResourceTemplateDefinition;
101
+ export interface RegisterResourcesOptions {
102
+ /** The loaded env; required for `requires`. */
103
+ env?: LoadedEnv;
104
+ /** Register only these resource names. */
105
+ enabled?: readonly string[];
106
+ /** Server name in the degraded-mode message (default "this server"). */
107
+ serverName?: string;
108
+ /** Per-service wording for thrown errors (the `registerTools` signature). */
109
+ mapError?: MapError;
110
+ /** Server-wide read cap in bytes (default MCP_MAX_RESULT_BYTES); a definition's `maxBytes` wins. */
111
+ maxBytes?: number;
112
+ /**
113
+ * Advertise `resources.subscribe` and serve `resources/subscribe` / `resources/unsubscribe` (2025-era
114
+ * clients; 2026-07-28 clients subscribe through `subscriptions/listen`). Not advertised on a 2025-era
115
+ * stateless HTTP instance (pass `request`), where no update could ever be delivered.
116
+ */
117
+ subscribe?: boolean;
118
+ /** The factory's request context (lets `subscribe` skip 2025-era stateless HTTP). */
119
+ request?: RequestContext;
120
+ /** Runtime enable/disable state (see `createRuntimeSurface`). */
121
+ surface?: RuntimeSurface;
122
+ }
123
+ /** A text resource contents entry. */
124
+ export declare function textContents(uri: string, text: string, mimeType?: string): ReadResourceResult['contents'][number];
125
+ /** A binary resource contents entry (base64). */
126
+ export declare function blobContents(uri: string, data: Uint8Array, mimeType?: string): ReadResourceResult['contents'][number];
127
+ /** Map a read outcome onto a `ReadResourceResult` (shorthands, default mimeType). */
128
+ export declare function normalizeReadOutcome(outcome: ResourceReadOutcome, uri: string, mimeType?: string): ReadResourceResult | InputRequiredResult;
129
+ /** A `resource_link` content block for a tool result (the client reads it with `resources/read`). */
130
+ export declare function resourceLink(resource: {
131
+ uri: string;
132
+ name: string;
133
+ title?: string;
134
+ description?: string;
135
+ mimeType?: string;
136
+ size?: number;
137
+ }): ResourceLink;
138
+ /** An embedded `resource` content block (the contents inline in the tool result). */
139
+ export declare function embeddedResource(contents: ReadResourceResult['contents'][number]): EmbeddedResource;
140
+ /** Register `defs` on `server`; returns the SDK handles by name (`enable` / `disable` / `update` / `remove`). */
141
+ export declare function registerResources(server: McpServer, defs: readonly AnyResourceDefinition[], opts?: RegisterResourcesOptions): Map<string, RegisteredResource | RegisteredResourceTemplate>;
142
+ /**
143
+ * Advertise `resources.subscribe` and serve the 2025-era `resources/subscribe` / `resources/unsubscribe`
144
+ * on this instance (the subscribed URIs filter `notify.resourceUpdated` on a 2025-era connection).
145
+ * Call before the instance is connected. Idempotent.
146
+ */
147
+ export declare function enableResourceSubscriptions(server: McpServer): void;
148
+ export interface ResultSpillOptions {
149
+ /** URI prefix of spilled results (default `mcp-core://results/`); the template is `<prefix>{id}`. */
150
+ uriPrefix?: string;
151
+ /** How long a spilled result stays readable (default 15 minutes). */
152
+ ttlMs?: number;
153
+ /** Max spilled results kept (default 100; the oldest is dropped first). */
154
+ maxEntries?: number;
155
+ /** Max bytes of one spilled result (default 16 MiB); a larger one keeps the default isError. */
156
+ maxBytes?: number;
157
+ /** Max bytes of all spilled results together (default 64 MiB; the oldest is dropped first). */
158
+ maxTotalBytes?: number;
159
+ /** Resource name (default `tool-result`). */
160
+ name?: string;
161
+ /** Clock (tests). */
162
+ now?: () => number;
163
+ }
164
+ export interface ResultSpill {
165
+ /** Pass as `registerTools(..., { onOversize: spill.onOversize })`. */
166
+ onOversize: (info: OversizeInfo) => CallToolResult | undefined;
167
+ /** Register this template so clients can read the spilled results (`registerResources`). */
168
+ resource: ResourceTemplateDefinition;
169
+ /** Drop every spilled result. */
170
+ clear(): void;
171
+ }
172
+ /**
173
+ * Connect the tool result byte cap to resource links: an oversized result is kept in memory and the
174
+ * tool answers a short text plus a `resource_link` the client reads with `resources/read` (bounded by
175
+ * `maxBytes`, bound to the caller's `clientId`, expiring after `ttlMs`). In-memory, so on a
176
+ * multi-instance HTTP deployment the read must reach the same process (sticky routing) or the client
177
+ * gets "not found"; use a shared store in the host for that case.
178
+ */
179
+ export declare function createResultSpill(options?: ResultSpillOptions): ResultSpill;
180
+ export {};
181
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,302 @@
1
+ /**
2
+ * @novorb/mcp-core - Resources (static resources and URI templates), resource links, subscriptions
3
+ *
4
+ * `registerResources` mirrors `registerTools`: definitions go onto the SDK's own
5
+ * `McpServer.registerResource` (so `resources/list`, `resources/templates/list`, `resources/read`,
6
+ * template matching, completion of template variables and the `ResourceNotFoundError` are the SDK's),
7
+ * and mcp-core adds only what the SDK lacks:
8
+ *
9
+ * - one wrapper per resource: `Resource read: <uri or uri template>` / `Resource result: ...` log
10
+ * lines (name, template, duration, size; never the content and never the filled-in URI);
11
+ * - thrown errors become JSON-RPC errors through `mapError` (masked, never a stack);
12
+ * - degraded mode: a resource whose `requires` env keys are missing is still listed and answers the
13
+ * uniform `<server> is not configured: set <KEYS>`;
14
+ * - a size cap on every read (default `MCP_MAX_RESULT_BYTES`, per resource `maxBytes`): an oversized
15
+ * read is an actionable error, never a truncated document;
16
+ * - shorthand results (a string is text, bytes are a blob, both with the definition's `mimeType`);
17
+ * - `resources/subscribe` / `resources/unsubscribe` for 2025-era clients (`subscribe: true`); updates
18
+ * are published with `notify.resourceUpdated(uri)` (see `notifications.ts`);
19
+ * - the list pagination of `resources/list` and `resources/templates/list` (C1, `createMcpServer`).
20
+ *
21
+ * registerResources(server, [
22
+ * defineResource({ name: 'readme', uri: 'repo://readme', mimeType: 'text/markdown',
23
+ * read: async () => readme }),
24
+ * defineResourceTemplate({ name: 'file', uriTemplate: 'repo://files/{path}', mimeType: 'text/plain',
25
+ * complete: { path: (prefix) => paths.filter((p) => p.startsWith(prefix)) },
26
+ * read: async ({ variables }) => readFile(String(variables.path)) }),
27
+ * ], { env, serverName: 'repo-mcp', subscribe: true });
28
+ *
29
+ * Tools point at resources instead of inlining large payloads with `resourceLink(...)` /
30
+ * `embeddedResource(...)`, and `createResultSpill()` connects the tool result byte cap (`onOversize`)
31
+ * to a resource link automatically.
32
+ */
33
+ import { randomUUID } from 'node:crypto';
34
+ import { isInputRequiredResult, ProtocolError, ProtocolErrorCode, ResourceTemplate, } from '@modelcontextprotocol/server';
35
+ import { requestEra } from './client-input.js';
36
+ import { resolveLimits } from './limits.js';
37
+ import { bindToSurface, resourceSubscriptions } from './notifications.js';
38
+ import { toProtocolError } from './protocol-errors.js';
39
+ import { runWithRequestContext } from './protocol-logging.js';
40
+ import { notConfiguredMessage } from './tools.js';
41
+ import { getLogger } from './utils/logger.js';
42
+ /** Identity helper for a static resource definition. */
43
+ export function defineResource(definition) {
44
+ return definition;
45
+ }
46
+ /** Identity helper for a resource template definition. */
47
+ export function defineResourceTemplate(definition) {
48
+ return definition;
49
+ }
50
+ function isTemplate(def) {
51
+ return 'uriTemplate' in def;
52
+ }
53
+ function contentBytes(result) {
54
+ let bytes = 0;
55
+ for (const c of result.contents) {
56
+ if ('text' in c && typeof c.text === 'string')
57
+ bytes += Buffer.byteLength(c.text, 'utf8');
58
+ if ('blob' in c && typeof c.blob === 'string')
59
+ bytes += c.blob.length;
60
+ }
61
+ return bytes;
62
+ }
63
+ /** A text resource contents entry. */
64
+ export function textContents(uri, text, mimeType) {
65
+ return { uri, text, ...(mimeType !== undefined ? { mimeType } : {}) };
66
+ }
67
+ /** A binary resource contents entry (base64). */
68
+ export function blobContents(uri, data, mimeType) {
69
+ return { uri, blob: Buffer.from(data).toString('base64'), ...(mimeType !== undefined ? { mimeType } : {}) };
70
+ }
71
+ /** Map a read outcome onto a `ReadResourceResult` (shorthands, default mimeType). */
72
+ export function normalizeReadOutcome(outcome, uri, mimeType) {
73
+ if (typeof outcome === 'string')
74
+ return { contents: [textContents(uri, outcome, mimeType)] };
75
+ if (outcome instanceof Uint8Array)
76
+ return { contents: [blobContents(uri, outcome, mimeType)] };
77
+ if (isInputRequiredResult(outcome))
78
+ return outcome;
79
+ if (mimeType === undefined)
80
+ return outcome;
81
+ return { ...outcome, contents: outcome.contents.map((c) => (c.mimeType === undefined ? { ...c, mimeType } : c)) };
82
+ }
83
+ /** A `resource_link` content block for a tool result (the client reads it with `resources/read`). */
84
+ export function resourceLink(resource) {
85
+ return { type: 'resource_link', ...resource };
86
+ }
87
+ /** An embedded `resource` content block (the contents inline in the tool result). */
88
+ export function embeddedResource(contents) {
89
+ return { type: 'resource', resource: contents };
90
+ }
91
+ /** Register `defs` on `server`; returns the SDK handles by name (`enable` / `disable` / `update` / `remove`). */
92
+ export function registerResources(server, defs, opts = {}) {
93
+ const handles = new Map();
94
+ const enabled = opts.enabled ? new Set(opts.enabled) : undefined;
95
+ const serverName = opts.serverName ?? 'this server';
96
+ const declared = new Set(opts.env?.schema.map((s) => s.key));
97
+ for (const def of defs) {
98
+ if (enabled && !enabled.has(def.name))
99
+ continue;
100
+ const requires = def.requires ?? [];
101
+ if (requires.length > 0 && !opts.env) {
102
+ throw new Error(`registerResources: resource ${def.name} declares requires but no env was passed`);
103
+ }
104
+ const undeclared = requires.filter((k) => !declared.has(k));
105
+ if (undeclared.length > 0) {
106
+ throw new Error(`registerResources: resource ${def.name} requires ${undeclared.join(', ')}, which the env schema does not declare`);
107
+ }
108
+ const label = isTemplate(def) ? def.uriTemplate : def.uri;
109
+ const maxBytes = def.maxBytes ?? opts.maxBytes ?? resolveLimits().maxResultBytes;
110
+ const read = async (uri, variables, sdk) => {
111
+ const log = getLogger();
112
+ const started = Date.now();
113
+ log.info(`Resource read: ${label}`, 'Resources', { resource: def.name });
114
+ let isError = true;
115
+ let bytes = 0;
116
+ try {
117
+ const missing = requires.filter((k) => !opts.env?.has(k));
118
+ if (missing.length > 0) {
119
+ throw new ProtocolError(ProtocolErrorCode.InternalError, notConfiguredMessage(serverName, missing));
120
+ }
121
+ const ctx = {
122
+ name: def.name,
123
+ uri,
124
+ variables,
125
+ signal: sdk.mcpReq.signal,
126
+ era: requestEra(sdk),
127
+ logger: log,
128
+ sdk,
129
+ ...(sdk.http?.authInfo ? { authInfo: sdk.http.authInfo } : {}),
130
+ };
131
+ const result = normalizeReadOutcome(await def.read(ctx), uri.href, def.mimeType);
132
+ if (isInputRequiredResult(result)) {
133
+ isError = false;
134
+ return result;
135
+ }
136
+ bytes = contentBytes(result);
137
+ if (bytes > maxBytes) {
138
+ throw new ProtocolError(ProtocolErrorCode.InternalError, `${def.name}: the resource is ${bytes} bytes, over the ${maxBytes} byte limit per response; read a narrower resource (a smaller range or a sub-path)`);
139
+ }
140
+ isError = false;
141
+ return result;
142
+ }
143
+ catch (err) {
144
+ throw toProtocolError(err, opts.mapError);
145
+ }
146
+ finally {
147
+ const meta = { resource: def.name, isError, durationMs: Math.round(Date.now() - started), bytes };
148
+ if (isError)
149
+ log.warn(`Resource result: ${label}`, 'Resources', meta);
150
+ else
151
+ log.info(`Resource result: ${label}`, 'Resources', meta);
152
+ }
153
+ };
154
+ const scoped = (uri, variables, sdk) => runWithRequestContext(sdk, () => read(uri, variables, sdk));
155
+ const metadata = {
156
+ ...(def.title !== undefined ? { title: def.title } : {}),
157
+ ...(def.description !== undefined ? { description: def.description } : {}),
158
+ ...(def.mimeType !== undefined ? { mimeType: def.mimeType } : {}),
159
+ ...(def.size !== undefined ? { size: def.size } : {}),
160
+ ...(def.annotations !== undefined ? { annotations: def.annotations } : {}),
161
+ ...(def.icons !== undefined ? { icons: def.icons } : {}),
162
+ ...(def._meta !== undefined ? { _meta: def._meta } : {}),
163
+ ...(def.cacheHint !== undefined ? { cacheHint: def.cacheHint } : {}),
164
+ ...(def.scopeChallenge !== undefined ? { scopeChallenge: def.scopeChallenge } : {}),
165
+ };
166
+ let handle;
167
+ if (isTemplate(def)) {
168
+ const list = def.list;
169
+ const template = new ResourceTemplate(def.uriTemplate, {
170
+ list: list
171
+ ? async (ctx) => {
172
+ const listed = await list(ctx);
173
+ return Array.isArray(listed) ? { resources: listed } : listed;
174
+ }
175
+ : undefined,
176
+ ...(def.complete !== undefined ? { complete: def.complete } : {}),
177
+ });
178
+ handle = server.registerResource(def.name, template, metadata, (uri, variables, sdk) => scoped(uri, variables, sdk));
179
+ }
180
+ else {
181
+ handle = server.registerResource(def.name, def.uri, metadata, (uri, sdk) => scoped(uri, {}, sdk));
182
+ }
183
+ if (opts.surface)
184
+ bindToSurface(server, opts.surface, 'resource', def.name, handle);
185
+ handles.set(def.name, handle);
186
+ }
187
+ const legacyStatelessHttp = opts.request?.era === 'legacy' && opts.request.requestInfo !== undefined;
188
+ if (opts.subscribe && !legacyStatelessHttp)
189
+ enableResourceSubscriptions(server);
190
+ return handles;
191
+ }
192
+ const SUBSCRIBE_INSTALLED = Symbol.for('@novorb/mcp-core/resourceSubscribe');
193
+ /**
194
+ * Advertise `resources.subscribe` and serve the 2025-era `resources/subscribe` / `resources/unsubscribe`
195
+ * on this instance (the subscribed URIs filter `notify.resourceUpdated` on a 2025-era connection).
196
+ * Call before the instance is connected. Idempotent.
197
+ */
198
+ export function enableResourceSubscriptions(server) {
199
+ const low = server.server;
200
+ if (low[SUBSCRIBE_INSTALLED])
201
+ return;
202
+ low[SUBSCRIBE_INSTALLED] = true;
203
+ const listChanged = low.getCapabilities().resources?.listChanged;
204
+ low.registerCapabilities({ resources: { subscribe: true, ...(listChanged !== undefined ? { listChanged } : {}) } });
205
+ const subscriptions = resourceSubscriptions(server);
206
+ low.setRequestHandler('resources/subscribe', (request) => {
207
+ subscriptions.add(request.params.uri);
208
+ return {};
209
+ });
210
+ low.setRequestHandler('resources/unsubscribe', (request) => {
211
+ subscriptions.delete(request.params.uri);
212
+ return {};
213
+ });
214
+ }
215
+ /**
216
+ * Connect the tool result byte cap to resource links: an oversized result is kept in memory and the
217
+ * tool answers a short text plus a `resource_link` the client reads with `resources/read` (bounded by
218
+ * `maxBytes`, bound to the caller's `clientId`, expiring after `ttlMs`). In-memory, so on a
219
+ * multi-instance HTTP deployment the read must reach the same process (sticky routing) or the client
220
+ * gets "not found"; use a shared store in the host for that case.
221
+ */
222
+ export function createResultSpill(options = {}) {
223
+ const prefix = options.uriPrefix ?? 'mcp-core://results/';
224
+ const ttlMs = options.ttlMs ?? 15 * 60_000;
225
+ const maxEntries = options.maxEntries ?? 100;
226
+ const maxBytes = options.maxBytes ?? 16 * 1024 * 1024;
227
+ const maxTotalBytes = options.maxTotalBytes ?? 64 * 1024 * 1024;
228
+ const name = options.name ?? 'tool-result';
229
+ const now = options.now ?? Date.now;
230
+ const entries = new Map();
231
+ let totalBytes = 0;
232
+ const drop = (id) => {
233
+ const e = entries.get(id);
234
+ if (!e)
235
+ return;
236
+ totalBytes -= e.bytes;
237
+ entries.delete(id);
238
+ };
239
+ const prune = () => {
240
+ const t = now();
241
+ for (const [id, e] of entries)
242
+ if (e.expiresAt <= t)
243
+ drop(id);
244
+ while (entries.size > maxEntries || totalBytes > maxTotalBytes) {
245
+ const oldest = entries.keys().next().value;
246
+ if (oldest === undefined)
247
+ break;
248
+ drop(oldest);
249
+ }
250
+ };
251
+ return {
252
+ onOversize(info) {
253
+ const payload = info.result.structuredContent ?? info.result.content;
254
+ const json = JSON.stringify(payload);
255
+ const bytes = Buffer.byteLength(json, 'utf8');
256
+ if (bytes > maxBytes || bytes > maxTotalBytes)
257
+ return undefined;
258
+ const id = randomUUID();
259
+ entries.set(id, { json, bytes, owner: info.authInfo?.clientId, expiresAt: now() + ttlMs, tool: info.tool });
260
+ totalBytes += bytes;
261
+ prune();
262
+ const uri = `${prefix}${id}`;
263
+ return {
264
+ content: [
265
+ {
266
+ type: 'text',
267
+ text: `${info.tool}: the result is ${info.bytes} bytes, over the ${info.maxBytes} byte limit per response; it is available as the resource ${uri} for ${Math.round(ttlMs / 60_000)} minutes`,
268
+ },
269
+ resourceLink({
270
+ uri,
271
+ name,
272
+ mimeType: 'application/json',
273
+ size: bytes,
274
+ description: `Full result of ${info.tool}`,
275
+ }),
276
+ ],
277
+ };
278
+ },
279
+ resource: {
280
+ name,
281
+ uriTemplate: `${prefix}{id}`,
282
+ description: 'Tool results too large to return inline',
283
+ mimeType: 'application/json',
284
+ maxBytes,
285
+ read: async ({ variables, authInfo, uri }) => {
286
+ prune();
287
+ const id = String(variables.id);
288
+ const entry = entries.get(id);
289
+ // A foreign caller's entry answers exactly like a missing one (no existence leak).
290
+ if (!entry || (entry.owner !== undefined && entry.owner !== authInfo?.clientId)) {
291
+ throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Resource ${uri.href} not found or expired`);
292
+ }
293
+ return entry.json;
294
+ },
295
+ },
296
+ clear: () => {
297
+ entries.clear();
298
+ totalBytes = 0;
299
+ },
300
+ };
301
+ }
302
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @novorb/mcp-core - Tool result limits
3
+ *
4
+ * `registerTools` enforces two caps on every tool result, by default:
5
+ *
6
+ * - items: a list-shaped result (`structuredContent` of the `PagedResult` shape `{ items, nextCursor?,
7
+ * total? }`) carries at most `maxItems` items (MCP_MAX_RESULT_ITEMS, default 100; a smaller `limit`
8
+ * argument wins). The rest is reached through an opaque `nextCursor`.
9
+ * - bytes: the serialized result is at most `maxBytes` (MCP_MAX_RESULT_BYTES, default 256 KiB). A
10
+ * list-shaped result is first paged smaller; anything still too large becomes an actionable isError
11
+ * result (never a truncated, invalid or schema-breaking body).
12
+ *
13
+ * Cursors are stateless. mcp-core's cursor records the tool, a fingerprint of the other arguments, the
14
+ * offset inside the handler's page, and the handler's own cursor for that page; on the next call the
15
+ * handler is re-run with its own cursor (as `args.cursor` and `ctx.cursor`) and mcp-core serves the next
16
+ * slice, or wraps the handler's own `nextCursor` once its page is exhausted. A cursor for another tool or
17
+ * other arguments, or a malformed one, is refused (`Invalid cursor: ...`), so an edited cursor can only
18
+ * ever address the caller's own result set. The handler must be a deterministic read for a given cursor
19
+ * (list tools are).
20
+ */
21
+ import type { AuthInfo, CallToolResult, StandardSchemaWithJSON } from '@modelcontextprotocol/server';
22
+ /** Per-tool overrides of the response caps. */
23
+ export interface ToolLimits {
24
+ /** Max items in a list-shaped result. */
25
+ maxItems?: number;
26
+ /** Max serialized bytes of one result. */
27
+ maxBytes?: number;
28
+ }
29
+ /**
30
+ * A result that carries its payload under one `structuredContent` member (an envelope such as
31
+ * `{ data }`). The item cap applies to that member when it is an array or a PagedResult (refused, not
32
+ * paged: an envelope tool has no mcp-core cursor), a text block that only repeats it is counted once in
33
+ * the byte cap, and `hint` names the caller's real lever in both refusals.
34
+ */
35
+ export interface ResultEnvelope {
36
+ key: string;
37
+ /** Advice appended to the refusals, for example "page it with query.limit and query.offset". */
38
+ hint?: string;
39
+ }
40
+ /** What `onOversize` receives when a result cannot be brought under the byte cap. */
41
+ export interface OversizeInfo {
42
+ tool: string;
43
+ bytes: number;
44
+ maxBytes: number;
45
+ result: CallToolResult;
46
+ /** The caller, when the transport authenticated one (bind a spilled result to it). */
47
+ authInfo?: AuthInfo;
48
+ }
49
+ /** The decoded mcp-core tool cursor. */
50
+ export interface ToolCursor {
51
+ /** Offset inside the handler's page. */
52
+ o: number;
53
+ /** The handler's own cursor for that page (absent = its first page). */
54
+ c?: string;
55
+ }
56
+ /** A short fingerprint of the arguments other than `cursor` / `limit` (binds a cursor to its query). */
57
+ export declare function argsFingerprint(args: unknown): string;
58
+ /**
59
+ * Decode `cursor` as an mcp-core tool cursor. Returns undefined when it is not one (a handler's own
60
+ * cursor; only allowed when `strict` is false). Throws `InvalidCursorError` for a mismatch.
61
+ */
62
+ export declare function decodeToolCursor(tool: string, args: unknown, cursor: string, strict: boolean): ToolCursor | undefined;
63
+ /** The arguments handed to the handler: `cursor` = its own cursor (or none), `limit` capped. */
64
+ export declare function handlerArgs(args: unknown, decoded: ToolCursor | undefined, maxItems: number): unknown;
65
+ export interface EnforceContext {
66
+ tool: string;
67
+ /** The client's arguments (cursor and limit as sent). */
68
+ args: unknown;
69
+ decoded: ToolCursor | undefined;
70
+ maxItems: number;
71
+ maxBytes: number;
72
+ onOversize?: (info: OversizeInfo) => CallToolResult | undefined;
73
+ authInfo?: AuthInfo;
74
+ envelope?: ResultEnvelope;
75
+ }
76
+ /** Apply the item and byte caps to one handler result. */
77
+ export declare function enforceResultLimits(ctx: EnforceContext, result: CallToolResult): CallToolResult;
78
+ /** Whether an input schema declares `cursor` and `limit` properties (required for `paginated` tools). */
79
+ export declare function declaresPageArgs(schema: StandardSchemaWithJSON): boolean;
80
+ //# sourceMappingURL=result-limits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result-limits.d.ts","sourceRoot":"","sources":["../src/result-limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAIrG,+CAA+C;AAC/C,MAAM,WAAW,UAAU;IACzB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,gGAAgG;IAChG,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qFAAqF;AACrF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;IACvB,sFAAsF;IACtF,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,wCAAwC;IACxC,CAAC,EAAE,MAAM,CAAC;IACV,wEAAwE;IACxE,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAyBD,wGAAwG;AACxG,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAQrD;AAcD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CASrH;AAQD,gGAAgG;AAChG,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CASrG;AAUD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,cAAc,GAAG,SAAS,CAAC;IAChE,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAmFD,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,cAAc,GAAG,cAAc,CAqD/F;AAED,yGAAyG;AACzG,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CASxE"}