Skip to content

Quickstart

Create a Tenchi application, run its checks, and make one contract change that you can observe at every boundary.

Requirements

Tenchi requires Python 3.12 or newer. The examples use uv to create environments and run commands.

Create the application

uvx tenchi new my_app
cd my_app
uv sync

The scaffold is intentionally a small complete application rather than a single route. Its important files are:

PathResponsibility
app/features/todos/contracts.pyHTTP method, path, inputs, response, and metadata
app/features/todos/schemas.pyPydantic boundary and application data models
app/features/todos/use_cases/Plain application functions
app/features/todos/ports.pyApp-owned infrastructure protocols
app/infra/SQLite runtime adapter, memory test adapter, and port wiring
app/server/context.pyFrozen context passed to use cases
app/server/runtime.pyLifespan and context wiring shared by entrypoints
app/server/preflight.pyRead-only checks of the target deployment environment
app/server/jobs.pyBackground-job handler composition
app/server/tasks.pyOperational task composition
app/server/tools.pyRegistered machine-facing tool composition
app/server/asgi.pyComposition root and ASGI application
openapi.json and tools.jsonVersion-controlled HTTP and tool contracts
AGENTS.mdPlacement rules and the complete agent validation loop
.mcp.jsonProject-local registration for MCP-aware coding agents
.github/workflows/ci.ymlChecks and historical boundary compatibility gates

The starter preflight group is empty because a local source check must not contact an environment implicitly. Add production dependency observations by following deployment preflight.

Run the checks

uv run tenchi check

The command runs Ruff formatting and linting, Pyright, pytest, doctor, and the OpenAPI and application-tool snapshot checks. It runs every step even after a failure so one pass reports the complete repair list. Generated code passes untouched. Use-case tests run without an HTTP server; integration tests exercise the composed ASGI application.

Start the server

uv run tenchi dev

The runtime database defaults to my_app.db. Set MY_APP_DATABASE to choose a different path.

In another terminal:

curl -i \
  -H 'content-type: application/json' \
  -d '{"title":"Buy milk"}' \
  http://127.0.0.1:8000/todos

curl http://127.0.0.1:8000/todos

The create response is validated as Todo, returns status 201, and includes the declared Location header. Restart the server and list again: the todo is still present because the startup lifespan ensures the SQLite schema while each request owns its own commit-or-rollback transaction.

Open http://127.0.0.1:8000/docs to inspect and call the same contracts through Swagger UI. The underlying document is served at /openapi.json, and /health exposes the starter's liveness route.

Make the first contract change

Open app/features/todos/schemas.py and require a longer title:

 class CreateTodo(BaseModel):
-    title: str = Field(min_length=1)
+    title: str = Field(min_length=3)

The server now rejects shorter input before the use case runs. Generate the current OpenAPI and compare it to the committed baseline:

uv run tenchi openapi \
  --routes app.server.routes:api_routes \
  --title my_app \
  --diff openapi.json

Tightening a request constraint is breaking for existing callers, so the command fails and explains the affected operation. Restore the old constraint, then add an optional field instead:

class CreateTodo(BaseModel):
    title: str = Field(min_length=1)
    notes: str | None = None

The compatibility report now classifies the change as additive. After reviewing it, update the snapshot:

uv run tenchi openapi \
  --routes app.server.routes:api_routes \
  --title my_app \
  --write openapi.json
uv run tenchi check
Keep the baseline historical

Run --diff before replacing the snapshot. The generated CI runs --diff-ref against the pull request's base commit, so committing an updated snapshot cannot hide an incompatible contract change.

Add another feature

uv run tenchi make feature notes
uv run tenchi make use-case notes create_note
uv run tenchi map --feature notes

Generators create files and print the wiring steps. They do not edit existing composition modules, keeping dependency wiring visible and app-owned. Add --dry-run to preview every file or --json for a versioned result. The map shows the new declarations before they are wired. Runtime-bound contracts, use cases, and adapters become registered after you follow the printed composition steps. Use tenchi map --feature notes --json when an agent or another tool will consume the graph. See coding agents for the complete inspect, preview, edit, and validate loop, or connect the coding-agent MCP server to expose those operations as agent tools.

Next, read the mental model, then follow app architecture when deciding where new code belongs.