sdd_save
Validates and persists an SDD contract, recording phase transitions for project traceability.
Instructions
Validate and persist an SDD contract. Records the phase transition for project traceability.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| contract | Yes | JSON string of the SDD contract to save |
Implementation Reference
- src/tools/sdd-contracts.ts:86-141 (handler)The main handler function for the 'sdd_save' tool. Parses the JSON contract, validates it with SddContractSchema, inserts it into the SQLite database, and returns the saved contract ID, phase, and project.
// ── Save SDD Contract ────────────────────────────── server.tool( "sdd_save", "Validate and persist an SDD contract. Records the phase transition for project traceability.", { contract: z.string().max(131072).describe("JSON string of the SDD contract to save"), }, async ({ contract }) => { try { const parsed = JSON.parse(contract); const result = SddContractSchema.parse(parsed); const db = getDb(); const id = generateId("sdd"); db.prepare( `INSERT INTO contracts (id, phase, change_name, project, status, confidence, executive_summary, data) VALUES (?, ?, ?, ?, ?, ?, ?, ?)` ).run( id, result.phase, result.change_name, result.project, result.status, result.confidence, result.executive_summary, JSON.stringify(result.data) ); return { content: [ { type: "text" as const, text: JSON.stringify({ saved: true, id, phase: result.phase, project: result.project, }), }, ], }; } catch (e) { return { content: [ { type: "text" as const, text: JSON.stringify({ saved: false, error: `${e}`, }), }, ], }; } } ); - src/types/index.ts:54-66 (schema)SddContractSchema: Zod schema defining the shape of an SDD contract (phase, change_name, project, status, confidence, executive_summary, artifacts, risks, etc.) used by the handler for validation.
export const SddContractSchema = z.object({ schema_version: z.string().max(32).default("1.0"), phase: z.enum(SDD_PHASES), change_name: z.string().min(1).max(256), project: z.string().min(1).max(256), status: z.enum(["success", "partial", "failed", "blocked"]), confidence: z.number().min(0).max(1), executive_summary: z.string().min(10).max(65536), artifacts_saved: z.array(ArtifactSchema).max(50).default([]), next_recommended: z.array(z.enum(SDD_PHASES)).max(9).default([]), risks: z.array(RiskSchema).max(50).default([]), data: z.record(z.unknown()).default({}), }); - src/tools/sdd-contracts.ts:12-88 (registration)The registerSddTools function registers all SDD tools (including sdd_save) on the McpServer instance.
export function registerSddTools(server: McpServer): void { // ── Validate SDD Contract ─────────────────────────── server.tool( "sdd_validate", "Validate an SDD contract against the phase schema. Returns validation result with confidence check and allowed transitions.", { contract: z .string() .max(131072) .describe("JSON string of the SDD contract to validate"), }, async ({ contract }) => { try { const parsed = JSON.parse(contract); const result = SddContractSchema.safeParse(parsed); if (!result.success) { return { content: [ { type: "text" as const, text: JSON.stringify({ valid: false, errors: result.error.issues.map((i) => ({ path: i.path.join("."), message: i.message, })), }), }, ], }; } const data = result.data; const threshold = CONFIDENCE_THRESHOLDS[data.phase]; const meetsConfidence = data.confidence >= threshold; const allowedNext = PHASE_TRANSITIONS[data.phase]; return { content: [ { type: "text" as const, text: JSON.stringify({ valid: true, phase: data.phase, confidence: data.confidence, threshold, meets_confidence: meetsConfidence, allowed_next_phases: allowedNext, warnings: !meetsConfidence ? [ `Confidence ${data.confidence} is below threshold ${threshold} for phase "${data.phase}"`, ] : [], }), }, ], }; } catch (e) { return { content: [ { type: "text" as const, text: JSON.stringify({ valid: false, errors: [{ path: "root", message: `Invalid JSON: ${e}` }], }), }, ], }; } } ); // ── Save SDD Contract ────────────────────────────── server.tool( "sdd_save", - src/utils/id.ts:1-6 (helper)generateId helper: creates a UUID-based ID with an optional prefix (used to generate the 'sdd-...' ID for the contract).
import { randomUUID } from "node:crypto"; export function generateId(prefix: string = ""): string { const uuid = randomUUID().replace(/-/g, ""); return prefix ? `${prefix}-${uuid}` : uuid; } - src/server.ts:12-22 (registration)Server creation that calls registerSddTools, which includes the 'sdd_save' tool registration.
export function createServer(): McpServer { const server = new McpServer({ name: "forgespec-mcp", version: pkg.version, }); registerSddTools(server); registerTaskBoardTools(server); registerFileTools(server); return server;