Skip to main content
Glama
attestedintelligence

AGA-mcp-server

aga_trigger_measurement

Measure content integrity and generate cryptographic receipts for verification and tamper-evident logging within the AGA-mcp-server portal.

Instructions

Trigger a measurement of subject content and generate a receipt.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
subject_contentNoRaw content to measure
subject_bytes_hashNoPre-computed SHA-256 bytes hash (64 hex)
subject_metadata_hashNoPre-computed SHA-256 metadata hash (64 hex)
measurement_typeNo
subject_metadataNo

Implementation Reference

  • The handler function for the aga_trigger_measurement tool. It performs measurements, detects drift, triggers enforcement, generates a receipt, and stores interaction data.
    export async function handleTriggerMeasurement(args: TriggerMeasurementArgs, ctx: ServerContext) {
      if (!ctx.portal.artifact) return ctx.error('No artifact loaded.');
      if (ctx.portal.state === 'TERMINATED' || ctx.portal.state === 'SAFE_STATE') {
        return ctx.error(`Portal is ${ctx.portal.state}. Artifact revoked or expired.`);
      }
    
      let match: boolean;
      let action: EnforcementAction | null = null;
      let driftDesc: string | null = null;
      let currentHash = 'UNAVAILABLE';
    
      if (args.subject_bytes_hash) {
        // Pre-computed hash mode
        const bMatch = args.subject_bytes_hash === ctx.portal.artifact.subject_identifier.bytes_hash;
        const mMatch = !args.subject_metadata_hash || args.subject_metadata_hash === ctx.portal.artifact.subject_identifier.metadata_hash;
        match = bMatch && mMatch;
        currentHash = args.subject_bytes_hash;
        if (!match && ctx.portal.state === 'ACTIVE_MONITORING') {
          (ctx.portal as any).state = 'DRIFT_DETECTED';
        }
      } else if (args.subject_content) {
        const meta = args.subject_metadata ?? {};
        const result = ctx.portal.measure(new TextEncoder().encode(args.subject_content), meta);
        match = result.match;
        currentHash = result.currentBytesHash || 'UNAVAILABLE';
        if (!result.ttl_ok) { driftDesc = 'TTL expired'; action = 'TERMINATE'; match = false; }
        else if (result.revoked) { driftDesc = 'Artifact revoked'; action = 'TERMINATE'; match = false; }
      } else {
        return ctx.error('Provide either subject_content or subject_bytes_hash');
      }
    
      if (!match && !action) {
        driftDesc = 'Subject modified - hash mismatch';
        action = ctx.portal.artifact.enforcement_parameters.enforcement_triggers[0] ?? 'ALERT_ONLY';
        if (ctx.portal.state === 'DRIFT_DETECTED') {
          ctx.portal.enforce(action);
        }
        if (action === 'QUARANTINE') ctx.quarantine = initQuarantine();
      }
    
      ctx.measurementCount++;
      const artRef = hashArtifact(ctx.portal.artifact);
      const mType = args.measurement_type ?? ctx.portal.artifact.enforcement_parameters.measurement_types[0] ?? 'FILE_SYSTEM_STATE';
    
      const receipt = generateReceipt({
        subjectId: ctx.portal.artifact.subject_identifier,
        artifactRef: artRef,
        currentHash,
        sealedHash: ctx.portal.artifact.subject_identifier.bytes_hash,
        driftDetected: !match,
        driftDescription: driftDesc,
        action,
        measurementType: mType,
        seq: ctx.portal.sequenceCounter + 1,
        prevLeaf: ctx.portal.lastLeafHash,
        portalKP: ctx.portalKP,
      });
      await ctx.storage.storeReceipt(receipt);
      await ctx.appendToChain('INTERACTION_RECEIPT', {
        receipt_id: receipt.receipt_id,
        drift_detected: !match,
        enforcement_action: action,
        measurement_type: mType,
      });
    
      return ctx.json({
        success: true,
        match,
        drift_detected: !match,
        enforcement_action: action,
        portal_state: ctx.portal.state,
        receipt_id: receipt.receipt_id,
        measurement_type: mType,
        measurement_count: ctx.measurementCount,
      });
    }
  • Definition of the arguments (schema) accepted by the trigger measurement tool.
    export interface TriggerMeasurementArgs {
      subject_content?: string;
      subject_bytes_hash?: string;
      subject_metadata_hash?: string;
      measurement_type?: string;
      subject_metadata?: Record<string, string>;
    }
  • src/server.ts:173-184 (registration)
    Tool registration for 'aga_trigger_measurement' in the main server file using governedTool, mapping inputs to the handler and defining the schema using Zod.
    // 8. aga_trigger_measurement (governed)
    governedTool('aga_trigger_measurement',
      'Trigger a measurement of subject content and generate a receipt.',
      {
        subject_content: z.string().optional().describe('Raw content to measure'),
        subject_bytes_hash: z.string().optional().describe('Pre-computed SHA-256 bytes hash (64 hex)'),
        subject_metadata_hash: z.string().optional().describe('Pre-computed SHA-256 metadata hash (64 hex)'),
        measurement_type: z.string().optional(),
        subject_metadata: z.record(z.string()).optional(),
      },
      async (args) => handleTriggerMeasurement(args, ctx),
    );

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/attestedintelligence/aga-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server