Skip to content
Scryr

Manifest language

A .scry file is a Python dialect loaded through Scryr’s manifest importer. It can import ordinary Python modules and sibling .scry modules, so normal composition and type checking still apply. Humans can review it as code, and AI agents can generate it without learning a proprietary diagram format.

Because the file executes as Python, it is useful beyond drawing the diagram. Teams can compose reusable declarations, inspect repository or environment data, and model deployment targets such as Kubernetes clusters or Helm releases with normal Python control flow. Keep those scripts deterministic, never put secrets in source, and review agent-generated files before execution.

A public Manifest variable becomes a block on the diagram. Its core fields are:

  • manifest_id: stable organization-scoped component identity.
  • name: the display label and connection target.
  • icon: an emoji or short icon string.
  • classification: the block’s architectural role.
  • tags: useful categories for filtering and queries.
  • connections: named links to other manifests.
  • forges: developer-environment configurations used by the component.

Add detail through typed sections: Info and OtherDiagram.

Info describes version, programming languages, frameworks, deployment targets and IaC tools, owners, metric tools, docs, and external links. Every enum field is a list: languages, frameworks, deployments, and metric_tools. Unspecified lists are empty; authentication is not part of Info. owners is a single string for now.

A public Diagram selects the blocks a reader should see together.

from scryr import Diagram
system = Diagram(name="System", manifests=[web, api, database])
customer_path = Diagram(name="Customer path", manifests=[web, api])

For large systems, use multiple diagrams for system context, customer paths, operability, or ownership boundaries.

Use ManifestQuery to select components by typed fields instead of maintaining a long list.

from scryr import Diagram, ManifestQuery
from scryr.types import ProgrammingLanguage
python_services = Diagram(
name="Python services",
query=ManifestQuery(languages=ProgrammingLanguage.python),
)

A diagram accepts either manifests=[...] or query=..., never both.

Set manifest_id on components that need a durable identity:

catalog = Manifest(manifest_id="services/catalog-api", name="Catalog API")

The ID remains stable if the display name changes. Use repository-relative, organization-scoped values with letters, digits, dots, underscores, colons, slashes, or hyphens.

The entrypoint can import local .scry and .py modules:

from services.catalog import catalog_api
from services.checkout import checkout_api
commerce = Diagram(name="Commerce", manifests=[catalog_api, checkout_api])

Scryr’s formatter, linter, and type checker follow reachable local imports. Public imported Scryr objects can also be exports, so unused-import warnings are suppressed for this workflow.

A public Forge models tools, environment variables, variables, tasks, settings, and plugins once.

from scryr import Forge
local = Forge(
name="Developer environment",
tools={"python": "3.14", "node": "24", "postgres": "17"},
tasks={
"install": "uv sync && npm install",
"dev": "npm run dev",
"test": "pytest && npm test",
},
)

Export the same declaration into useful project files:

Terminal window
scryr export mise --forge "Developer environment"
scryr export compose --forge "Developer environment"
scryr export devcontainer --forge "Developer environment"

The CLI normally uses the embedded SDK. To use a repository’s locked Python environment, add an empty scryr.toml beside a pyproject.toml that depends on scryr and an up-to-date uv.lock.

scryr.toml
# Presence opts this directory into project mode.

Scryr then runs uv sync --no-dev --locked for that project.