@ttoss/http-server-mcp 0.32.0 → 0.33.1
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 +16 -0
- package/dist/index.cjs +12 -5
- package/dist/index.d.cts +16 -2
- package/dist/index.d.mts +16 -2
- package/dist/index.mjs +12 -5
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -594,6 +594,19 @@ The spec suggests checking the client's declared capability before registering U
|
|
|
594
594
|
|
|
595
595
|
Declaring it always is also strictly more compatible — a host without Apps support ignores `_meta` and renders the tool's `content`, which is the extension's own graceful-degradation contract. Keep every tool's text result meaningful on its own and the fallback takes care of itself.
|
|
596
596
|
|
|
597
|
+
### Writing the view
|
|
598
|
+
|
|
599
|
+
A view is plain HTML; a raw `postMessage` client is enough, no SDK needed. Tools generated from OpenAPI link to a view through [`toolMeta` and `toStructuredContent`](https://github.com/ttoss/ttoss/tree/main/packages/http-server-mcp-openapi#mcp-apps-views). The parts that only fail inside a host:
|
|
600
|
+
|
|
601
|
+
- **The view speaks first.** It sends `ui/initialize` (`appInfo`, `appCapabilities`, `protocolVersion`), then `ui/notifications/initialized`, and reads the result from `ui/notifications/tool-result` — `structuredContent` when the tool sets it, else the text.
|
|
602
|
+
- **Buttons call tools through the host** with `tools/call`, and the host may ask the person to confirm. `ui/notifications/tool-input` carries the original arguments, which is what a button needs to repeat or extend the call.
|
|
603
|
+
- **Fonts and scripts load only from origins in `ui.csp.resourceDomains`.** The host's default CSP is `font-src 'self'`, so a `data:` font is blocked.
|
|
604
|
+
- **Report size from `document.body`**, not `document.documentElement`: the document is never shorter than the iframe, so the view would grow but never shrink.
|
|
605
|
+
- **Set every value from a tool result with `textContent`.** It is data a model or a user produced.
|
|
606
|
+
- **Theme from `hostContext.theme`**, updated by `ui/notifications/host-context-changed`.
|
|
607
|
+
|
|
608
|
+
To see a view, render it in a host: ext-apps' `AppBridge` in a browser works, connected before the iframe's `srcdoc` is set because the view speaks first. An agent CLI such as Claude Code is an MCP client but not an Apps host, so it never renders one.
|
|
609
|
+
|
|
597
610
|
## Issuing tokens for MCP clients
|
|
598
611
|
|
|
599
612
|
The `auth` option above covers the **resource-server** half of MCP authorization — it verifies tokens issued by an external authorization server (Cognito, Auth0, …). To make your own first-party server _issue_ the tokens an MCP client runs the full OAuth flow against, add the [`@ttoss/http-server-auth`](https://ttoss.dev/docs/modules/packages/http-server-auth) plugin's `oauthServer()` and pair it with `createMcpRouter({ auth: { verifyToken } })` so one deployment both issues and verifies tokens. See the [OAuth Authorization Server](https://ttoss.dev/docs/engineering/guidelines/oauth-authorization-server) guideline.
|
|
@@ -716,6 +729,9 @@ The `GatedToolDef` passed to `register` has:
|
|
|
716
729
|
- `inputSchema` — Zod field map or `ZodObject`, forwarded to `server.registerTool`.
|
|
717
730
|
- `gates` (`Array<(ctx: ToolCallContext) => void | Promise<void>>`, optional) — Per-tool guards appended after the global `gates`. Receive the full `ToolCallContext` enabling arg-conditional authorization.
|
|
718
731
|
- `_meta` (`Record<string, unknown>`, optional) — Tool metadata forwarded verbatim on `tools/list`; how a gated tool links to an [MCP Apps](#mcp-apps-interactive-uis) view.
|
|
732
|
+
- `title` (`string`, optional) — Display name forwarded on `tools/list`.
|
|
733
|
+
- `annotations` (`ToolAnnotations`, optional) — Behaviour hints forwarded on `tools/list`: `readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`. Clients use them to decide when to ask for confirmation; they never replace `requiredScope` or `gates`.
|
|
734
|
+
- `outputSchema` (Zod field map or `ZodObject`, optional) — Result schema forwarded on `tools/list`. When set, a successful result is returned as `structuredContent` **and** as the same JSON in a `TextContent` block, and the SDK validates it against the schema. Without it, the result is a single `TextContent`, as before.
|
|
719
735
|
- `method` — Async handler. Receives merged call args + `buildContext` output.
|
|
720
736
|
|
|
721
737
|
**`ToolCallContext`** is the object passed to gates, `buildContext`, and `onError`:
|
package/dist/index.cjs
CHANGED
|
@@ -576,11 +576,15 @@ var createGatedToolRegistrar = ({
|
|
|
576
576
|
...extra
|
|
577
577
|
});
|
|
578
578
|
if (result == null) return toolError(notFoundMessage);
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
579
|
+
const content = [{
|
|
580
|
+
type: "text",
|
|
581
|
+
text: JSON.stringify(result)
|
|
582
|
+
}];
|
|
583
|
+
return def.outputSchema === void 0 ? {
|
|
584
|
+
content
|
|
585
|
+
} : {
|
|
586
|
+
content,
|
|
587
|
+
structuredContent: result
|
|
584
588
|
};
|
|
585
589
|
} catch (error) {
|
|
586
590
|
if (onError) await onError(error, ctx);
|
|
@@ -608,8 +612,11 @@ var createGatedToolRegistrar = ({
|
|
|
608
612
|
return runMethod(def, ctx);
|
|
609
613
|
};
|
|
610
614
|
server.registerTool(def.name, {
|
|
615
|
+
title: def.title,
|
|
611
616
|
description: def.description,
|
|
612
617
|
inputSchema: def.inputSchema,
|
|
618
|
+
outputSchema: def.outputSchema,
|
|
619
|
+
annotations: def.annotations,
|
|
613
620
|
_meta: def._meta
|
|
614
621
|
}, handler);
|
|
615
622
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
-
import { CallToolResult, InMemoryServerEventBus, McpServer, McpServer as McpServer$1, McpServerFactory, RegisteredResource, ServerEvent, ServerEventBus, ServerEventBus as ServerEventBus$1, ServerNotifier, ServerNotifier as ServerNotifier$1 } from "@modelcontextprotocol/server";
|
|
3
|
+
import { CallToolResult, InMemoryServerEventBus, McpServer, McpServer as McpServer$1, McpServerFactory, RegisteredResource, ServerEvent, ServerEventBus, ServerEventBus as ServerEventBus$1, ServerNotifier, ServerNotifier as ServerNotifier$1, ToolAnnotations } from "@modelcontextprotocol/server";
|
|
4
4
|
import { Router } from "@ttoss/http-server";
|
|
5
5
|
import accepts from "accepts";
|
|
6
6
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -1012,7 +1012,21 @@ type ToolCallContext = {
|
|
|
1012
1012
|
/** Definition for a single gated tool. */
|
|
1013
1013
|
type GatedToolDef = {
|
|
1014
1014
|
/** Tool name as registered with the MCP server. */name: string; /** Human-readable tool description. */
|
|
1015
|
-
description: string; /**
|
|
1015
|
+
description: string; /** Display name shown by clients instead of `name`. */
|
|
1016
|
+
title?: string;
|
|
1017
|
+
/**
|
|
1018
|
+
* Behaviour hints forwarded on `tools/list` (`readOnlyHint`,
|
|
1019
|
+
* `destructiveHint`, `idempotentHint`, `openWorldHint`). Clients use them to
|
|
1020
|
+
* decide when to ask the user for confirmation; they are hints, never
|
|
1021
|
+
* enforcement — scope and gates still decide what may run.
|
|
1022
|
+
*/
|
|
1023
|
+
annotations?: ToolAnnotations;
|
|
1024
|
+
/**
|
|
1025
|
+
* Zod field map or ZodObject describing the result. When set, a successful
|
|
1026
|
+
* result is also returned as `structuredContent`, and the SDK validates it
|
|
1027
|
+
* against this schema.
|
|
1028
|
+
*/
|
|
1029
|
+
outputSchema?: unknown; /** The single scope that must be present on the caller's token. */
|
|
1016
1030
|
requiredScope: string; /** Zod field map or ZodObject — passed through to `server.registerTool`. */
|
|
1017
1031
|
inputSchema: unknown;
|
|
1018
1032
|
/**
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { Router } from "@ttoss/http-server";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
|
-
import { CallToolResult, InMemoryServerEventBus, McpServer, McpServer as McpServer$1, McpServerFactory, RegisteredResource, ServerEvent, ServerEventBus, ServerEventBus as ServerEventBus$1, ServerNotifier, ServerNotifier as ServerNotifier$1 } from "@modelcontextprotocol/server";
|
|
5
|
+
import { CallToolResult, InMemoryServerEventBus, McpServer, McpServer as McpServer$1, McpServerFactory, RegisteredResource, ServerEvent, ServerEventBus, ServerEventBus as ServerEventBus$1, ServerNotifier, ServerNotifier as ServerNotifier$1, ToolAnnotations } from "@modelcontextprotocol/server";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import accepts from "accepts";
|
|
8
8
|
import { AsyncLocalStorage as AsyncLocalStorage$1 } from "async_hooks";
|
|
@@ -1013,7 +1013,21 @@ type ToolCallContext = {
|
|
|
1013
1013
|
/** Definition for a single gated tool. */
|
|
1014
1014
|
type GatedToolDef = {
|
|
1015
1015
|
/** Tool name as registered with the MCP server. */name: string; /** Human-readable tool description. */
|
|
1016
|
-
description: string; /**
|
|
1016
|
+
description: string; /** Display name shown by clients instead of `name`. */
|
|
1017
|
+
title?: string;
|
|
1018
|
+
/**
|
|
1019
|
+
* Behaviour hints forwarded on `tools/list` (`readOnlyHint`,
|
|
1020
|
+
* `destructiveHint`, `idempotentHint`, `openWorldHint`). Clients use them to
|
|
1021
|
+
* decide when to ask the user for confirmation; they are hints, never
|
|
1022
|
+
* enforcement — scope and gates still decide what may run.
|
|
1023
|
+
*/
|
|
1024
|
+
annotations?: ToolAnnotations;
|
|
1025
|
+
/**
|
|
1026
|
+
* Zod field map or ZodObject describing the result. When set, a successful
|
|
1027
|
+
* result is also returned as `structuredContent`, and the SDK validates it
|
|
1028
|
+
* against this schema.
|
|
1029
|
+
*/
|
|
1030
|
+
outputSchema?: unknown; /** The single scope that must be present on the caller's token. */
|
|
1017
1031
|
requiredScope: string; /** Zod field map or ZodObject — passed through to `server.registerTool`. */
|
|
1018
1032
|
inputSchema: unknown;
|
|
1019
1033
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -573,11 +573,15 @@ var createGatedToolRegistrar = ({
|
|
|
573
573
|
...extra
|
|
574
574
|
});
|
|
575
575
|
if (result == null) return toolError(notFoundMessage);
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
576
|
+
const content = [{
|
|
577
|
+
type: "text",
|
|
578
|
+
text: JSON.stringify(result)
|
|
579
|
+
}];
|
|
580
|
+
return def.outputSchema === void 0 ? {
|
|
581
|
+
content
|
|
582
|
+
} : {
|
|
583
|
+
content,
|
|
584
|
+
structuredContent: result
|
|
581
585
|
};
|
|
582
586
|
} catch (error) {
|
|
583
587
|
if (onError) await onError(error, ctx);
|
|
@@ -605,8 +609,11 @@ var createGatedToolRegistrar = ({
|
|
|
605
609
|
return runMethod(def, ctx);
|
|
606
610
|
};
|
|
607
611
|
server.registerTool(def.name, {
|
|
612
|
+
title: def.title,
|
|
608
613
|
description: def.description,
|
|
609
614
|
inputSchema: def.inputSchema,
|
|
615
|
+
outputSchema: def.outputSchema,
|
|
616
|
+
annotations: def.annotations,
|
|
610
617
|
_meta: def._meta
|
|
611
618
|
}, handler);
|
|
612
619
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/http-server-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.1",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server integration for @ttoss/http-server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"@modelcontextprotocol/server": "^2.0.0",
|
|
39
39
|
"zod": "^4.4.3",
|
|
40
40
|
"@ttoss/auth-core": "^0.16.0",
|
|
41
|
+
"@ttoss/http-server": "^0.11.0",
|
|
41
42
|
"@ttoss/http-server-auth": "^0.8.0",
|
|
42
|
-
"@ttoss/i18n-core": "^0.6.0"
|
|
43
|
-
"@ttoss/http-server": "^0.11.0"
|
|
43
|
+
"@ttoss/i18n-core": "^0.6.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@modelcontextprotocol/client": "^2.0.0",
|