complete_receipt
Finalize a pending receipt by recording execution results, costs, and output data. Updates status to completed, failed, or timeout and re-signs with Ed25519.
Instructions
Finalize a pending receipt by recording execution results, costs, and output data. Updates the receipt status to completed, failed, or timeout and re-signs with Ed25519. Use after create_receipt when you need to record results separately from creation (two-phase tracking). Cannot complete an already-completed receipt. Returns the updated signed receipt.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| receipt_id | Yes | The receipt ID to complete — must be a pending receipt (status: "pending") | |
| status | Yes | Final status: "completed" (success), "failed" (error occurred), or "timeout" (timed out) | |
| output_hash | No | Pre-computed SHA-256 hash of the output in format "sha256:hexstring" | |
| output_summary | No | Human-readable summary of the execution result | |
| model | No | AI model used during execution | |
| tokens_in | No | Input tokens consumed | |
| tokens_out | No | Output tokens generated | |
| cost_usd | No | Total cost in USD | |
| latency_ms | No | Total execution time in milliseconds | |
| tool_calls | No | Names of tools called during execution | |
| confidence | No | Confidence score for output quality, 0.0 to 1.0 | |
| callback_verified | No | Whether an external callback verified the result | |
| error | No | Error details if status is "failed" (e.g., {"code": "TIMEOUT", "message": "..."}) |
Implementation Reference
- The ReceiptEngine.complete() method that executes the core completion logic: fetches the pending receipt, updates fields (status, output_hash, timestamps, costs, etc.), evaluates constraints if present, re-signs with Ed25519, validates against the ActionReceipt schema, and persists the updated receipt.
async complete(receiptId: string, params: CompleteParams): Promise<ActionReceipt> { const existing = await this.store.get(receiptId) if (!existing) { throw new Error(`Receipt not found: ${receiptId}`) } if (existing.status !== 'pending') { throw new Error(`Receipt ${receiptId} is not pending (status: ${existing.status})`) } const now = new Date().toISOString() const updated = { ...existing, status: params.status, completed_at: now, output_hash: params.output_hash ?? existing.output_hash, output_summary: params.output_summary ?? existing.output_summary, model: params.model ?? existing.model, tokens_in: params.tokens_in ?? existing.tokens_in, tokens_out: params.tokens_out ?? existing.tokens_out, cost_usd: params.cost_usd ?? existing.cost_usd, latency_ms: params.latency_ms ?? existing.latency_ms, tool_calls: params.tool_calls ?? existing.tool_calls, confidence: params.confidence ?? existing.confidence, callback_verified: params.callback_verified ?? existing.callback_verified, error: params.error ?? existing.error, metadata: params.metadata ? { ...existing.metadata, ...params.metadata } : existing.metadata, constraint_result: existing.constraint_result, } // Evaluate constraints if present on the receipt const storedConstraints = existing.constraints as { definitions: ConstraintDefinition[] } | null const constraints = storedConstraints?.definitions ?? null if (Array.isArray(constraints) && constraints.length > 0) { updated.constraint_result = evaluateConstraints( updated as unknown as ActionReceipt, constraints, ) } // Re-sign with updated data const signable = getSignablePayload(updated) const signature = signReceipt(signable, this.keyManager.getPrivateKey()) updated.signature = signature const receipt = ActionReceipt.parse(updated) await this.store.save(receipt) return receipt } - The registerCompleteReceipt function that defines the MCP tool 'complete_receipt', registers its Zod input schema, and its async handler which extracts receipt_id, delegates to engine.complete(), and returns the receipt as JSON.
export function registerCompleteReceipt(server: McpServer, engine: ReceiptEngine): void { server.tool( 'complete_receipt', 'Finalize a pending receipt by recording execution results, costs, and output data. Updates the receipt status to completed, failed, or timeout and re-signs with Ed25519. Use after create_receipt when you need to record results separately from creation (two-phase tracking). Cannot complete an already-completed receipt. Returns the updated signed receipt.', { receipt_id: z.string().describe('The receipt ID to complete — must be a pending receipt (status: "pending")'), status: z.enum(['completed', 'failed', 'timeout']).describe('Final status: "completed" (success), "failed" (error occurred), or "timeout" (timed out)'), output_hash: z.string().nullable().optional().describe('Pre-computed SHA-256 hash of the output in format "sha256:hexstring"'), output_summary: z.string().nullable().optional().describe('Human-readable summary of the execution result'), model: z.string().nullable().optional().describe('AI model used during execution'), tokens_in: z.number().int().nonnegative().nullable().optional().describe('Input tokens consumed'), tokens_out: z.number().int().nonnegative().nullable().optional().describe('Output tokens generated'), cost_usd: z.number().nonnegative().nullable().optional().describe('Total cost in USD'), latency_ms: z.number().int().nonnegative().nullable().optional().describe('Total execution time in milliseconds'), tool_calls: z.array(z.string()).nullable().optional().describe('Names of tools called during execution'), confidence: z.number().min(0).max(1).nullable().optional().describe('Confidence score for output quality, 0.0 to 1.0'), callback_verified: z.boolean().nullable().optional().describe('Whether an external callback verified the result'), error: z.record(z.unknown()).nullable().optional().describe('Error details if status is "failed" (e.g., {"code": "TIMEOUT", "message": "..."})'), }, async (params) => { const { receipt_id, ...completeParams } = params const receipt = await engine.complete(receipt_id, completeParams) return { content: [{ type: 'text' as const, text: JSON.stringify(receipt, null, 2) }], } }, ) - packages/schema/src/index.ts:38-73 (schema)The CompleteReceiptInput Zod schema defining the input validation for the complete_receipt tool, including status enum ('completed', 'failed', 'timeout') and optional fields for output, costs, timing, tools, confidence, callback, and error details.
ConfidenceLevel, Observation, Relationship, Entity, MemoryReceiptPayload, MemoryQuery, MemoryBundle, } from './memory' // Validation utilities export { validate, formatZodError, createErrorResponse } from './validation' // Re-export types explicitly for consumers who import types only export type { ReceiptStatus as ReceiptStatusType, ReceiptType as ReceiptTypeType, Environment as EnvironmentType, ErrorCode as ErrorCodeType, } from './enums' - packages/schema/src/index.ts:55-73 (schema)The CompleteReceiptInput TypeScript type inferred from the Zod schema.
ErrorCode as ErrorCodeType, } from './enums' - packages/mcp-server/src/tools/index.ts:38-38 (registration)Registration call to registerCompleteReceipt(server, engine) within the registerAllTools function that wires up all MCP tools.
registerCompleteReceipt(server, engine)