Skip to main content
Glama

audit_pipeline

Read-onlyIdempotent

Retrieve hash-chained governance audit entries filtered by operation name or recent activity, with MAI classification context.

Instructions

Query the audit ledger for governance entries. Search by operation name or retrieve recent entries. Returns hash-chained audit trail with MAI classification context.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
operationNoFilter by operation name
limitNoMaximum entries to return
suppress_noiseNoWhen true, filters out known high-volume infrastructure actors (legacy-* prefix, SYSTEM) and lifecycle-only operations (mcp-reinitialize, mcp-initialize) from results. The full forensic ledger is never mutated — this is a view-layer filter only.
exclude_actorsNoAdditional actor IDs or prefixes (prefix matched) to exclude from results. Useful for silencing a specific noisy integration without suppress_noise.

Implementation Reference

  • Handler function that registers the audit_pipeline MCP tool. Queries the audit ledger for governance entries, supporting filtering by operation name, limit, suppress_noise (filters infrastructure actors/lifecycle ops), and exclude_actors. Returns hash-chained audit trail with MAI classification context.
    export function registerAuditPipelineTool(server: McpServer, engine: GovernanceEngine): void {
      server.tool(
        'audit_pipeline',
        'Query the audit ledger for governance entries. Search by operation name or retrieve recent entries. Returns hash-chained audit trail with MAI classification context.',
        {
          operation: z.string().optional().describe('Filter by operation name'),
          limit: z.number().min(1).max(100).default(20).describe('Maximum entries to return'),
          suppress_noise: z.boolean().default(false).describe(
            'When true, filters out known high-volume infrastructure actors (legacy-* prefix, SYSTEM) ' +
            'and lifecycle-only operations (mcp-reinitialize, mcp-initialize) from results. ' +
            'The full forensic ledger is never mutated — this is a view-layer filter only.'
          ),
          exclude_actors: z.array(z.string()).optional().describe(
            'Additional actor IDs or prefixes (prefix matched) to exclude from results. ' +
            'Useful for silencing a specific noisy integration without suppress_noise.'
          ),
        },
        { title: 'Query Audit Ledger', readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
        async (input) => {
          // Known noise operations — lifecycle bookkeeping with no governance signal
          const NOISE_OPERATIONS = new Set(['mcp-reinitialize', 'mcp-initialize', 'mcp-session-end']);
          // Legacy/infrastructure actor prefixes excluded when suppress_noise is active
          const NOISE_ACTOR_PREFIXES = ['legacy-', 'SYSTEM'];
    
          function isNoise(actor: string, operation: string): boolean {
            if (NOISE_OPERATIONS.has(operation)) return true;
            return NOISE_ACTOR_PREFIXES.some(p => actor.startsWith(p));
          }
    
          function isExcluded(actor: string): boolean {
            const extras = input.exclude_actors ?? [];
            return extras.some(ex => actor === ex || actor.startsWith(ex));
          }
    
          let entries;
          if (input.operation) {
            entries = engine.ledger.queryByOperation(input.operation);
          } else {
            // Return the most recent completed entries (not time-windowed).
            // Previous behavior used a 1-hour window which returned empty results
            // after restart or low-activity periods. Now returns the N most recent
            // unique operations sorted by timestamp descending.
            entries = engine.ledger.queryCompleted()
              .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
          }
    
          // Apply view-layer filters (forensic ledger is never mutated)
          if (input.suppress_noise || (input.exclude_actors?.length ?? 0) > 0) {
            entries = entries.filter(e => {
              if (input.suppress_noise && isNoise(e.actor, e.operation)) return false;
              if (isExcluded(e.actor)) return false;
              return true;
            });
          }
    
          const noiseFiltered = input.suppress_noise || (input.exclude_actors?.length ?? 0) > 0;
    
          const limited = entries.slice(0, input.limit).map(e => ({
            id: e.id,
            operation: e.operation,
            status: e.status,
            // maiLevel = the operation's own MAI classification (e.g. classify-decision is INFORMATIONAL)
            maiLevel: e.maiLevel,
            // decisionMaiLevel = the classified result's MAI level, when the operation produces one
            // Resolves auditor concern: "why is classify-decision INFORMATIONAL if it returned MANDATORY?"
            // Answer: the act of classifying is informational; the decision it classified IS mandatory.
            decisionMaiLevel: (e.metadata?.maiClassification as string) ?? null,
            requiresGate: (e.metadata?.requiresGate as boolean) ?? (e.gateDecision ? true : null),
            layer: e.layer,
            actor: e.actor,
            timestamp: e.timestamp,
            duration: e.duration,
            hasScore: !!e.governanceScore,
            hasGate: !!e.gateDecision,
            // Hash chain fields — tamper-evident audit trail
            entryHash: e.entryHash ?? null,
            previousHash: e.previousHash ?? null,
            chainIndex: e.chainIndex ?? null,
          }));
    
          // Tool accountability tracking
          engine.telemetryService.emitToolCall('audit_pipeline', `audit-${Date.now().toString(36)}`, 'INFORMATIONAL', true);
    
          return {
            content: [{ type: 'text' as const, text: JSON.stringify({
              totalLedgerEntries: engine.ledger.size,
              uniqueOperations: engine.ledger.uniqueOperations,
              returned: limited.length,
              activeOperations: engine.ledger.getActiveOperations().length,
              chainHead: engine.ledger.chainHead,
              viewFilter: noiseFiltered
                ? { active: true, suppressNoise: input.suppress_noise, excludeActors: input.exclude_actors ?? [], note: 'Forensic ledger is complete — these filters apply to this view only.' }
                : { active: false },
              entries: limited,
            }, null, 2) }],
          };
        }
      );
    }
  • Zod schema defining input parameters: operation (optional string), limit (1-100, default 20), suppress_noise (boolean, default false), exclude_actors (optional array of strings). Plus metadata annotation with title, readOnlyHint, idempotentHint.
    {
      operation: z.string().optional().describe('Filter by operation name'),
      limit: z.number().min(1).max(100).default(20).describe('Maximum entries to return'),
      suppress_noise: z.boolean().default(false).describe(
        'When true, filters out known high-volume infrastructure actors (legacy-* prefix, SYSTEM) ' +
        'and lifecycle-only operations (mcp-reinitialize, mcp-initialize) from results. ' +
        'The full forensic ledger is never mutated — this is a view-layer filter only.'
      ),
      exclude_actors: z.array(z.string()).optional().describe(
        'Additional actor IDs or prefixes (prefix matched) to exclude from results. ' +
        'Useful for silencing a specific noisy integration without suppress_noise.'
      ),
    },
    { title: 'Query Audit Ledger', readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
  • Registration entry in TOOL_REGISTRY array: tier 'tenant', register function is registerAuditPipelineTool, described as 'audit_pipeline'. This means the tool is available to tenant and operator visibility tiers.
    { tier: 'tenant', register: registerAuditPipelineTool, description: 'audit_pipeline' },
    { tier: 'tenant', register: registerMonitorAgentsTool, description: 'monitor_agents' },
    { tier: 'tenant', register: registerSystemStatusTool, description: 'system_status' },
    { tier: 'tenant', register: registerGenerateReportTool, description: 'generate_report' },
    { tier: 'tenant', register: registerExportLedgerTool, description: 'export_ledger' },
    { tier: 'tenant', register: registerValueMetricsTools, description: 'value_metrics (record_value_metric, record_governance_event, generate_impact_report)' },
  • Import of registerAuditPipelineTool from the audit-pipeline.ts module into server.ts.
    import { registerAuditPipelineTool } from './tools/audit-pipeline.js';
    import { registerMonitorAgentsTool } from './tools/monitor-agents.js';
  • Telemetry/tool accountability profile: audit_pipeline is classified as 'read' tool class, 'low' risk tier, 'INFORMATIONAL' MAI default, no human approval required, category 'forensics'.
    { toolName: 'audit_pipeline',      toolClass: 'read',     riskTier: 'low',      maiDefault: 'INFORMATIONAL',  requiresHumanApproval: false, category: 'forensics' },
    { toolName: 'approve_gate',        toolClass: 'gate',     riskTier: 'critical', maiDefault: 'MANDATORY',      requiresHumanApproval: true,  category: 'governance' },
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, destructiveHint, and idempotentHint, establishing safety profile. Description adds that it returns a hash-chained audit trail with MAI classification, which provides slight behavioral context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences: first states the core purpose, second adds key details about return format. No redundant phrases, front-loaded with the main action.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 4 optional parameters, read-only annotations, and no output schema, the description provides sufficient context for a query tool. Mentions hash-chained trail and MAI classification, but could optionally note ordering or that results are recent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with each parameter having detailed descriptions. The tool description adds no extra meaning beyond what the schema provides, so baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool queries the audit ledger for governance entries, providing two specific use cases: search by operation name or retrieve recent entries. It distinguishes from sibling tools like export_ledger and verify_ledger by focusing on querying return of hash-chained audit trail with MAI classification context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance on when to use this tool versus alternatives like export_ledger or verify_ledger. The description only states what it does without mentioning exclusion criteria or comparative context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/knowledgepa3/gia-mcp-server'

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