@corsenai/corsen-context 1.2.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/README.md CHANGED
@@ -1,27 +1,88 @@
1
- # @corsenai/corsen-context
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`.
4
-
5
- ```bash
6
- npm install @corsenai/corsen-context
7
- ```
8
-
9
- ```typescript
10
- import { CorsenContext, createInMemoryProvider } from '@corsenai/corsen-context';
11
-
12
- const cc = new CorsenContext(
13
- { siteUrl: 'https://example.com' },
14
- createInMemoryProvider([
15
- { url: 'https://example.com/', title: 'Home', description: 'Welcome', markdown: '# Home', metadata: {}, type: 'page' },
16
- ]),
17
- );
18
-
19
- const server = cc.createMCPServer();
20
- const result = await server.handleRequest(requestBody, clientIp);
21
- ```
22
-
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.
24
-
25
- - **Full docs:** https://github.com/CorsenAI/corsen-context#readme
26
- - **Security model:** [SECURITY.md](https://github.com/CorsenAI/corsen-context/blob/main/SECURITY.md)
27
- - **License:** MIT
1
+ # @corsenai/corsen-context
2
+
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
+
5
+ ```bash
6
+ npm install @corsenai/corsen-context
7
+ ```
8
+
9
+ ```typescript
10
+ import {
11
+ CorsenContext,
12
+ createInMemoryProvider,
13
+ generateWebMCPScript,
14
+ toWebMCPTools,
15
+ } from '@corsenai/corsen-context';
16
+
17
+ const cc = new CorsenContext(
18
+ { siteUrl: 'https://example.com' },
19
+ createInMemoryProvider([
20
+ {
21
+ url: 'https://example.com/',
22
+ title: 'Home',
23
+ description: 'Welcome',
24
+ markdown: '# Home',
25
+ metadata: {},
26
+ type: 'page',
27
+ },
28
+ ]),
29
+ );
30
+
31
+ const server = cc.createMCPServer();
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
+ );
69
+ ```
70
+
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.
85
+
86
+ - **Full docs:** https://github.com/CorsenAI/corsen-context#readme
87
+ - **Security model:** [SECURITY.md](https://github.com/CorsenAI/corsen-context/blob/main/SECURITY.md)
88
+ - **License:** MIT
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,36 +400,47 @@ 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
 
379
434
  /**
380
435
  * Single source of truth for version strings.
381
436
  *
382
- * Keep CORSEN_CONTEXT_VERSION in sync with each package.json `version` on release
383
- * (the release tooling does this). serverInfo and the CLI both read from here so
384
- * the version can never silently drift between what is published and what is
385
- * reported over MCP.
437
+ * CORSEN_CONTEXT_VERSION is bumped by hand on every release, in the same
438
+ * commit that updates the package.json versions. serverInfo and the CLI both
439
+ * read from here so the version can never silently drift between what is
440
+ * published and what is reported over MCP.
386
441
  */
387
442
  /** Corsen Context release version. */
388
- declare const CORSEN_CONTEXT_VERSION = "1.2.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
 
@@ -461,6 +516,65 @@ declare function mcpLinkTag(config: DiscoveryConfig): string;
461
516
  declare function generateLlmsTxt(config: ResolvedConfig, provider: ContentProvider): Promise<string>;
462
517
  declare function generateLlmsFullTxt(config: ResolvedConfig, provider: ContentProvider): Promise<string>;
463
518
 
519
+ /**
520
+ * WebMCP exposes the same tools to an agent running inside the page, through
521
+ * `document.modelContext`. The browser never reimplements a tool: it receives
522
+ * the definitions from the server and every `execute()` calls back into the
523
+ * existing MCP endpoint, so there is one implementation per runtime and one
524
+ * contract for every transport.
525
+ *
526
+ * Spec: https://webmachinelearning.github.io/webmcp/
527
+ */
528
+ /** Tool annotations defined by the WebMCP `ToolAnnotations` dictionary. */
529
+ interface WebMCPToolAnnotations {
530
+ /** Tool only reads state. Lets an agent decide when a call is safe. */
531
+ readOnlyHint: boolean;
532
+ /** Tool output is untrusted data, from the perspective of this site. */
533
+ untrustedContentHint: boolean;
534
+ }
535
+ interface WebMCPTool extends MCPToolDefinition {
536
+ annotations: WebMCPToolAnnotations;
537
+ }
538
+ interface WebMCPScriptConfig {
539
+ /**
540
+ * MCP endpoint the browser bridge calls. Defaults to `/v1/mcp`.
541
+ *
542
+ * The bridge is deliberately keyless: any credential embedded in a public
543
+ * page's script is disclosed to every visitor, so a key-protected endpoint
544
+ * should not enable the WebMCP bridge at all.
545
+ */
546
+ mcpEndpoint?: string;
547
+ }
548
+ /**
549
+ * Every tool Corsen Context exposes reads published site content, so all of
550
+ * them are read-only and all of them return untrusted data: page bodies come
551
+ * from authors, comments and imports, and an agent must treat that output as
552
+ * data rather than as instructions.
553
+ */
554
+ declare const WEBMCP_TOOL_ANNOTATIONS: Readonly<Record<string, WebMCPToolAnnotations>>;
555
+ /** Annotations for a tool. Unknown tools fall back to the safest pair. */
556
+ declare function webMCPAnnotationsFor(name: string): WebMCPToolAnnotations;
557
+ /** Attach WebMCP annotations to MCP tool definitions. */
558
+ declare function toWebMCPTools(tools: MCPToolDefinition[]): WebMCPTool[];
559
+ /**
560
+ * Build the inline script that registers the tools with the in-page agent.
561
+ *
562
+ * Deliberate constraints:
563
+ * - `exposedTo` is never set, so tools stay same-origin by default.
564
+ * - Registration is refused inside a frame: the Permissions Policy `tools`
565
+ * feature already defaults to `['self']`, and this keeps a same-origin
566
+ * frame from registering the set a second time.
567
+ * - The bridge only forwards calls to this site's own MCP endpoint; the page
568
+ * cannot introduce a tool the server does not already serve.
569
+ * - Every forwarded call carries the MCP-Protocol-Version header, which the
570
+ * endpoint requires on every request after initialize.
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.
575
+ */
576
+ declare function generateWebMCPScript(tools: WebMCPTool[], config?: WebMCPScriptConfig): string;
577
+
464
578
  declare function parseSitemap(sitemapUrl: string, maxPages?: number): Promise<SitemapEntry[]>;
465
579
  declare function discoverSitemap(siteUrl: string): Promise<string | null>;
466
580
 
@@ -500,18 +614,20 @@ declare class MemoryCache implements CacheDriver {
500
614
 
501
615
  /**
502
616
  * Redis-backed cache driver for distributed / multi-instance deployments.
503
- * 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.
504
619
  *
505
620
  * Usage:
506
621
  * import Redis from 'ioredis';
507
- * const redis = new Redis();
622
+ * import { adaptIORedisClient } from '@corsenai/corsen-context';
623
+ * const redis = adaptIORedisClient(new Redis());
508
624
  * const cache = new RedisCache(redis);
509
625
  * const ctx = new CorsenContext(config, provider, cache);
510
626
  */
511
627
  declare class RedisCache implements CacheDriver {
512
628
  private redis;
513
629
  private prefix;
514
- constructor(redis: RedisClient, options?: {
630
+ constructor(redis: RedisCacheClient, options?: {
515
631
  prefix?: string;
516
632
  });
517
633
  get<T>(key: string): Promise<T | null>;
@@ -532,13 +648,13 @@ declare class RedisCache implements CacheDriver {
532
648
  * still occupies a slot), which keeps the overshoot small and bounded. For a
533
649
  * strict guarantee, back this with a client exposing an atomic script (Lua).
534
650
  *
535
- * Compatible with ioredis, @upstash/redis, or any client implementing RedisClient.
651
+ * Accepts @upstash/redis directly. Wrap ioredis with adaptIORedisClient().
536
652
  */
537
653
  declare class RedisRateLimitStore implements RateLimitStore {
538
654
  private redis;
539
655
  private prefix;
540
656
  private windowMs;
541
- constructor(redis: RedisClient, options?: {
657
+ constructor(redis: RedisRateLimitClient, options?: {
542
658
  prefix?: string;
543
659
  windowMs?: number;
544
660
  });
@@ -557,6 +673,12 @@ declare class RedisRateLimitStore implements RateLimitStore {
557
673
  cleanup(): Promise<void>;
558
674
  }
559
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
+
560
682
  /**
561
683
  * Check if an IP address is private/internal.
562
684
  * Sync function — works on resolved IPs, not hostnames.
@@ -648,9 +770,9 @@ declare function extractClientIp(headers: Record<string, string | string[] | und
648
770
  */
649
771
  declare function buildRateLimitKey(clientIp: string, apiKey?: string): string;
650
772
  declare const searchParamsSchema: z.ZodObject<{
651
- query: z.ZodString;
773
+ query: z.ZodEffects<z.ZodString, string, string>;
652
774
  limit: z.ZodDefault<z.ZodNumber>;
653
- }, "strip", z.ZodTypeAny, {
775
+ }, "strict", z.ZodTypeAny, {
654
776
  query: string;
655
777
  limit: number;
656
778
  }, {
@@ -658,17 +780,17 @@ declare const searchParamsSchema: z.ZodObject<{
658
780
  limit?: number | undefined;
659
781
  }>;
660
782
  declare const getPageParamsSchema: z.ZodObject<{
661
- uri: z.ZodString;
662
- }, "strip", z.ZodTypeAny, {
783
+ uri: z.ZodEffects<z.ZodString, string, string>;
784
+ }, "strict", z.ZodTypeAny, {
663
785
  uri: string;
664
786
  }, {
665
787
  uri: string;
666
788
  }>;
667
789
  declare const listContentParamsSchema: z.ZodObject<{
668
- type: z.ZodDefault<z.ZodString>;
790
+ type: z.ZodDefault<z.ZodEffects<z.ZodString, string, string>>;
669
791
  page: z.ZodDefault<z.ZodNumber>;
670
792
  limit: z.ZodDefault<z.ZodNumber>;
671
- }, "strip", z.ZodTypeAny, {
793
+ }, "strict", z.ZodTypeAny, {
672
794
  type: string;
673
795
  page: number;
674
796
  limit: number;
@@ -753,7 +875,7 @@ declare class CorsenContext {
753
875
  }): MCPServer;
754
876
  /** Drop the cached body for a single page URL (wire to CMS update/delete hooks). */
755
877
  invalidatePage(url: string): Promise<void>;
756
- /** Clear all cached MCP responses. Call after bulk content changes. */
878
+ /** Clear all cached page bodies. Call after bulk content changes. */
757
879
  clearCache(): Promise<void>;
758
880
  discoverSitemap(url?: string): Promise<string | null>;
759
881
  parseSitemap(sitemapUrl: string): Promise<SitemapEntry[]>;
@@ -774,6 +896,7 @@ declare class CorsenContext {
774
896
  static: {
775
897
  generateLlmsTxt: boolean;
776
898
  includeFullContent: boolean;
899
+ maxOutputBytes: number;
777
900
  };
778
901
  security: {
779
902
  rateLimit: number;
@@ -794,4 +917,4 @@ declare class CorsenContext {
794
917
  };
795
918
  }
796
919
 
797
- 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, buildRateLimitKey, corsenContextConfigSchema, createInMemoryProvider, createLogger, createSitemapProvider, discoverSitemap, extractClientIp, extractMetadata, filterPublicPages, filterPublicSearchResults, generateLlmsFullTxt, generateLlmsTxt, generateRobotsTxt, generateWellKnownMcp, getLogger, getPageParamsSchema, hashApiKey, htmlToMarkdown, isPrivateIp, isPrivateUrl, isPublicListItem, isPublicPageContent, listContentParamsSchema, mcpLinkTag, mcpLogger, parseSitemap, resolveConfig, resolvePublicPageUrl, safeFetch, searchParamsSchema, securityLogger, setLogger, validateApiKey, validateHost, validateOrigin };
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 };