UNPKG

@receiz/mcp-server

Version:

MCP server for agents building and verifying Receiz proof-native applications through the canonical Receiz SDK rails.

59 lines • 4.46 kB
import { readFile, realpath } from "node:fs/promises"; import { basename, isAbsolute } from "node:path"; import { createReceizArtifactAdmissionEngine, createReceizV127SubjectRuntimeAdapter, readReceizIdentityPublicBinding, verifyReceizArtifact, RECEIZ_CURRENT_REGISTRY_DIGEST, RECEIZ_LIVING_SUBJECT_REDUCER_DIGEST, } from "@receiz/sdk"; import { createReceizNodeOfflineSealer } from "@receiz/sdk/offline/node"; import { createReceizNodeOfflineKaiProofFactory } from "@receiz/sdk/offline/kai/node"; import { createReceizV127SubjectRuntimeFileStore, readReceizV127SubjectRuntimeSourceFile } from "@receiz/sdk/subjects/node"; import { createReceizMcpRuntime } from "./index.js"; import { shareDeviceIdentityContext } from "./deviceIdentityContext.js"; import { bindDeviceRuntimeOwner } from "./deviceOwner.js"; import { bindReceizMcpDeviceAiSubjectCreation } from "./deviceAiSubjectTool.js"; import { createReceizDeviceMaterialHost } from "./deviceMaterialHost.js"; /** Device host composition, never an MCP tool. Keys and admissions stay local. */ export async function openReceizMcpDeviceRuntime(options) { // Snapshot host configuration before the first async boundary. const { identityArtifactPath, identityPassphrase, workspace, sealDirectory, subjectDirectory, snapshotArtifactPath, identityContextSharing } = options; if (identityContextSharing !== undefined && identityContextSharing !== "all-carried-state") throw new TypeError("RECEIZ_DEVICE_CONTEXT_SHARING_INVALID"); const transport = { ...options.runtime }; for (const path of [identityArtifactPath, workspace, sealDirectory, subjectDirectory, ...(snapshotArtifactPath ? [snapshotArtifactPath] : [])]) { if (typeof path !== "string" || !isAbsolute(path)) throw new TypeError("RECEIZ_MCP_DEVICE_ABSOLUTE_PATH_REQUIRED"); } const workspacePath = await realpath(workspace); const bytes = await readFile(identityArtifactPath); const verification = await verifyReceizArtifact(new File([bytes], basename(identityArtifactPath))); const identityAdmission = await createReceizArtifactAdmissionEngine()(verification, { profile: "identity", identityPassphrase }); await readReceizIdentityPublicBinding(identityAdmission); // Both primitives retain this exact SDK-issued admission. A later replacement // of the input file cannot silently change the owner of newly sealed objects. const offlineSealer = await createReceizNodeOfflineSealer({ directory: sealDirectory, ownerIdentityAdmission: identityAdmission, ...(transport.fetch ? { fetch: transport.fetch } : {}) }); const store = createReceizV127SubjectRuntimeFileStore(subjectDirectory); const initialSource = snapshotArtifactPath && await store.load() === null ? await readReceizV127SubjectRuntimeSourceFile(snapshotArtifactPath) : undefined; let prover; const subjectRuntime = await createReceizV127SubjectRuntimeAdapter({ identityAdmission, store, ...(initialSource ? { initialSource } : {}), registryDigest: RECEIZ_CURRENT_REGISTRY_DIGEST, reducerDigest: RECEIZ_LIVING_SUBJECT_REDUCER_DIGEST, resolveTemporalCoordinate: async (context) => { prover ??= createReceizNodeOfflineKaiProofFactory(); return (await prover)({ previousKaiSigilProofHead: context.previousKaiSigilProofHead }); }, }); const materials = createReceizDeviceMaterialHost(workspacePath); const runtime = createReceizMcpRuntime({ ...transport, subjectRuntime, offlineSealer, resolveV124Material: transport.resolveV124Material ?? materials.resolveMaterial, resolveV125ProofReference: transport.resolveV125ProofReference ?? materials.resolveProofReference, // No passphrase, input file, or serialized admission is retained as runtime // configuration. The canonical sealer and subject host hold genuine custody. localCustody: { workspace: workspacePath, directory: sealDirectory, identity: null, identityAdmitted: true }, }); if (identityContextSharing === "all-carried-state") await shareDeviceIdentityContext(runtime, identityAdmission); await bindDeviceRuntimeOwner(runtime, identityAdmission, identityPassphrase); await bindReceizMcpDeviceAiSubjectCreation(runtime, { ownerIdentityAdmission: identityAdmission, sealer: offlineSealer, workspace: workspacePath }); return runtime; } //# sourceMappingURL=deviceRuntime.js.map