Source code for squadds_mcp.schemas

"""
Pydantic schemas for MCP tool inputs and outputs.
=================================================

These models define the structured data contracts for all MCP tools.
They enable:
  - Automatic JSON Schema generation for MCP clients
  - Input validation before tool execution
  - Type-safe, documented responses

Adding a New Schema
-------------------
1. Define a Pydantic BaseModel class with typed fields.
2. Use ``Field(...)`` to add descriptions — these become tool parameter docs.
3. Import and use the schema in your tool function's type annotations.
"""

from __future__ import annotations

from typing import Any

from pydantic import BaseModel, Field

# ---------------------------------------------------------------------------
# Input schemas
# ---------------------------------------------------------------------------


[docs] class SystemConfig(BaseModel): """Configuration for selecting a quantum system in SQuADDS.""" system_type: str = Field( description=( "Type of system to search. " "One of: 'qubit_cavity' (coupled qubit+cavity), " "'qubit' (qubit only), 'cavity_claw' (cavity only)." ), ) qubit: str = Field( default="TransmonCross", description="Qubit component name (e.g. 'TransmonCross').", ) cavity: str = Field( default="RouteMeander", description="Cavity component name (e.g. 'RouteMeander').", ) resonator_type: str = Field( default="quarter", description="Resonator type: 'quarter' or 'half'.", )
[docs] class TargetParams(BaseModel): """Target Hamiltonian parameters for a design search. Not all fields are required — which ones to set depends on ``system_type``: - **qubit**: ``qubit_frequency_GHz``, ``anharmonicity_MHz`` - **cavity_claw**: ``cavity_frequency_GHz``, ``kappa_kHz``, ``resonator_type`` - **qubit_cavity**: all of the above plus ``g_MHz`` """ qubit_frequency_GHz: float | None = Field( default=None, description="Target qubit frequency in GHz (typical range: 3–8 GHz).", ) anharmonicity_MHz: float | None = Field( default=None, description="Target anharmonicity in MHz (typical range: −500 to −50 MHz, negative).", ) cavity_frequency_GHz: float | None = Field( default=None, description="Target cavity/resonator frequency in GHz (typical range: 5–12 GHz).", ) kappa_kHz: float | None = Field( default=None, description="Target cavity linewidth (kappa) in kHz (typical range: 10–1000 kHz).", ) g_MHz: float | None = Field( default=None, description="Target qubit-cavity coupling strength in MHz (typical range: 10–200 MHz).", ) resonator_type: str | None = Field( default=None, description="Resonator type: 'quarter' or 'half'. Required for cavity searches.", )
[docs] def to_search_dict(self) -> dict[str, Any]: """Convert to a plain dict, dropping None values.""" return {k: v for k, v in self.model_dump().items() if v is not None}
# --------------------------------------------------------------------------- # Output schemas # ---------------------------------------------------------------------------
[docs] class ComponentListResult(BaseModel): """List of supported components or component names.""" items: list[str] = Field(description="List of component identifiers.") count: int = Field(description="Number of items.")
[docs] class ConfigListResult(BaseModel): """List of dataset configuration strings.""" configs: list[str] = Field(description="List of config name strings (e.g. 'qubit-TransmonCross-cap_matrix').") count: int = Field(description="Number of configs.")
[docs] class DatasetEntry(BaseModel): """A single row from a SQuADDS dataset, serialized as a dict.""" data: dict[str, Any] = Field(description="Column name → value mapping for this row.")
[docs] class DatasetResult(BaseModel): """Paginated dataset result.""" rows: list[dict[str, Any]] = Field(description="List of row dicts.") total_rows: int = Field(description="Total number of rows in the full dataset.") offset: int = Field(description="Starting offset of this page.") limit: int = Field(description="Maximum rows per page.") component: str = Field(description="Component type.") component_name: str = Field(description="Component name.") data_type: str = Field(description="Data type.")
[docs] class DatasetInfoResult(BaseModel): """Metadata about a SQuADDS dataset.""" config: str = Field(description="Config string (component-name-data_type).") num_rows: int = Field(description="Number of rows.") features: dict[str, str] = Field(description="Feature name → type mapping.") description: str = Field(default="", description="Dataset description.") size_bytes: int | None = Field(default=None, description="Dataset size in bytes.")
[docs] class DatasetSummaryRow(BaseModel): """Summary of a single available dataset.""" component: str component_name: str data_type: str
[docs] class DatasetSummaryResult(BaseModel): """Summary table of all available datasets.""" datasets: list[DatasetSummaryRow] count: int
[docs] class MeasuredDeviceResult(BaseModel): """Information about a measured (experimental) device.""" name: str = Field(description="Device name.") design_code: str | None = Field(default=None, description="Design code identifier.") paper_link: str | None = Field(default=None, description="Link to associated paper.") foundry: str | None = Field(default=None, description="Fabrication foundry.") fabrication_recipe: Any | None = Field(default=None, description="Fabrication recipe details.")
[docs] class DesignResult(BaseModel): """Result from a closest-design search.""" rank: int = Field(description="Rank (1 = closest).") design_options: dict[str, Any] = Field(description="Full design options dict.") hamiltonian_params: dict[str, Any] = Field(description="Computed Hamiltonian parameters.") metadata: dict[str, Any] = Field(default_factory=dict, description="Additional metadata (coupler_type, etc.).")
[docs] class ClosestDesignsResult(BaseModel): """Result set from find_closest_designs.""" designs: list[DesignResult] = Field(description="Ranked list of closest designs.") num_results: int = Field(description="Number of results returned.") target_params: dict[str, Any] = Field(description="The target parameters used for the search.") system_config: dict[str, Any] = Field(description="The system configuration used.")
[docs] class InterpolatedDesignResult(BaseModel): """Result from scaling interpolation.""" design_options: dict[str, Any] = Field(description="Interpolated design options (qubit + cavity + coupler).") qubit_options: dict[str, Any] = Field(description="Qubit-specific design options.") cavity_options: dict[str, Any] = Field(description="Cavity-specific design options.") coupler_type: str | None = Field(default=None, description="Coupler type used.") scaling_info: dict[str, Any] = Field(default_factory=dict, description="Scaling factors applied.")
[docs] class ContributorInfo(BaseModel): """Information about a data contributor.""" uploader: str | None = None PI: str | None = None group: str | None = None institution: str | None = None
[docs] class ContributorsResult(BaseModel): """List of contributors.""" contributors: list[ContributorInfo] count: int
[docs] class HamiltonianKeysResult(BaseModel): """Valid Hamiltonian parameter keys for a given system type.""" keys: list[str] = Field(description="List of valid target parameter keys.") system_type: str = Field(description="The system type these keys apply to.")
[docs] class VersionResult(BaseModel): """SQuADDS version information.""" squadds_version: str mcp_server_version: str repo_name: str