@corsenai/corsen-context 1.3.0 → 2.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.
package/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Corsen AI
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Corsen AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,26 +1,87 @@
1
1
  # @corsenai/corsen-context
2
2
 
3
- The core engine of **[Corsen Context](https://github.com/CorsenAI/corsen-context)** — the Universal AI Context Layer that makes any website AI-native with an MCP server + enhanced `llms.txt`.
3
+ The core engine of **[Corsen Context](https://github.com/CorsenAI/corsen-context)** — owner-controlled public content through MCP, WebMCP, and bounded `llms.txt` output.
4
4
 
5
5
  ```bash
6
6
  npm install @corsenai/corsen-context
7
7
  ```
8
8
 
9
9
  ```typescript
10
- import { CorsenContext, createInMemoryProvider } from '@corsenai/corsen-context';
10
+ import {
11
+ CorsenContext,
12
+ createInMemoryProvider,
13
+ generateWebMCPScript,
14
+ toWebMCPTools,
15
+ } from '@corsenai/corsen-context';
11
16
 
12
17
  const cc = new CorsenContext(
13
18
  { siteUrl: 'https://example.com' },
14
19
  createInMemoryProvider([
15
- { url: 'https://example.com/', title: 'Home', description: 'Welcome', markdown: '# Home', metadata: {}, type: 'page' },
20
+ {
21
+ url: 'https://example.com/',
22
+ title: 'Home',
23
+ description: 'Welcome',
24
+ markdown: '# Home',
25
+ metadata: {},
26
+ type: 'page',
27
+ },
16
28
  ]),
17
29
  );
18
30
 
19
31
  const server = cc.createMCPServer();
20
32
  const result = await server.handleRequest(requestBody, clientIp);
33
+
34
+ // Serve this string as GET /webmcp.js on the same origin as POST /v1/mcp.
35
+ const webmcpScript = generateWebMCPScript(toWebMCPTools(server.getToolDefinitions()), {
36
+ mcpEndpoint: '/v1/mcp',
37
+ });
38
+ ```
39
+
40
+ Load `/webmcp.js` from the site's pages with
41
+ `<script src="/webmcp.js" defer></script>`. The bridge registers the four
42
+ tools through `document.modelContext` and forwards calls to the same-origin MCP
43
+ endpoint. It intentionally sends no API key or visitor credentials: use a
44
+ public, read-only, rate-limited endpoint for WebMCP, or omit the browser bridge
45
+ when MCP requires server-side authentication.
46
+
47
+ This package provides the framework-agnostic core: the MCP JSON-RPC 2.0 server,
48
+ WebMCP bridge generation, `llms.txt` generators, HTML-to-Markdown converter,
49
+ SSRF-safe fetching, rate limiting, caching, and the content-access policy. A
50
+ working site integration must also implement a `ContentProvider` backed only
51
+ by the public content it intends to expose.
52
+
53
+ The resolved configuration enforces these owner controls and bounds:
54
+
55
+ ```typescript
56
+ const cc = new CorsenContext(
57
+ {
58
+ siteUrl: 'https://example.com',
59
+ mcp: { enabled: true },
60
+ content: { maxPages: 500 }, // 1–5000
61
+ static: {
62
+ generateLlmsTxt: true,
63
+ includeFullContent: false,
64
+ maxOutputBytes: 5_242_880, // 64 KiB–10 MiB
65
+ },
66
+ },
67
+ provider,
68
+ );
21
69
  ```
22
70
 
23
- This package provides the framework-agnostic core: the MCP JSON-RPC 2.0 server, `llms.txt` generators, HTML→Markdown converter, SSRF-safe fetching, rate limiting, caching, and the content-access policy.
71
+ With `mcp.enabled: false`, direct MCP dispatch is rejected before the provider
72
+ is invoked; adapters also use this value to return `404` from their MCP and
73
+ WebMCP routes. With `static.generateLlmsTxt: false`, both `CorsenContext`
74
+ generation methods refuse generation. Full-content generation additionally
75
+ requires
76
+ `static.includeFullContent: true`, which is off by default. Both static outputs
77
+ are capped at `maxOutputBytes` without splitting a UTF-8 code point and append
78
+ a truncation notice when the complete output would exceed the limit.
79
+ Full-content iteration returns as soon as the next block would exceed the budget.
80
+
81
+ Static headings, labels, descriptions, dates, and Markdown destinations are
82
+ normalized and escaped. The provider's page-body `markdown` is passed through
83
+ unchanged and remains untrusted site-authored content; this package does not
84
+ claim to neutralize it.
24
85
 
25
86
  - **Full docs:** https://github.com/CorsenAI/corsen-context#readme
26
87
  - **Security model:** [SECURITY.md](https://github.com/CorsenAI/corsen-context/blob/main/SECURITY.md)
package/dist/index.d.mts CHANGED
@@ -41,7 +41,7 @@ interface JSONRPCRequest {
41
41
  jsonrpc: '2.0';
42
42
  method: string;
43
43
  params?: Record<string, unknown>;
44
- id?: string | number | null;
44
+ id?: string | number;
45
45
  }
46
46
  interface JSONRPCResponse {
47
47
  jsonrpc: '2.0';
@@ -61,6 +61,7 @@ interface MCPToolDefinition {
61
61
  type: 'object';
62
62
  properties: Record<string, unknown>;
63
63
  required?: string[];
64
+ additionalProperties?: boolean;
64
65
  };
65
66
  }
66
67
  interface MCPResourceDefinition {
@@ -95,22 +96,50 @@ interface RateLimitStore {
95
96
  addTimestamp(key: string, timestamp: number): Promise<void>;
96
97
  cleanup(): Promise<void>;
97
98
  /**
98
- * Optional atomic prune + record + count. When present, the RateLimiter uses
99
- * this instead of the getTimestamps()/addTimestamp() pair to avoid the
100
- * check-then-add race. Returns counts that INCLUDE the current request.
99
+ * Optional combined record + count path. When present, the RateLimiter uses
100
+ * it instead of getTimestamps()/addTimestamp(). Implementations document
101
+ * whether their backing store makes the whole operation atomic. Returned
102
+ * counts INCLUDE the current request.
101
103
  */
102
104
  hit?(key: string, windowStart: number, burstWindowStart: number, now: number): Promise<{
103
105
  windowCount: number;
104
106
  burstCount: number;
105
107
  }>;
106
108
  }
107
- interface RedisClient {
108
- get(key: string): Promise<string | null>;
109
- set(key: string, value: string, options?: {
110
- ex?: number;
111
- } | 'EX', ttlSeconds?: number): Promise<unknown>;
109
+ /** Commands required by RedisCache. SET with EX makes value + TTL one atomic write. */
110
+ interface RedisCacheClient {
111
+ get(key: string): Promise<unknown | null>;
112
+ set(key: string, value: string, options: {
113
+ ex: number;
114
+ }): Promise<unknown>;
115
+ del(...keys: string[]): Promise<number>;
116
+ }
117
+ /** Numeric sorted-set bound accepted by Redis and the Upstash TypeScript SDK. */
118
+ type RedisScoreBoundary = number | '-inf' | '+inf' | `(${number}`;
119
+ /**
120
+ * Upstash-compatible sorted-set shape used by RedisRateLimitStore. ioredis
121
+ * callers can use adaptIORedisClient() to normalize its variadic commands.
122
+ */
123
+ interface RedisRateLimitClient {
124
+ expire(key: string, seconds: number): Promise<number | boolean>;
125
+ zadd(key: string, entry: {
126
+ score: number;
127
+ member: string;
128
+ }): Promise<number | null>;
129
+ zremrangebyscore(key: string, min: RedisScoreBoundary, max: RedisScoreBoundary): Promise<number>;
130
+ zcard(key: string): Promise<number>;
131
+ zrange(key: string, min: RedisScoreBoundary, max: RedisScoreBoundary, options: {
132
+ byScore: true;
133
+ }): Promise<string[]>;
134
+ }
135
+ /** Direct @upstash/redis-compatible client contract. */
136
+ interface RedisClient extends RedisCacheClient, RedisRateLimitClient {
137
+ }
138
+ /** Minimal ioredis surface normalized by adaptIORedisClient(). */
139
+ interface IORedisClient {
140
+ get(key: string): Promise<unknown | null>;
141
+ set(key: string, value: string, mode: 'EX', ttlSeconds: number): Promise<unknown>;
112
142
  del(...keys: string[]): Promise<number>;
113
- incr(key: string): Promise<number>;
114
143
  expire(key: string, seconds: number): Promise<number | boolean>;
115
144
  zadd(key: string, score: number, member: string): Promise<number>;
116
145
  zremrangebyscore(key: string, min: number | string, max: number | string): Promise<number>;
@@ -201,12 +230,15 @@ declare const corsenContextConfigSchema: z.ZodObject<{
201
230
  static: z.ZodDefault<z.ZodObject<{
202
231
  generateLlmsTxt: z.ZodDefault<z.ZodBoolean>;
203
232
  includeFullContent: z.ZodDefault<z.ZodBoolean>;
233
+ maxOutputBytes: z.ZodDefault<z.ZodNumber>;
204
234
  }, "strip", z.ZodTypeAny, {
205
235
  generateLlmsTxt: boolean;
206
236
  includeFullContent: boolean;
237
+ maxOutputBytes: number;
207
238
  }, {
208
239
  generateLlmsTxt?: boolean | undefined;
209
240
  includeFullContent?: boolean | undefined;
241
+ maxOutputBytes?: number | undefined;
210
242
  }>>;
211
243
  security: z.ZodDefault<z.ZodObject<{
212
244
  rateLimit: z.ZodDefault<z.ZodNumber>;
@@ -259,6 +291,7 @@ declare const corsenContextConfigSchema: z.ZodObject<{
259
291
  static: {
260
292
  generateLlmsTxt: boolean;
261
293
  includeFullContent: boolean;
294
+ maxOutputBytes: number;
262
295
  };
263
296
  security: {
264
297
  rateLimit: number;
@@ -293,6 +326,7 @@ declare const corsenContextConfigSchema: z.ZodObject<{
293
326
  static?: {
294
327
  generateLlmsTxt?: boolean | undefined;
295
328
  includeFullContent?: boolean | undefined;
329
+ maxOutputBytes?: number | undefined;
296
330
  } | undefined;
297
331
  security?: {
298
332
  rateLimit?: number | undefined;
@@ -326,6 +360,7 @@ declare class MCPServer {
326
360
  private provider;
327
361
  private rateLimiter;
328
362
  private cache;
363
+ private cacheNamespace;
329
364
  private log;
330
365
  constructor(config: ResolvedConfig, provider: ContentProvider, options?: {
331
366
  cache?: CacheDriver;
@@ -334,6 +369,15 @@ declare class MCPServer {
334
369
  });
335
370
  getSecurityHeaders(): Record<string, string>;
336
371
  getCorsHeaders(origin?: string): Record<string, string>;
372
+ /**
373
+ * Validate a browser Origin for the Streamable HTTP endpoint.
374
+ *
375
+ * Non-browser clients commonly omit Origin and remain accepted. When an
376
+ * Origin is present, MCP requires validation to prevent DNS rebinding. The
377
+ * canonical site origin is always allowed; operators can add explicit
378
+ * browser origins through security.allowedOrigins.
379
+ */
380
+ validateRequestOrigin(origin?: string): boolean;
337
381
  checkRateLimit(clientIp: string, apiKey?: string): Promise<{
338
382
  allowed: boolean;
339
383
  headers: Record<string, string>;
@@ -356,23 +400,34 @@ declare class MCPServer {
356
400
  private cacheSet;
357
401
  /**
358
402
  * Drop the cached body for a single page URL. Call this from your CMS's
359
- * publish/update/delete hooks so edits and unpublishes propagate before the
360
- * TTL expires (otherwise stale content can be served for up to cache.ttl).
403
+ * publish/update/delete hooks. Aggregate surfaces are intentionally read
404
+ * through so an unpublished URL is not retained behind an unenumerable key.
361
405
  */
362
406
  invalidatePage(url: string): Promise<void>;
363
407
  /**
364
- * Clear all cached MCP responses (search, page, list, sitemap). Call after
365
- * bulk content changes. No-op for cache drivers without prefix enumeration
366
- * (see RedisCache.clear notes).
408
+ * Clear all cached page bodies. Cache drivers that cannot prove a complete
409
+ * purge reject instead of reporting success.
367
410
  */
368
411
  clearCache(): Promise<void>;
369
- searchSite(query: string, limit?: number): Promise<{} | undefined>;
412
+ searchSite(query: string, limit?: number): Promise<SearchResult[]>;
370
413
  getPageContent(uri: string): Promise<{} | null | undefined>;
371
- listContent(type: string, page?: number, limit?: number): Promise<{} | undefined>;
372
- getSitemap(): Promise<{} | undefined>;
414
+ listContent(type: string, page?: number, limit?: number): Promise<{
415
+ items: ContentListItem[];
416
+ total: number;
417
+ page: number;
418
+ limit: number;
419
+ hasMore: boolean;
420
+ }>;
421
+ getSitemap(): Promise<{
422
+ url: string;
423
+ title: string;
424
+ type: string;
425
+ lastModified: string | undefined;
426
+ }[]>;
373
427
  getToolDefinitions(): MCPToolDefinition[];
374
428
  getCapabilities(): MCPCapabilities;
375
429
  private successResponse;
430
+ private toolErrorResponse;
376
431
  private errorResponse;
377
432
  }
378
433
 
@@ -385,7 +440,7 @@ declare class MCPServer {
385
440
  * published and what is reported over MCP.
386
441
  */
387
442
  /** Corsen Context release version. */
388
- declare const CORSEN_CONTEXT_VERSION = "1.3.0";
443
+ declare const CORSEN_CONTEXT_VERSION = "2.0.0";
389
444
  /** MCP protocol version implemented by this server. */
390
445
  declare const MCP_PROTOCOL_VERSION = "2025-11-25";
391
446
 
@@ -513,9 +568,10 @@ declare function toWebMCPTools(tools: MCPToolDefinition[]): WebMCPTool[];
513
568
  * cannot introduce a tool the server does not already serve.
514
569
  * - Every forwarded call carries the MCP-Protocol-Version header, which the
515
570
  * endpoint requires on every request after initialize.
516
- * - Chrome 153+ passes an AbortSignal as execute's second argument; the
517
- * bridge forwards it to fetch, so a cancelled execution aborts the
518
- * in-flight request instead of leaving work running.
571
+ * - Chrome 153+ passes an AbortSignal as execute's second argument. Each
572
+ * caller can stop waiting for the shared handshake, and its own tool fetch
573
+ * receives that signal. The handshake itself uses an independent timeout so
574
+ * cancelling one concurrent execution cannot fail every other caller.
519
575
  */
520
576
  declare function generateWebMCPScript(tools: WebMCPTool[], config?: WebMCPScriptConfig): string;
521
577
 
@@ -558,18 +614,20 @@ declare class MemoryCache implements CacheDriver {
558
614
 
559
615
  /**
560
616
  * Redis-backed cache driver for distributed / multi-instance deployments.
561
- * Compatible with ioredis, @upstash/redis, or any client implementing RedisClient.
617
+ * Accepts @upstash/redis directly. Wrap ioredis with adaptIORedisClient().
618
+ * Custom RedisCacheClient implementations must expose atomic SET with EX.
562
619
  *
563
620
  * Usage:
564
621
  * import Redis from 'ioredis';
565
- * const redis = new Redis();
622
+ * import { adaptIORedisClient } from '@corsenai/corsen-context';
623
+ * const redis = adaptIORedisClient(new Redis());
566
624
  * const cache = new RedisCache(redis);
567
625
  * const ctx = new CorsenContext(config, provider, cache);
568
626
  */
569
627
  declare class RedisCache implements CacheDriver {
570
628
  private redis;
571
629
  private prefix;
572
- constructor(redis: RedisClient, options?: {
630
+ constructor(redis: RedisCacheClient, options?: {
573
631
  prefix?: string;
574
632
  });
575
633
  get<T>(key: string): Promise<T | null>;
@@ -590,13 +648,13 @@ declare class RedisCache implements CacheDriver {
590
648
  * still occupies a slot), which keeps the overshoot small and bounded. For a
591
649
  * strict guarantee, back this with a client exposing an atomic script (Lua).
592
650
  *
593
- * Compatible with ioredis, @upstash/redis, or any client implementing RedisClient.
651
+ * Accepts @upstash/redis directly. Wrap ioredis with adaptIORedisClient().
594
652
  */
595
653
  declare class RedisRateLimitStore implements RateLimitStore {
596
654
  private redis;
597
655
  private prefix;
598
656
  private windowMs;
599
- constructor(redis: RedisClient, options?: {
657
+ constructor(redis: RedisRateLimitClient, options?: {
600
658
  prefix?: string;
601
659
  windowMs?: number;
602
660
  });
@@ -615,6 +673,12 @@ declare class RedisRateLimitStore implements RateLimitStore {
615
673
  cleanup(): Promise<void>;
616
674
  }
617
675
 
676
+ /**
677
+ * Normalize ioredis's variadic sorted-set API to the Upstash-compatible
678
+ * RedisClient contract used by the core stores.
679
+ */
680
+ declare function adaptIORedisClient(redis: IORedisClient): RedisClient;
681
+
618
682
  /**
619
683
  * Check if an IP address is private/internal.
620
684
  * Sync function — works on resolved IPs, not hostnames.
@@ -706,9 +770,9 @@ declare function extractClientIp(headers: Record<string, string | string[] | und
706
770
  */
707
771
  declare function buildRateLimitKey(clientIp: string, apiKey?: string): string;
708
772
  declare const searchParamsSchema: z.ZodObject<{
709
- query: z.ZodString;
773
+ query: z.ZodEffects<z.ZodString, string, string>;
710
774
  limit: z.ZodDefault<z.ZodNumber>;
711
- }, "strip", z.ZodTypeAny, {
775
+ }, "strict", z.ZodTypeAny, {
712
776
  query: string;
713
777
  limit: number;
714
778
  }, {
@@ -716,17 +780,17 @@ declare const searchParamsSchema: z.ZodObject<{
716
780
  limit?: number | undefined;
717
781
  }>;
718
782
  declare const getPageParamsSchema: z.ZodObject<{
719
- uri: z.ZodString;
720
- }, "strip", z.ZodTypeAny, {
783
+ uri: z.ZodEffects<z.ZodString, string, string>;
784
+ }, "strict", z.ZodTypeAny, {
721
785
  uri: string;
722
786
  }, {
723
787
  uri: string;
724
788
  }>;
725
789
  declare const listContentParamsSchema: z.ZodObject<{
726
- type: z.ZodDefault<z.ZodString>;
790
+ type: z.ZodDefault<z.ZodEffects<z.ZodString, string, string>>;
727
791
  page: z.ZodDefault<z.ZodNumber>;
728
792
  limit: z.ZodDefault<z.ZodNumber>;
729
- }, "strip", z.ZodTypeAny, {
793
+ }, "strict", z.ZodTypeAny, {
730
794
  type: string;
731
795
  page: number;
732
796
  limit: number;
@@ -811,7 +875,7 @@ declare class CorsenContext {
811
875
  }): MCPServer;
812
876
  /** Drop the cached body for a single page URL (wire to CMS update/delete hooks). */
813
877
  invalidatePage(url: string): Promise<void>;
814
- /** Clear all cached MCP responses. Call after bulk content changes. */
878
+ /** Clear all cached page bodies. Call after bulk content changes. */
815
879
  clearCache(): Promise<void>;
816
880
  discoverSitemap(url?: string): Promise<string | null>;
817
881
  parseSitemap(sitemapUrl: string): Promise<SitemapEntry[]>;
@@ -832,6 +896,7 @@ declare class CorsenContext {
832
896
  static: {
833
897
  generateLlmsTxt: boolean;
834
898
  includeFullContent: boolean;
899
+ maxOutputBytes: number;
835
900
  };
836
901
  security: {
837
902
  rateLimit: number;
@@ -852,4 +917,4 @@ declare class CorsenContext {
852
917
  };
853
918
  }
854
919
 
855
- export { API_VERSION, ApiKeyManager, type ApiKeyRecord, CORSEN_CONTEXT_VERSION, CREDIT_LINE, type CacheDriver, type ContentList, type ContentListItem, type ContentProvider, CorsenContext, type CorsenContextConfig, type DiscoveryConfig, type InMemoryPage, type JSONRPCRequest, type JSONRPCResponse, JSONRPC_ERRORS, type LogLevel, type Logger, type LoggerOptions, MAX_BODY_SIZE, MAX_JSON_DEPTH, type MCPCapabilities, type MCPResourceDefinition, MCPServer, type MCPToolDefinition, MCP_PROTOCOL_VERSION, MemoryCache, MemoryRateLimitStore, type PageContent, REQUEST_TIMEOUT_MS, type RateLimitResult, type RateLimitStore, RateLimiter, RedisCache, type RedisClient, RedisRateLimitStore, type ResolvedConfig, SECURITY_HEADERS, type SearchResult, type SitemapEntry, WEBMCP_TOOL_ANNOTATIONS, type WebMCPScriptConfig, type WebMCPTool, type WebMCPToolAnnotations, buildRateLimitKey, corsenContextConfigSchema, createInMemoryProvider, createLogger, createSitemapProvider, discoverSitemap, extractClientIp, extractMetadata, filterPublicPages, filterPublicSearchResults, generateLlmsFullTxt, generateLlmsTxt, generateRobotsTxt, generateWebMCPScript, generateWellKnownMcp, getLogger, getPageParamsSchema, hashApiKey, htmlToMarkdown, isPrivateIp, isPrivateUrl, isPublicListItem, isPublicPageContent, listContentParamsSchema, mcpLinkTag, mcpLogger, parseSitemap, resolveConfig, resolvePublicPageUrl, safeFetch, searchParamsSchema, securityLogger, setLogger, toWebMCPTools, validateApiKey, validateHost, validateOrigin, webMCPAnnotationsFor };
920
+ export { API_VERSION, ApiKeyManager, type ApiKeyRecord, CORSEN_CONTEXT_VERSION, CREDIT_LINE, type CacheDriver, type ContentList, type ContentListItem, type ContentProvider, CorsenContext, type CorsenContextConfig, type DiscoveryConfig, type IORedisClient, type InMemoryPage, type JSONRPCRequest, type JSONRPCResponse, JSONRPC_ERRORS, type LogLevel, type Logger, type LoggerOptions, MAX_BODY_SIZE, MAX_JSON_DEPTH, type MCPCapabilities, type MCPResourceDefinition, MCPServer, type MCPToolDefinition, MCP_PROTOCOL_VERSION, MemoryCache, MemoryRateLimitStore, type PageContent, REQUEST_TIMEOUT_MS, type RateLimitResult, type RateLimitStore, RateLimiter, RedisCache, type RedisCacheClient, type RedisClient, type RedisRateLimitClient, RedisRateLimitStore, type ResolvedConfig, SECURITY_HEADERS, type SearchResult, type SitemapEntry, WEBMCP_TOOL_ANNOTATIONS, type WebMCPScriptConfig, type WebMCPTool, type WebMCPToolAnnotations, adaptIORedisClient, buildRateLimitKey, corsenContextConfigSchema, createInMemoryProvider, createLogger, createSitemapProvider, discoverSitemap, extractClientIp, extractMetadata, filterPublicPages, filterPublicSearchResults, generateLlmsFullTxt, generateLlmsTxt, generateRobotsTxt, generateWebMCPScript, generateWellKnownMcp, getLogger, getPageParamsSchema, hashApiKey, htmlToMarkdown, isPrivateIp, isPrivateUrl, isPublicListItem, isPublicPageContent, listContentParamsSchema, mcpLinkTag, mcpLogger, parseSitemap, resolveConfig, resolvePublicPageUrl, safeFetch, searchParamsSchema, securityLogger, setLogger, toWebMCPTools, validateApiKey, validateHost, validateOrigin, webMCPAnnotationsFor };