@xtrable-ltd/nanoesis 0.1.11 → 0.1.12
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/dist/chunk-EN5SMEWJ.js +1221 -0
- package/dist/editor-api.js +21 -1198
- package/dist/mcp.d.ts +48 -0
- package/dist/mcp.js +76 -0
- package/package.json +7 -1
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { ApiDeps } from '@nanoesis/editor-api';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Identity reported to MCP clients on `initialize`. Defaults: `{ name: 'nanoesis', version:
|
|
5
|
+
* '0.0.0' }`. Adopters embedding the HTTP route in their own host typically override `name`
|
|
6
|
+
* with their site identifier and `version` with their app version so client UIs identify
|
|
7
|
+
* the deployment, not the framework.
|
|
8
|
+
*/
|
|
9
|
+
interface McpServerIdentity {
|
|
10
|
+
readonly name?: string;
|
|
11
|
+
readonly version?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Options for {@link handleMcpRequest}. Both fields are passed straight through to the
|
|
16
|
+
* MCP `Server`'s `initialize` response so client UIs (Claude Desktop, Cursor, …) identify
|
|
17
|
+
* the deployment rather than the framework.
|
|
18
|
+
*/
|
|
19
|
+
type HandleMcpRequestOptions = McpServerIdentity;
|
|
20
|
+
/**
|
|
21
|
+
* Handle a single MCP HTTP request over the SDK's web-standard Streamable HTTP transport
|
|
22
|
+
* (DESIGN §11c/§14). Stateless: each call builds a fresh `Server` + `Transport` pair, so
|
|
23
|
+
* the caller's per-request `Authorization: Bearer …` header — propagated by the SDK into
|
|
24
|
+
* the request handlers as `extra.requestInfo.headers` — drives the editor's per-user role
|
|
25
|
+
* gate exactly as `/api/*` does.
|
|
26
|
+
*
|
|
27
|
+
* The signature is Fetch-API neutral: any runtime that hands a handler a standard
|
|
28
|
+
* `Request` (Azure Functions v4, Cloudflare Workers, plain Node 18+, Bun, Deno, Hono)
|
|
29
|
+
* wires it the same way:
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { handleMcpRequest } from '@xtrable-ltd/nanoesis/mcp';
|
|
33
|
+
* // ... build `deps` once at startup
|
|
34
|
+
* app.http('mcp', {
|
|
35
|
+
* methods: ['POST', 'GET', 'DELETE'],
|
|
36
|
+
* handler: (req) => handleMcpRequest(deps, req, { name: 'my-site', version: pkg.version }),
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* Runtimes whose request shape is not a standard `Request` (e.g. Azure Functions' enhanced
|
|
41
|
+
* HttpRequest, Express' IncomingMessage) translate to/from `Request`/`Response` at the
|
|
42
|
+
* boundary — that translation is adopter-side because it depends on the host runtime; the
|
|
43
|
+
* MCP server construction and transport handling, which used to be ~120 lines of inlined
|
|
44
|
+
* boilerplate per adopter, is now this one call.
|
|
45
|
+
*/
|
|
46
|
+
declare function handleMcpRequest(deps: ApiDeps, request: Request, opts?: HandleMcpRequestOptions): Promise<Response>;
|
|
47
|
+
|
|
48
|
+
export { type HandleMcpRequestOptions, handleMcpRequest };
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MCP_RESOURCES,
|
|
3
|
+
MCP_TOOLS,
|
|
4
|
+
callMcpTool,
|
|
5
|
+
readMcpResource
|
|
6
|
+
} from "./chunk-EN5SMEWJ.js";
|
|
7
|
+
import "./chunk-XO3CT6GL.js";
|
|
8
|
+
|
|
9
|
+
// ../../hosts/host-mcp/src/http.ts
|
|
10
|
+
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
11
|
+
|
|
12
|
+
// ../../hosts/host-mcp/src/server.ts
|
|
13
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
14
|
+
import {
|
|
15
|
+
CallToolRequestSchema,
|
|
16
|
+
ListResourcesRequestSchema,
|
|
17
|
+
ListToolsRequestSchema,
|
|
18
|
+
ReadResourceRequestSchema
|
|
19
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
20
|
+
var BEARER_PREFIX = /^Bearer\s+/i;
|
|
21
|
+
function bearerFrom(headers) {
|
|
22
|
+
if (headers === void 0) return void 0;
|
|
23
|
+
const raw = headers["authorization"] ?? headers["Authorization"];
|
|
24
|
+
const value = Array.isArray(raw) ? raw[0] : raw;
|
|
25
|
+
if (value === void 0) return void 0;
|
|
26
|
+
const match = BEARER_PREFIX.exec(value);
|
|
27
|
+
return match ? value.slice(match[0].length).trim() : void 0;
|
|
28
|
+
}
|
|
29
|
+
function createMcpServer(deps, identity) {
|
|
30
|
+
const server = new Server(
|
|
31
|
+
{ name: identity?.name ?? "nanoesis", version: identity?.version ?? "0.0.0" },
|
|
32
|
+
{ capabilities: { tools: {}, resources: {} } }
|
|
33
|
+
);
|
|
34
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [...MCP_TOOLS] }));
|
|
35
|
+
server.setRequestHandler(CallToolRequestSchema, async (req, extra) => {
|
|
36
|
+
const args = req.params.arguments ?? {};
|
|
37
|
+
const token = bearerFrom(extra.requestInfo?.headers);
|
|
38
|
+
const result = await callMcpTool(
|
|
39
|
+
deps,
|
|
40
|
+
req.params.name,
|
|
41
|
+
args,
|
|
42
|
+
token !== void 0 ? { token } : {}
|
|
43
|
+
);
|
|
44
|
+
return { content: [{ type: "text", text: result.text }], isError: result.isError };
|
|
45
|
+
});
|
|
46
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => ({
|
|
47
|
+
resources: [...MCP_RESOURCES]
|
|
48
|
+
}));
|
|
49
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (req) => {
|
|
50
|
+
const { uri } = req.params;
|
|
51
|
+
const resource = readMcpResource(uri);
|
|
52
|
+
if (resource === void 0) throw new Error(`Unknown resource: ${uri}`);
|
|
53
|
+
return { contents: [{ uri, mimeType: resource.mimeType, text: resource.text }] };
|
|
54
|
+
});
|
|
55
|
+
return server;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ../../hosts/host-mcp/src/http.ts
|
|
59
|
+
var DEFAULT_VERSION = true ? "0.1.12" : "0.0.0-workspace";
|
|
60
|
+
async function handleMcpRequest(deps, request, opts) {
|
|
61
|
+
const server = createMcpServer(deps, {
|
|
62
|
+
name: opts?.name ?? "nanoesis",
|
|
63
|
+
version: opts?.version ?? DEFAULT_VERSION
|
|
64
|
+
});
|
|
65
|
+
const transport = new WebStandardStreamableHTTPServerTransport({ enableJsonResponse: true });
|
|
66
|
+
await server.connect(transport);
|
|
67
|
+
try {
|
|
68
|
+
return await transport.handleRequest(request);
|
|
69
|
+
} finally {
|
|
70
|
+
await transport.close();
|
|
71
|
+
await server.close();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export {
|
|
75
|
+
handleMcpRequest
|
|
76
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xtrable-ltd/nanoesis",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "nanoesis: a static-first publishing compiler. The engine, the mountable editor API, the storage/image/auth adapters, and the editor UI bundle, in one package (DESIGN 11c).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Xtrable Ltd",
|
|
@@ -49,6 +49,10 @@
|
|
|
49
49
|
"types": "./dist/editor.d.ts",
|
|
50
50
|
"default": "./dist/editor.js"
|
|
51
51
|
},
|
|
52
|
+
"./mcp": {
|
|
53
|
+
"types": "./dist/mcp.d.ts",
|
|
54
|
+
"default": "./dist/mcp.js"
|
|
55
|
+
},
|
|
52
56
|
"./package.json": "./package.json"
|
|
53
57
|
},
|
|
54
58
|
"files": [
|
|
@@ -66,6 +70,7 @@
|
|
|
66
70
|
},
|
|
67
71
|
"dependencies": {
|
|
68
72
|
"@azure/storage-blob": "^12.26.0",
|
|
73
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
69
74
|
"parse5": "^7.2.1",
|
|
70
75
|
"sharp": "^0.33.0"
|
|
71
76
|
},
|
|
@@ -79,6 +84,7 @@
|
|
|
79
84
|
"@nanoesis/adapter-trusted-header": "*",
|
|
80
85
|
"@nanoesis/editor-api": "*",
|
|
81
86
|
"@nanoesis/engine": "*",
|
|
87
|
+
"@nanoesis/host-mcp": "*",
|
|
82
88
|
"@types/node": "^22.10.0",
|
|
83
89
|
"tsup": "^8.3.0"
|
|
84
90
|
}
|