Skip to content

Tool Schemas

Complete schema definitions for all Orchestre MCP tools.

Overview

Orchestre uses Zod for schema validation. All tool inputs are validated against these schemas before processing.

Tool Schemas

initialize_project

Initialize a new project with a selected template.

typescript
import { z } from 'zod';

const initializeProjectSchema = z.object({
  projectName: z.string()
    .min(1, "Project name is required")
    .max(100, "Project name too long")
    .regex(/^[a-z0-9-]+$/, "Project name must be lowercase with hyphens"),
    
  template: z.enum([
    "cloudflare-hono",
    "makerkit-nextjs", 
    "react-native-expo"
  ]).describe("Template to use for initialization"),
  
  projectPath: z.string()
    .min(1, "Project path is required")
    .describe("Absolute path where project will be created"),
    
  requirements: z.string()
    .optional()
    .describe("Optional project requirements for customization")
});

// Example usage
const params = {
  projectName: "my-saas-app",
  template: "makerkit-nextjs",
  projectPath: "/Users/dev/projects/my-saas-app"
};

analyze_project

Analyze project requirements using AI.

typescript
const analyzeProjectSchema = z.object({
  requirements: z.string()
    .min(10, "Requirements too short")
    .max(5000, "Requirements too long")
    .describe("Natural language project requirements"),
    
  constraints: z.array(z.string())
    .optional()
    .describe("Technical or business constraints"),
    
  existingCode: z.boolean()
    .optional()
    .default(false)
    .describe("Whether analyzing existing codebase"),
    
  projectPath: z.string()
    .optional()
    .describe("Path to existing project for context")
});

// Example usage
const params = {
  requirements: "Build a multi-tenant SaaS platform with subscription billing",
  constraints: ["Must use Next.js", "PostgreSQL database", "Stripe for payments"],
  existingCode: false
};

generate_plan

Generate an implementation plan based on analysis.

typescript
const generatePlanSchema = z.object({
  analysis: z.object({
    complexity: z.enum(["simple", "moderate", "complex"]),
    estimatedHours: z.number(),
    technologies: z.array(z.object({
      name: z.string(),
      purpose: z.string(),
      required: z.boolean()
    })),
    risks: z.array(z.object({
      type: z.string(),
      description: z.string(),
      mitigation: z.string(),
      severity: z.enum(["low", "medium", "high"])
    }))
  }).describe("Analysis result from analyze_project"),
  
  requirements: z.string()
    .describe("Original requirements for context"),
    
  preferences: z.object({
    maxPhases: z.number().optional().default(5),
    prioritization: z.enum(["speed", "quality", "learning"])
      .optional()
      .default("quality"),
    parallelism: z.boolean().optional().default(true)
  }).optional()
});

// Example usage
const params = {
  analysis: analysisResult,
  requirements: "Build a multi-tenant SaaS platform",
  preferences: {
    maxPhases: 4,
    prioritization: "speed",
    parallelism: true
  }
};

multi_llm_review

Review code using multiple language models.

typescript
const multiLlmReviewSchema = z.object({
  files: z.array(z.object({
    path: z.string(),
    content: z.string(),
    language: z.string().optional()
  })).min(1, "At least one file required for review"),
  
  reviewType: z.enum([
    "security",
    "performance", 
    "quality",
    "comprehensive"
  ]).optional().default("comprehensive"),
  
  context: z.string()
    .optional()
    .describe("Additional context for reviewers"),
    
  specificConcerns: z.array(z.string())
    .optional()
    .describe("Specific areas to focus on"),
    
  models: z.array(z.string())
    .optional()
    .default(["gpt-4o", "claude-3-sonnet"])
    .describe("Models to use for review")
});

// Example usage
const params = {
  files: [
    {
      path: "/src/auth/login.ts",
      content: "...",
      language: "typescript"
    }
  ],
  reviewType: "security",
  specificConcerns: ["SQL injection", "XSS vulnerabilities"],
  models: ["gpt-4o", "claude-3-sonnet", "gemini-pro"]
};

research

Research technical topics and best practices.

typescript
const researchSchema = z.object({
  topic: z.string()
    .min(3, "Topic too short")
    .max(200, "Topic too long")
    .describe("Research topic or question"),
    
  depth: z.enum(["quick", "standard", "comprehensive"])
    .optional()
    .default("standard")
    .describe("Research depth level"),
    
  sources: z.array(z.enum([
    "documentation",
    "best-practices",
    "case-studies",
    "security-advisories",
    "performance-guides"
  ])).optional()
    .describe("Preferred source types"),
    
  outputFormat: z.enum(["summary", "detailed", "actionable"])
    .optional()
    .default("actionable")
    .describe("Desired output format")
});

// Example usage
const params = {
  topic: "Implementing multi-tenancy in Next.js applications",
  depth: "comprehensive",
  sources: ["documentation", "best-practices", "case-studies"],
  outputFormat: "actionable"
};

Schema Patterns

Common Field Types

typescript
// String with constraints
const nameField = z.string()
  .min(1, "Name is required")
  .max(50, "Name too long")
  .regex(/^[a-zA-Z0-9-_]+$/, "Invalid characters");

// Optional with default
const optionalBoolean = z.boolean()
  .optional()
  .default(true);

// Enum with description
const typeEnum = z.enum(["type1", "type2", "type3"])
  .describe("Selection type");

// Array with validation
const itemArray = z.array(z.string())
  .min(1, "At least one item required")
  .max(10, "Too many items");

// Nested object
const nestedObject = z.object({
  id: z.string(),
  data: z.object({
    value: z.number(),
    unit: z.string()
  })
});

Validation Helpers

typescript
// Email validation
const email = z.string().email("Invalid email format");

// URL validation
const url = z.string().url("Invalid URL format");

// Date validation
const date = z.string().datetime("Invalid date format");

// Custom validation
const customValidation = z.string().refine(
  (val) => val.includes("@"),
  { message: "Must contain @ symbol" }
);

Error Handling

typescript
try {
  const validated = schema.parse(input);
  // Process validated input
} catch (error) {
  if (error instanceof z.ZodError) {
    return {
      error: "Validation failed",
      issues: error.errors.map(e => ({
        path: e.path.join("."),
        message: e.message
      }))
    };
  }
}

Response Schemas

Success Response

typescript
const successResponseSchema = z.object({
  success: z.literal(true),
  data: z.any(),
  metadata: z.object({
    timestamp: z.string().datetime(),
    duration: z.number().optional(),
    version: z.string()
  }).optional()
});

Error Response

typescript
const errorResponseSchema = z.object({
  error: z.string(),
  code: z.string(),
  details: z.any().optional(),
  suggestion: z.string().optional(),
  documentation: z.string().url().optional()
});

Progress Response

typescript
const progressResponseSchema = z.object({
  status: z.enum(["pending", "in_progress", "completed", "failed"]),
  progress: z.number().min(0).max(100).optional(),
  message: z.string(),
  estimatedTime: z.string().optional(),
  currentStep: z.string().optional(),
  totalSteps: z.number().optional()
});

Advanced Schemas

Conditional Validation

typescript
const conditionalSchema = z.object({
  type: z.enum(["basic", "advanced"]),
  settings: z.any()
}).refine(
  (data) => {
    if (data.type === "advanced") {
      return typeof data.settings === "object";
    }
    return true;
  },
  { message: "Advanced type requires settings object" }
);

Dynamic Schemas

typescript
function createDynamicSchema(fields: string[]) {
  const shape: Record<string, z.ZodTypeAny> = {};
  
  fields.forEach(field => {
    shape[field] = z.string().optional();
  });
  
  return z.object(shape);
}

Schema Composition

typescript
const baseSchema = z.object({
  id: z.string(),
  createdAt: z.string().datetime()
});

const extendedSchema = baseSchema.extend({
  name: z.string(),
  description: z.string().optional()
});

const mergedSchema = z.intersection(
  baseSchema,
  z.object({ extra: z.string() })
);

Usage Examples

In Tool Implementation

typescript
import { z } from 'zod';
import { analyzeProjectSchema } from './schemas';

export async function analyzeProject(params: unknown) {
  // Validate input
  const validated = analyzeProjectSchema.parse(params);
  
  // Use validated data
  const analysis = await performAnalysis(validated.requirements);
  
  return {
    content: [{
      type: "text",
      text: JSON.stringify(analysis, null, 2)
    }]
  };
}

In Tests

typescript
describe('analyzeProject schema', () => {
  it('validates correct input', () => {
    const input = {
      requirements: "Build a web application",
      constraints: ["Use React"]
    };
    
    expect(() => analyzeProjectSchema.parse(input)).not.toThrow();
  });
  
  it('rejects invalid input', () => {
    const input = {
      requirements: "Too short"
    };
    
    expect(() => analyzeProjectSchema.parse(input)).toThrow();
  });
});

Best Practices

  1. Always validate inputs before processing
  2. Provide clear error messages for validation failures
  3. Use appropriate constraints (min/max lengths, patterns)
  4. Document optional fields with descriptions
  5. Consider edge cases in validation rules
  6. Test schema validation thoroughly
  7. Version schemas when making breaking changes

See Also

Built with ❤️ for the AI Coding community, by Praney Behl