@kya-os/mcp-i
Version:
The TypeScript MCP framework with identity features built-in
109 lines (108 loc) • 3.73 kB
JavaScript
;
/**
* Request Context Management
*
* Uses AsyncLocalStorage to track request-scoped data like session information
* across async operations without needing to pass it through every function.
*
* This enables the compiler path to access session data (like agentDid) that
* was set during handshake processing.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.runWithContext = runWithContext;
exports.getContext = getContext;
exports.getCurrentSession = getCurrentSession;
exports.getCurrentAgentDid = getCurrentAgentDid;
exports.setSession = setSession;
exports.setDelegationContext = setDelegationContext;
exports.setDelegationContextFromIdentity = setDelegationContextFromIdentity;
const async_hooks_1 = require("async_hooks");
const asyncLocalStorage = new async_hooks_1.AsyncLocalStorage();
/**
* Run a function with request context
*/
function runWithContext(context, fn) {
return asyncLocalStorage.run(context, fn);
}
/**
* Get the current request context
*/
function getContext() {
return asyncLocalStorage.getStore();
}
/**
* Get the current session from context
*/
function getCurrentSession() {
return getContext()?.session;
}
/**
* Get the current agent DID from session
*/
function getCurrentAgentDid() {
return getCurrentSession()?.agentDid;
}
/**
* Set session in current context
*
* NOTE: This only works if called within a runWithContext block
*/
function setSession(session) {
const context = getContext();
if (context) {
context.session = session;
}
else {
console.warn('[RequestContext] Attempted to set session outside of request context');
}
}
/**
* Update delegation context fields in the current request context.
* Called after delegation is verified for a protected tool call.
*
* NOTE: This only works if called within a runWithContext block
*/
function setDelegationContext(fields) {
const context = getContext();
if (!context) {
console.warn('[RequestContext] setDelegationContext called outside of runWithContext — delegation headers will not be injected');
return;
}
context.delegationRef = fields.delegationRef;
context.delegationChain = fields.delegationChain;
context.delegationScopes = fields.delegationScopes;
if (fields.delegationCredential !== undefined) {
context.delegationCredential = fields.delegationCredential;
}
if (fields.delegationPrivateKeyJwk !== undefined) {
context.delegationPrivateKeyJwk = fields.delegationPrivateKeyJwk;
}
if (fields.delegationAgentKid !== undefined) {
context.delegationAgentKid = fields.delegationAgentKid;
}
}
/**
* Convenience helper that wires delegation metadata from a verified delegation
* result and agent identity into AsyncLocalStorage in a single call.
*
* Avoids duplicating the base64-to-base64url JWK conversion and the
* setDelegationContext call across mcpi-runtime.ts and utils/tools.ts.
*/
function setDelegationContextFromIdentity(params) {
setDelegationContext({
delegationRef: params.delegationId,
delegationChain: params.delegationChain,
delegationScopes: params.delegationScopes,
delegationCredential: params.delegationCredential,
delegationPrivateKeyJwk: params.identity?.privateKey
? {
kty: "OKP",
crv: "Ed25519",
d: Buffer.from(params.identity.privateKey, "base64").toString("base64url"),
x: Buffer.from(params.identity.publicKey, "base64").toString("base64url"),
kid: params.identity.kid,
}
: undefined,
delegationAgentKid: params.identity?.kid,
});
}