@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
JavaScript
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