@segmentstream-cloud/ontology · ontology/

Model your business in code. Get a database, an API and MCP tools.

The backend of a workspace app. The ontology/ folder declares entities, relationships, roles and the actions people and agents may take. From that one definition the platform builds the tables in your Postgres database, the REST API, the OpenAPI reference, the typed client and the MCP server.

Get started

ontology/
$ npm install @segmentstream-cloud/ontology effect@4.0.0-rc.113

At a glance

  • Entities, properties, relationships, actions and roles in TypeScript
  • Every write is an action, in one transaction, with history
  • Served as REST, OpenAPI, a typed client and MCP from one definition
  • Written with Effect; Apache-2.0

What it does

01

Entities and relationships

An entity has typed properties, relationships named in both directions and a description agents read. Its id is permanent, so a deploy can tell a rename from a new entity.

ontology/lead.ts
import { entity, p, rel, User } from "@segmentstream-cloud/ontology";export const Lead = entity("lead", {  id: "ent_01J9Q4M8ZK",  label: "Lead",  plural: "Leads",  title: "email",  description: "A person who asked for a pilot.",  properties: {    email: p.email({ unique: true, description: "The address they submitted." }),    status: p.select(      [        { value: "new", label: "New", description: "Nobody has replied yet." },        { value: "won", label: "Won", description: "They became a customer. Final." },      ],      { default: "new", managed: true },    ),  },  relationships: {    owner: rel.one(User, {      optional: true,      inverse: "ownedLeads",      onDelete: "setNull",      phrase: ["is owned by", "owns"],      description: "The team member responsible for the next step.",    }),  },});
02

Actions with your rules inside

Records change only through actions. An action validates its input, checks the caller's permission, runs your rules in one transaction and writes history. ActionRejected undoes the transaction and tells the caller why.

ontology/lead.ts
.actions((self) => ({  win: action({    description: "Mark the lead as won.",    input: Schema.Struct({ lead: self.ref }),    // Requires lead:win: <entity>:<action name>.    handler: ({ input }) =>      Effect.gen(function* () {        const lead = yield* self.get(input.lead, { forUpdate: true });        if (lead.status === "won") {          return yield* new ActionRejected({ message: "The lead is already won." });        }        yield* self.update(lead, { status: "won" });      }),  }),}));
03

Roles and sign-in

A permission is <entity>:<verb>; a role is a named set of them. Every member holds member, and sign-in admits only the people you invite.

ontology/index.ts
export const sales = role("sales", {  description: "Works leads to a pilot.",  permissions: ["lead:read", "lead:win"],});export default defineOntology({  entities: [Lead],  roles: [sales],  member: { permissions: ["*:read"] },  signIn: { policy: "invited" },});
04

Connections inside actions

An action can call a workspace connection for one record before its transaction opens. The credentials stay with the platform.

ontology/lead.ts
export const apollo = connection("apollo", {  description: "Apollo people search. Enriches new leads with company and title.",});enrich: action({  description: "Fill the lead's company from Apollo.",  input: Schema.Struct({ lead: self.ref }),  connections: [apollo],  prepare: ({ input }) =>    Effect.gen(function* () {      const lead = yield* self.get(input.lead);      const response = yield* apollo.post("/people/match", { json: { email: lead.email } });      return yield* response.json(ApolloMatch);    }),  handler: ({ input, prepared }) =>    Effect.gen(function* () {      const lead = yield* self.get(input.lead, { forUpdate: true });      yield* self.update(lead, { company: prepared.company });    }),}),
05

Measures

Declare measures on an entity, over its records or a warehouse table. Apps, agents and the CLI ask for totals by dimension, and the service checks read permission on every entity a request touches.

ontology/lead.ts
measures: {  leads: m.count({ description: "Leads, in every status." }),  companies: m.countDistinct("company", { description: "Distinct companies among leads." }),},
06

Checked before it deploys

Check the definition and plan the migration locally. A deploy refuses unsafe changes, such as a type change or a dropped property, before anything applies.

ontology/
$ npx segmentstream-ontology check$ npx segmentstream-ontology check --catalog$ npx segmentstream-ontology migrate --plan

The rest of the surface

Your company’s software, built by agents, owned by you.

$ segmentstream workspace create acme --region eu --subdomain acme

▸ Created workspace acme · database, warehouse and a private git repository

$ segmentstream workspace WORKSPACE-ID clone acme && cd acme

▸ your agent writes the five folders and runs the checks

$ git add -A && git commit -m "First version"

$ segmentstream deploy

▸ app, ontology API and MCP tools live for your invited members

Start a pilot

Our engineers build the first version on your data in two weeks, at a fixed price.

Or join the waitlist for self-serve:

We’ll email you product updates, tips and onboarding help. Unsubscribe anytime.

Self-serve opens to the waitlist first.