# Generate service clients and tool schemas

> Guide: Regenerate OpenAPI JSON, TypeScript clients, DCS model types, AI tool schemas, and MCP documentation pages from Rust sources.

- Repository: macro-inc/macro
- GitHub: https://github.com/macro-inc/macro
- Human docs: https://grok-wiki.com/public/docs/macro-inc-macro-bb988e1a448e
- Complete Markdown: https://grok-wiki.com/public/docs/macro-inc-macro-bb988e1a448e/llms-full.txt

## Source Files

- `js/app/scripts/generate-api-schema.ts`
- `js/app/scripts/generate-dcs-tools.ts`
- `js/app/scripts/services.ts`
- `rust/cloud-storage/ai_tools/src/lib.rs`
- `rust/cloud-storage/ai_tools/src/bin/gen_tool_schemas.rs`
- `docs/scripts/generate-mcp-tool-pages.ts`
- `docs/package.json`

---

---
title: "Generate service clients and tool schemas"
description: "Guide: Regenerate OpenAPI JSON, TypeScript clients, DCS model types, AI tool schemas, and MCP documentation pages from Rust sources."
---

Macro regenerates frontend service clients and AI tool artifacts from local Rust binaries under `rust/cloud-storage`; `js/app/scripts/generate-api-schema.ts` builds OpenAPI emitters, writes `openapi.json`, runs Orval, and applies DCS-specific model and tool generation when `document-cognition` is included.

## Generated artifact map

```text
Rust sources
  ├─ */src/openapi.rs                         -> service-*/openapi.json
  ├─ document_cognition_service/src/models_bin.rs -> service-cognition/generated/schemas/model.ts
  └─ ai_tools/src/bin/gen_tool_schemas.rs     -> ai_tools/schemas/tools.json
                                                   -> service-cognition/generated/tools/*
                                                   -> docs/AI/mcp/tools/*
```

| Artifact | Generator | Output |
| --- | --- | --- |
| OpenAPI JSON | `js/app/scripts/generate-api-schema.ts` | `js/app/packages/service-clients/service-*/openapi.json` |
| TypeScript service clients | Orval via `orval.config.ts` | `generated/client.ts`, `generated/zod.ts`, and generated schemas/models |
| DCS model enum | `document_cognition_service_models` + `generate-dcs-models.ts` | `service-cognition/generated/schemas/model.ts` |
| DCS AI tool validators and types | `gen_tool_schemas` + `generate-dcs-tools.ts` | `service-cognition/generated/tools/{schemas,types,tool}.ts` |
| MCP tool pages | `docs/scripts/generate-mcp-tool-pages.ts` | `docs/AI/mcp/tools/*.mdx`, `docs/config/tool-pages.json` |

<Note>
The main OpenAPI workflow runs local Rust binaries instead of fetching deployed `/api-doc/openapi.json` endpoints.
</Note>

## Prerequisites

- Bun installed for `js/app` and `docs` scripts.
- Rust toolchain available for `cargo build` in `rust/cloud-storage`.
- Run generation from the package directory shown in each command.
- SQLx is built in offline mode by the scripts with `SQLX_OFFLINE=true`.

## Regenerate service clients

<Steps>
<Step title="Generate all service clients">

```bash
cd js/app
bun run gen-api
```

This processes every service listed in `js/app/scripts/services.ts`.

</Step>

<Step title="Generate one service">

```bash
cd js/app
bun run gen-api -- document-cognition
```

Valid service names include `cloud-storage`, `properties-service`, `document-cognition`, `auth-service`, `notification-service`, `static-files`, `connection-gateway`, `contacts-service`, `unfurl-service`, `email-service`, `search-service`, and `scheduled-action`.

</Step>

<Step title="Verify generated clients are committed">

```bash
cd js/app
bun run gen-api -- --check
```

Check mode regenerates artifacts, compares `js/app/packages/service-clients`, reports changed and untracked files, and exits non-zero when generated files are out of sync.

</Step>
</Steps>

### Service and crate mapping

`generate-api-schema.ts` maps public service names to Rust crate binaries. Each mapped crate must expose an OpenAPI binary named `<crate>_openapi`.

| Service | Rust crate | Orval project | Output package |
| --- | --- | --- | --- |
| `cloud-storage` | `document_storage_service` | `storageService` | `service-storage` |
| `properties-service` | `properties_service` | `propertiesService` | `service-properties` |
| `document-cognition` | `document_cognition_service` | `cognitionService` | `service-cognition` |
| `auth-service` | `authentication_service` | `authService` | `service-auth` |
| `notification-service` | `notification_service` | `notificationService` | `service-notification` |
| `static-files` | `static_file_service` | `staticFileService` | `service-static-files` |
| `connection-gateway` | `connection_gateway` | `connectionGateway` | `service-connection` |
| `contacts-service` | `contacts_service` | `contactService` | `service-contacts` |
| `unfurl-service` | `unfurl_service` | `unfurlService` | `service-unfurl` |
| `email-service` | `email_service` | `emailService` | `service-email` |
| `search-service` | `search_service` | `searchService` | `service-search` |
| `scheduled-action` | `scheduled_action` | `scheduledActionService` | `service-scheduled-action` |

### Build behavior

The script builds all requested OpenAPI binaries in one Cargo invocation:

```bash
cd rust/cloud-storage
SQLX_OFFLINE=true cargo build --bin <crate>_openapi ...
```

Then it runs each binary from `target/debug`, captures stdout as OpenAPI JSON, writes the service package `openapi.json`, removes the old `generated` directory, and runs:

```bash
cd js/app/packages/service-clients
bun run orval --config orval.config.ts --project <orvalKey>
```

Set `OPENAPI_BINS_DIR` to reuse prebuilt binaries and skip the Cargo build phase:

```bash
cd js/app
OPENAPI_BINS_DIR=/absolute/path/to/bins bun run gen-api
```

## DCS model and tool generation

When `document-cognition` is part of the service set, `generate-api-schema.ts` performs extra work after Orval:

1. Runs `document_cognition_service_models`.
2. Writes temporary `.models.json`.
3. Runs `MODELS_JSON=.models.json bun scripts/generate-dcs-types.ts`.
4. Deletes `.models.json`.

`generate-dcs-types.ts` runs both DCS generators:

```bash
cd js/app
bun scripts/generate-dcs-types.ts
```

### Model enum output

`generate-dcs-models.ts` writes:

```text
js/app/packages/service-clients/service-cognition/generated/schemas/model.ts
```

When `MODELS_JSON` is set, it reads model metadata from the local file produced by the Rust model binary. Without `MODELS_JSON`, it fetches `${documentCognitionBase}/models`, where `MODE` and `LOCAL_BACKEND=true` control the selected base URL.

The generated file exports:

- `Model`
- `Model` constant map
- `AllModels`
- `ModelEnum`

### Tool schema output

Run the tool generator directly when only AI tool types changed:

```bash
cd js/app
bun run gen-tools
```

The generator builds and runs:

```bash
cd rust/cloud-storage
SQLX_OFFLINE=true cargo build --bin gen_tool_schemas

cd rust/cloud-storage/ai_tools
../target/debug/gen_tool_schemas
```

The Rust binary writes `rust/cloud-storage/ai_tools/schemas/tools.json` as a combined schema:

```json
{
  "$defs": {},
  "tools": [
    {
      "name": "ContentSearch",
      "input": "ContentSearch",
      "output": "SearchToolResponse"
    }
  ]
}
```

`generate-dcs-tools.ts` validates that combined shape, dereferences shared definitions, and writes:

| File | Purpose |
| --- | --- |
| `generated/tools/schemas.ts` | Zod v3 validators generated from JSON Schema definitions |
| `generated/tools/types.ts` | TypeScript definition types generated from `$defs` |
| `generated/tools/tool.ts` | `ToolName`, `NamedTool`, `deserializeToolCall`, and `deserializeToolResponse` |

`deserializeToolCall` and `deserializeToolResponse` return `neverthrow` `Result` values. Unknown tool names return `not_found`; schema parse failures return `parse_error`.

## Regenerate MCP tool documentation pages

The docs package exposes a separate generator:

```bash
cd docs
bun install
bun run generate:tools
```

This script rebuilds `gen_tool_schemas`, removes the generated MCP tools directory, then writes:

```text
docs/AI/mcp/tools/index.mdx
docs/AI/mcp/tools/<slug>.mdx
docs/config/tool-pages.json
```

`docs/package.json` also runs this generator during `prepare`.

<Warning>
In this checkout, `gen_tool_schemas` writes the combined `$defs`/`tools` shape used by the app tool generator, while `docs/scripts/generate-mcp-tool-pages.ts` is typed to read a `schemas` array with inline `inputSchema` and `outputSchema`. If `bun run generate:tools` fails while sorting `toolSchemas.schemas`, align the docs generator with the combined schema or change the Rust schema emitter intentionally.
</Warning>

## Runtime and schema ownership

`rust/cloud-storage/ai_tools/src/lib.rs` owns toolset composition:

- `all_tools()` builds the DCS chat toolset and prompt.
- `all_tool_combined_schema()` merges `all_tools()` with the `ReadThread` phantom tool for schema generation.
- `mcp_tools()` builds the MCP runtime toolset separately.

Do not assume generated MCP documentation is automatically scoped to the MCP runtime toolset unless the schema generator is changed to use `mcp_tools()`.

## Verification

After regeneration, check the generated files that match the source change:

```bash
git diff -- js/app/packages/service-clients
git diff -- rust/cloud-storage/ai_tools/schemas/tools.json
git diff -- docs/AI/mcp/tools docs/config/tool-pages.json
```

For frontend type safety:

```bash
cd js/app
bun run type-check
```

For docs links:

```bash
cd docs
bun run lint
```

CI runs `bun run gen-api -- --check` for Rust/API changes in the web app workflow and fails when generated service clients drift from Rust sources.

## Troubleshooting

| Symptom | Cause | Fix |
| --- | --- | --- |
| `No matching services found` | Unknown service argument | Use a name from `services.ts` |
| Service skipped | Missing `serviceToCrate` entry | Add the service-to-crate mapping |
| Binary timeout after `120000ms` | OpenAPI/model binary hung or took too long | Run the specific Cargo binary locally and inspect stderr |
| Generated clients out of sync in CI | Rust API changed without committed generated files | Run `cd js/app && bun run gen-api`, then commit outputs |
| Biome binary fails on NixOS | npm-installed Biome dynamic linking issue | The scripts detect NixOS and use system `biome` when available |
| Docs tool generation fails on `schemas` | Docs generator expects the old inline schema shape | Update `generate-mcp-tool-pages.ts` for `$defs`/`tools` or restore the expected Rust output |

## Related pages

<CardGroup>
<Card title="MCP overview" href="/AI/mcp/overview">
Runtime context for Macro MCP integration.
</Card>
<Card title="MCP tool reference" href="/AI/mcp/tools">
Generated tool pages produced from Rust tool schemas.
</Card>
</CardGroup>
