@mcpcloud/runtime 0.1.2 → 0.2.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/dist/adapters/node.d.ts +7 -0
- package/dist/compat-stdio.js +6 -6
- package/dist/compat-worker.js +16 -16
- package/dist/config.d.ts +12 -0
- package/dist/container-host.js +2 -2
- package/dist/index.js +13 -13
- package/dist/node.js +2 -2
- package/dist/stdio.js +7 -7
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
|
@@ -26,6 +26,13 @@ export interface RuntimeEnv {
|
|
|
26
26
|
MCP_RUNTIME_AUTH_ORGANIZATION_ID?: string;
|
|
27
27
|
MCP_RUNTIME_AUTH_PUBLIC_KEY?: string;
|
|
28
28
|
MCP_RUNTIME_AUTH_SERVER_ID?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Optional static bearer token for the self-host / standalone node adapter.
|
|
31
|
+
* When set, every request except `/health` must carry
|
|
32
|
+
* `Authorization: Bearer <token>`. Unset = the exported server stays public
|
|
33
|
+
* (it runs without the dispatch proxy that enforces access on the edge).
|
|
34
|
+
*/
|
|
35
|
+
MCP_BEARER_TOKEN?: string;
|
|
29
36
|
}
|
|
30
37
|
/** Per-server data the codegen passes to `defineServer` / config resolution. */
|
|
31
38
|
export interface ServerIdentity {
|
|
@@ -69,6 +76,11 @@ export interface RuntimeConfig {
|
|
|
69
76
|
runtimeAuth: RuntimeAccessConfig | null;
|
|
70
77
|
}
|
|
71
78
|
export declare function getProcessEnv(): RuntimeEnv;
|
|
79
|
+
/**
|
|
80
|
+
* The configured static bearer token for the standalone node adapter, or null
|
|
81
|
+
* when none is set (the server stays public). See `MCP_BEARER_TOKEN`.
|
|
82
|
+
*/
|
|
83
|
+
export declare function resolveStaticBearerToken(env?: RuntimeEnv): string | null;
|
|
72
84
|
export declare function resolveRuntimeAccessMode(env?: RuntimeEnv): RuntimeAccessMode;
|
|
73
85
|
export declare function resolveRuntimeConfig(identity: ServerIdentity, env?: RuntimeEnv): RuntimeConfig;
|
|
74
86
|
export declare function postOAuthRuntimeRequest(config: RuntimeConfig, body: {
|
package/dist/container-host.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
/*! @mcpcloud/runtime v0.
|
|
2
|
-
import{mkdirSync as
|
|
1
|
+
/*! @mcpcloud/runtime v0.2.0 — (c) MCPCloud.sh. All rights reserved. SEE LICENSE: https://www.npmjs.com/package/@mcpcloud/runtime */
|
|
2
|
+
import{mkdirSync as V,mkdtempSync as R,writeFileSync as S}from"node:fs";import{tmpdir as E}from"node:os";import{dirname as w,join as L}from"node:path";import{pathToFileURL as k}from"node:url";import{timingSafeEqual as H}from"node:crypto";import{createServer as D}from"node:http";import{Readable as M}from"node:stream";function x(){return typeof process>"u"?{}:process.env}function W(G=x()){return G.MCP_BEARER_TOKEN?.trim()||null}function U(G,K){let J=Buffer.from(G),Q=Buffer.from(K);return J.length===Q.length&&H(J,Q)}function B(G,K){let J=W(K);if(!J)return null;if(new URL(G.url).pathname==="/health")return null;let Q=G.headers.get("authorization")??"",X=/^Bearer\s+(.+)$/i.exec(Q.trim());if(X&&U(X[1].trim(),J))return null;return Response.json({error:"unauthorized",message:"This MCP endpoint requires a bearer token (set in Authorization: Bearer <token>)."},{status:401,headers:{"www-authenticate":"Bearer"}})}function P(G,K){let J=new URL(G.url??"/",K),Q=new Headers;for(let[Z,$]of Object.entries(G.headers))if(Array.isArray($))for(let F of $)Q.append(Z,F);else if(typeof $==="string")Q.set(Z,$);let X=G.method??"GET",Y=X==="GET"||X==="HEAD"?void 0:M.toWeb(G);return new Request(J,{method:X,headers:Q,body:Y,...Y?{duplex:"half"}:{}})}async function A(G,K){if(K.statusCode=G.status,G.headers.forEach((Q,X)=>{K.setHeader(X,Q)}),!G.body){K.end();return}let J=G.body.getReader();for(;;){let{done:Q,value:X}=await J.read();if(Q)break;K.write(X)}K.end()}function j(G,K={}){let J=K.port??Number(process.env.PORT??8080),Q=K.hostname??"0.0.0.0",X=D((Y,Z)=>{let $=`http://${Y.headers.host??`${Q}:${J}`}`,F=P(Y,$),N=B(F,K.env);(N?Promise.resolve(N):G.handleRequest(F,K.env)).then((O)=>A(O,Z)).catch(()=>{Z.statusCode=500,Z.end(JSON.stringify({error:"internal_error"}))})});return X.listen(J,Q),X}var C=1;function z(G=process.env){let K=G.BUNDLE_URL?.trim(),J=G.BUNDLE_SHA256?.trim();if(!K)throw Error("BUNDLE_URL is not set; the runtime host has no code to run.");if(!J)throw Error("BUNDLE_SHA256 is not set; refusing to boot unverified code.");let Q=Number(G.PORT??8080);if(!Number.isInteger(Q)||Q<=0)throw Error(`Invalid PORT: ${String(G.PORT)}`);return{bundleUrl:K,bundleSha256:J,port:Q}}async function g(G){let K=G.buffer.slice(G.byteOffset,G.byteOffset+G.byteLength),J=await crypto.subtle.digest("SHA-256",K);return Array.from(new Uint8Array(J)).map((Q)=>Q.toString(16).padStart(2,"0")).join("")}function T(G){let K=JSON.parse(new TextDecoder().decode(G));if(!K||typeof K!=="object")throw Error("Boot artifact must be a JSON object.");let J=K;if(J.schemaVersion!==C)throw Error(`Unsupported boot artifact schemaVersion: ${String(J.schemaVersion)}.`);if(typeof J.runtimeVersion!=="string"||typeof J.mainEntry!=="string"||!Array.isArray(J.files))throw Error("Boot artifact is malformed.");let Q=J.files.map((X)=>{if(!X||typeof X!=="object"||typeof X.path!=="string"||typeof X.content!=="string")throw Error("Boot artifact files must be { path, content }.");let Y=X;return{path:Y.path,content:Y.content}});return{schemaVersion:C,runtimeVersion:J.runtimeVersion,mainEntry:J.mainEntry,files:Q}}async function I(G,K=fetch){let J=await K(G.bundleUrl);if(!J.ok)throw Error(`Bundle fetch failed (HTTP ${J.status}).`);let Q=new Uint8Array(await J.arrayBuffer()),X=await g(Q);if(X!==G.bundleSha256.toLowerCase())throw Error(`Bundle sha256 mismatch (expected ${G.bundleSha256}, got ${X}).`);return T(Q)}function _(G,K){for(let J of G.files){let Q=L(K,J.path);V(w(Q),{recursive:!0}),S(Q,J.content)}return{entryPath:L(K,G.mainEntry)}}async function q(G={}){let K=G.bootConfig??z(),J=await I(K,G.fetchImpl),Q=G.workDir??R(L(E(),"mcpcloud-server-")),{entryPath:X}=_(J,Q),Y=await import(k(X).href),Z=Y.server??Y.default;if(!Z)throw Error(`Boot module ${J.mainEntry} does not export a \`server\`.`);let $={port:K.port,...G.hostname?{hostname:G.hostname}:{},...G.env?{env:G.env}:{}};return j(Z,$)}export{q as serveFromBundle,z as resolveBootConfig,_ as materializeBundle,I as fetchAndVerifyBundle,C as BOOT_ARTIFACT_SCHEMA_VERSION};
|