@casys/mcp-server 0.11.0 → 0.13.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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Middleware module for ConcurrentMCPServer.
2
+ * Middleware module for McpApp.
3
3
  *
4
4
  * @module lib/server/middleware
5
5
  */
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Rate limiting middleware.
3
3
  *
4
- * Extracted from ConcurrentMCPServer's inline rate limit logic.
4
+ * Extracted from McpApp's inline rate limit logic.
5
5
  *
6
6
  * @module lib/server/middleware/rate-limit
7
7
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Middleware pipeline types for ConcurrentMCPServer.
2
+ * Middleware pipeline types for McpApp.
3
3
  *
4
4
  * Provides an onion-model middleware system (similar to Koa/Hono)
5
5
  * where each middleware wraps the next, enabling before/after logic.
@@ -2,7 +2,7 @@
2
2
  * Server Metrics Collector for @casys/mcp-server
3
3
  *
4
4
  * In-memory counters, histograms, and gauges with Prometheus text format export.
5
- * Designed to be embedded in ConcurrentMCPServer — no external dependencies.
5
+ * Designed to be embedded in McpApp — no external dependencies.
6
6
  *
7
7
  * @module lib/server/observability/metrics
8
8
  */
@@ -13,6 +13,8 @@ export interface CspOptions {
13
13
  readonly scriptSources?: readonly string[];
14
14
  /** Additional allowed connect sources (e.g. WebSocket endpoints). */
15
15
  readonly connectSources?: readonly string[];
16
+ /** Additional allowed image sources (e.g. tile servers). */
17
+ readonly imgSources?: readonly string[];
16
18
  /** Additional allowed frame ancestors. */
17
19
  readonly frameAncestors?: readonly string[];
18
20
  /**
@@ -49,7 +51,7 @@ export function buildCspHeader(options: CspOptions = {}): string {
49
51
  `default-src 'none'`,
50
52
  `script-src ${scriptSrc}`,
51
53
  `style-src 'self'${inlineDirective}`,
52
- `img-src 'self' data:`,
54
+ `img-src 'self' data: ${(options.imgSources ?? []).join(" ")}`.trim(),
53
55
  `font-src 'self'`,
54
56
  `connect-src ${connectSrc}`,
55
57
  `frame-ancestors ${frameAncestors}`,
package/src/types.ts CHANGED
@@ -45,9 +45,9 @@ export interface RateLimitContext {
45
45
  }
46
46
 
47
47
  /**
48
- * Configuration options for ConcurrentMCPServer
48
+ * Configuration options for McpApp
49
49
  */
50
- export interface ConcurrentServerOptions {
50
+ export interface McpAppOptions {
51
51
  /** Server name (shown in MCP protocol) */
52
52
  name: string;
53
53
 
@@ -78,12 +78,29 @@ export interface ConcurrentServerOptions {
78
78
  /** Enable sampling support for agentic tools (default: false) */
79
79
  enableSampling?: boolean;
80
80
 
81
+ /**
82
+ * Instructions for the LLM on how to use this server's tools.
83
+ * Sent in the MCP initialize response. The LLM sees this before any tool call.
84
+ */
85
+ instructions?: string;
86
+
81
87
  /** Sampling client implementation (required if enableSampling is true) */
82
88
  samplingClient?: SamplingClient;
83
89
 
84
90
  /** Custom logger function (default: console.error) */
85
91
  logger?: (msg: string) => void;
86
92
 
93
+ /**
94
+ * Custom error handler for tool execution errors.
95
+ *
96
+ * When set, errors thrown by tool handlers are passed to this function.
97
+ * Return a message string to produce `{ content: [{type:"text", text: msg}], isError: true }`
98
+ * instead of re-throwing. Return null to rethrow as a JSON-RPC error.
99
+ *
100
+ * Default: undefined (all errors are re-thrown, existing behaviour).
101
+ */
102
+ toolErrorMapper?: ToolErrorMapper;
103
+
87
104
  /**
88
105
  * OAuth2/Bearer authentication configuration.
89
106
  * When provided, HTTP requests require a valid Bearer token.
@@ -238,6 +255,23 @@ export const MCP_APP_URI_SCHEME = "ui:" as const;
238
255
  // MCP Tool Types
239
256
  // ============================================
240
257
 
258
+ /**
259
+ * Behavioural hints for model clients (MCP SDK 1.27 ToolAnnotations).
260
+ * Passed through in tools/list so hosts can adapt their UI accordingly.
261
+ */
262
+ export interface ToolAnnotations {
263
+ /** Short human-readable title, may differ from tool name */
264
+ title?: string;
265
+ /** If true, tool has no side-effects and is safe to call speculatively */
266
+ readOnlyHint?: boolean;
267
+ /** If true, executing may produce irreversible effects */
268
+ destructiveHint?: boolean;
269
+ /** If true, repeated calls with same args produce same result */
270
+ idempotentHint?: boolean;
271
+ /** If true, tool may interact with entities outside the MCP system */
272
+ openWorldHint?: boolean;
273
+ }
274
+
241
275
  /**
242
276
  * MCP Tool definition (compatible with MCP protocol)
243
277
  */
@@ -251,6 +285,15 @@ export interface MCPTool {
251
285
  /** JSON Schema for tool input */
252
286
  inputSchema: Record<string, unknown>;
253
287
 
288
+ /**
289
+ * JSON Schema for the tool's structured output (MCP SDK 1.27).
290
+ * Passed through in tools/list so hosts can validate tool results.
291
+ */
292
+ outputSchema?: Record<string, unknown>;
293
+
294
+ /** Behavioural hints passed to model clients */
295
+ annotations?: ToolAnnotations;
296
+
254
297
  /**
255
298
  * Tool metadata including UI configuration for MCP Apps
256
299
  * @see McpUiToolMeta
@@ -289,6 +332,32 @@ export type ToolHandler = (
289
332
  args: Record<string, unknown>,
290
333
  ) => Promise<unknown> | unknown;
291
334
 
335
+ /**
336
+ * Structured tool result: separates the LLM text summary (content)
337
+ * from the machine-readable payload (structuredContent).
338
+ *
339
+ * When a ToolHandler returns this shape, the framework produces a
340
+ * CallToolResult with both `content` and `structuredContent` set,
341
+ * keeping heavy data out of the LLM context.
342
+ */
343
+ export interface StructuredToolResult {
344
+ /** Human-readable summary shown in content[0].text */
345
+ content: string;
346
+ /** Structured data conforming to the tool's outputSchema */
347
+ structuredContent: Record<string, unknown>;
348
+ }
349
+
350
+ /**
351
+ * Maps a thrown error to either a business error result (isError: true)
352
+ * or signals that the error should be re-thrown as a JSON-RPC error.
353
+ *
354
+ * @returns A message string to produce `{ isError: true }`, or null to rethrow.
355
+ */
356
+ export type ToolErrorMapper = (
357
+ error: unknown,
358
+ toolName: string,
359
+ ) => string | null;
360
+
292
361
  /**
293
362
  * Sampling client interface for bidirectional LLM delegation
294
363
  * Compatible with the agentic sampling protocol (SEP-1577)
@@ -416,8 +485,15 @@ export interface HttpRateLimitOptions {
416
485
  /**
417
486
  * Options for starting an HTTP server
418
487
  */
488
+ // Re-exported from the runtime port so consumers can import the canonical
489
+ // fetch handler type from the same module as HttpServerOptions.
490
+ export type { FetchHandler } from "./runtime/types.js";
491
+ import type { FetchHandler } from "./runtime/types.js";
492
+
419
493
  export interface HttpServerOptions {
420
- /** Port to listen on */
494
+ /**
495
+ * Port to listen on. Ignored when {@link embedded} is `true`.
496
+ */
421
497
  port: number;
422
498
 
423
499
  /** Hostname to bind to (default: "0.0.0.0") */
@@ -463,6 +539,27 @@ export interface HttpServerOptions {
463
539
  * @param info - Server address info
464
540
  */
465
541
  onListen?: (info: { hostname: string; port: number }) => void;
542
+
543
+ /**
544
+ * Embedded mode: skip binding a port and instead surface the Hono fetch
545
+ * handler via the {@link embeddedHandlerCallback} option. Used by
546
+ * {@link McpApp.getFetchHandler} so consumers (Fresh, Hono,
547
+ * Express, etc.) can mount the MCP HTTP stack inside their own server
548
+ * without giving up port ownership.
549
+ *
550
+ * When `true`, `port`, `hostname`, and `onListen` are ignored.
551
+ */
552
+ embedded?: boolean;
553
+
554
+ /**
555
+ * Receives the Hono fetch handler when running in embedded mode.
556
+ * Required when {@link embedded} is `true`. Called exactly once,
557
+ * synchronously, before `startHttp` returns.
558
+ *
559
+ * Most consumers should use {@link McpApp.getFetchHandler}
560
+ * instead of setting this directly.
561
+ */
562
+ embeddedHandlerCallback?: (handler: FetchHandler) => void;
466
563
  }
467
564
 
468
565
  /**
@@ -8,7 +8,13 @@
8
8
  */
9
9
 
10
10
  /** Directories to skip during auto-discovery */
11
- const SKIP_DIRS = new Set(["shared", "dist", "node_modules", ".cache", ".vite"]);
11
+ const SKIP_DIRS = new Set([
12
+ "shared",
13
+ "dist",
14
+ "node_modules",
15
+ ".cache",
16
+ ".vite",
17
+ ]);
12
18
 
13
19
  /**
14
20
  * Convert a file:// URL to a filesystem path.