# How the OpenAPI Effect Layer Exposes RPC Endpoints in magnitudedev/magnitude

> Discover how the OpenAPI Effect layer in magnitudedev/magnitude compiles OpenAPI specs into typed RPC endpoints. Learn about operation descriptors and manifests for SDK client access.

- Repository: [Magnitude/magnitude](https://github.com/magnitudedev/magnitude)
- Tags: internals
- Published: 2026-09-08

---

**The OpenAPI Effect layer compiles an OpenAPI specification into fully-typed RPC endpoints using `compileOpenApi`, which generates operation descriptors and a manifest that the ACN daemon registers with its RPC server, exposing them to SDK clients.**

The `magnitudedev/magnitude` repository implements a protocol-driven architecture where API contracts are defined once in OpenAPI and automatically transformed into executable RPC endpoints. The **`@magnitudedev/openapi-effect`** package handles this transformation, bridging static specifications with the dynamic Effect-TS runtime used throughout the codebase.

---

## From OpenAPI Spec to Generated Project

The entry point for RPC exposure is **`compileOpenApi`** in [`packages/openapi-effect/src/compiler.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/openapi-effect/src/compiler.ts). This function performs a multi-stage compilation that converts an OpenAPI document into runnable code.

**Compilation stages:**

- **Parse and validate** the OpenAPI JSON/YAML against the supported subset of the specification
- **Build an intermediate representation (IR)** that normalizes paths, parameters, request bodies, and response schemas
- **Generate Effect Schemas** for runtime validation and type inference
- **Produce operation descriptors** (`HttpOperationDescriptor` for HTTP methods, `StreamOperationDescriptor` for streaming operations)
- **Emit a `GenerationManifest`** listing all generated modules and their RPC signatures

The function returns a **`GeneratedProject`** containing:

```typescript
interface GeneratedProject {
  files: Map<string, string>;     // filepath → TypeScript source
  manifest: GenerationManifest;   // RPC endpoint registry
}

```

This design ensures that every OpenAPI operation has a corresponding, type-safe RPC counterpart before any code is executed.

---

## Runtime Client Generation

Generated projects include **[`client-runtime.ts`](https://github.com/magnitudedev/magnitude/blob/main/client-runtime.ts)** ([`packages/openapi-effect/src/client-runtime.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/openapi-effect/src/client-runtime.ts)), which exports factory functions that wire descriptors to Effect's RPC layer.

**Key runtime helpers:**

- **`makeHttpOperation`** – Creates Effect functions from `HttpOperationDescriptor` instances
- **`makeStreamOperation`** – Creates streaming RPC clients from `StreamOperationDescriptor` instances

These helpers internally call **`Rpc.make`** from `acn-protocol`, the core primitive for registering callable operations in the Magnitude protocol. The result is a client function that:

1. Validates input against the generated Effect Schema
2. Serializes the request according to the OpenAPI parameter location (path, query, header, body)
3. Dispatches via the ACN RPC transport layer
4. Deserializes and validates the response

```typescript
// Generated client usage
import { makeHttpOperation } from "@magnitudedev/openapi-effect";

const getUser = makeHttpOperation({
  method: "GET",
  path: "/users/{userId}",
  // request/response schemas generated from OpenAPI components
});

// Effect-TS invocation
pipe(
  getUser({ userId: "123" }),
  Effect.runPromise
);

```

---

## ACN Daemon Registration

The generated manifest feeds into the **ACN (Agent Communication Network) daemon** build process. In [`packages/acn-protocol/scripts/generate.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/acn-protocol/scripts/generate.ts), the protocol layer consumes `compileOpenApi` output to create concrete handler implementations.

**Registration flow:**

1. Import the compiled manifest from the generated project
2. Iterate over `manifest.httpOperations` and `manifest.streamOperations`
3. Generate handler stubs in `packages/acn-protocol/src/boundary/`
4. Register each handler with **`Rpc.make`** to expose it on the daemon's internal protocol

```typescript
// Simplified daemon registration (from generate.ts pattern)
import { Rpc } from "@magnitudedev/acn-protocol";
import { manifest } from "./generated/manifest.js";

manifest.httpOperations.forEach((op) => {
  Rpc.make({
    name: op.name,
    handler: async (input) => {
      // Handler implementation calling underlying services
      return serviceLayer.execute(op, input);
    },
  });
});

```

This registration step is what **actually exposes** the RPC endpoints—without it, the generated client code would have no server counterpart to invoke.

---

## SDK and Client Consumption

The **`packages/sdk`** layer re-exports the generated client functions, while **`packages/client-common`** provides the transport glue that connects them to the ACN daemon's protocol.

**Client architecture:**

- **CLI clients** import directly from SDK and call operations as Effect programs
- **Web/desktop clients** use the same generated functions through a platform-specific transport adapter
- **Type safety** is preserved end-to-end because all clients share the same generated schemas

The OpenAPI Effect layer thus serves as the **single source of truth**: changes to the OpenAPI spec propagate automatically through compilation, daemon registration, and client code without manual synchronization.

---

## Summary

- **`compileOpenApi`** in [`packages/openapi-effect/src/compiler.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/openapi-effect/src/compiler.ts) transforms OpenAPI specs into `GeneratedProject` containing type-safe RPC descriptors
- **`makeHttpOperation`** and **`makeStreamOperation`** in [`packages/openapi-effect/src/client-runtime.ts`](https://github.com/magnitudedev/magnitude/blob/main/packages/openapi-effect/src/client-runtime.ts) create Effect- compatible client functions wired to `Rpc.make`
- The **ACN daemon build script** registers generated handlers from the manifest, exposing endpoints over the internal protocol
- **SDK clients** consume these endpoints with full compile-time and runtime type safety, ensuring the OpenAPI contract is enforced at every layer

---

## Frequently Asked Questions

### How does `compileOpenApi` handle validation errors in the OpenAPI specification?

`compileOpenApi` performs schema validation during the parsing stage and throws descriptive errors for unsupported OpenAPI features or malformed documents. The validation logic is integrated with the intermediate representation builder, ensuring that only well-formed specs proceed to code generation.

### Can I use the OpenAPI Effect layer without the ACN daemon?

Yes. The generated [`client-runtime.ts`](https://github.com/magnitudedev/magnitude/blob/main/client-runtime.ts) exports can be used with any Effect-compatible RPC transport. However, the full Magnitude stack expects daemon registration through `acn-protocol` for protocol compliance and service discovery.

### What is the performance overhead of the generated RPC layer?

The overhead is minimal: operation descriptors are plain objects, and `makeHttpOperation` creates lightweight Effect functions. Runtime validation uses optimized Effect Schemas, and the actual network transport is handled by pluggable adapters in `client-common`, not by the generator itself.

### How do streaming operations differ from HTTP operations in the generated code?

Streaming operations use `makeStreamOperation` instead of `makeHttpOperation`, producing Effect Streams (`Stream<A, E, R>`) rather than single-call Effects. The `StreamOperationDescriptor` includes additional metadata for subscription management and backpressure handling, as defined in the OpenAPI spec's `x-stream` extensions or AsyncAPI references.