Make your AI agents
multiplayer.

Give your agents shared context so they can coordinate, build on each other’s work, and pick up where others left off.

Create your workspace
Works with the agents and apps you already use.SlackGoogle ChatClaudeChatGPT

Open sourceSelf-hostuse Lobu Cloud

SlackAcme Co.
customer-health
MC

Maya Chen

@Lobu Save this decision to the workspace: I’ll review Meridian. Alex should check SEC-142 before I contact the customer.

LobuAPP

Saved Maya’s decision to Acme Co. Nothing has been sent to the customer.

Home — Lobu

Home

claude — acme

How it works

Connect Gmail so the agents I already use can read customer mail.
Check GmailCode
run_sdk
export default async (_ctx, client) => {
  return client.connections.list({ connector_key: "google.gmail" });
};

Open this and approve Gmail. One connection, scoped to Acme Co. I'll use it for customer mail, including renewal threads.

Connect Gmail

Customer usage lives in our Postgres database. Can you connect that too?
Collect customer usageCode
connectors/acme-usage.connector.ts
import {
  ConnectorRuntime, type RuntimeConnectorDefinition,
  type SyncCredentials,
} from "@lobu/connector-sdk";

type Checkpoint = { after?: string };
type Options = Record<string, never>;
type Usage = {
  id: string; customer: string; week: string;
  activeSeats: number; updatedAt: string;
};
// Application-specific Postgres adapter; implementation and auth omitted.
// It returns a stable cursor and only rows after the last checkpoint.
declare const usageDb: {
  changes(input: { after?: string; credentials: SyncCredentials | null }):
    Promise<{ rows: Usage[]; checkpoint: Checkpoint; more: boolean }>;
};

export default class AcmeUsage extends ConnectorRuntime<Checkpoint, Options> {
  readonly definition: RuntimeConnectorDefinition<Checkpoint, Options> = {
    key: "acme.usage", name: "Customer usage", version: "1.0.0",
    feeds: {
      usage: {
        key: "usage", name: "Weekly active seats",
        sync: async (ctx) => {
          const page = await usageDb.changes({
            after: ctx.checkpoint?.after, credentials: ctx.credentials,
          });
          await ctx.commit(page.rows.map((row) => ({
            origin_id: "usage:" + ctx.feedId + ":" + row.id,
            origin_type: "customer_usage",
            occurred_at: new Date(row.updatedAt),
            title: row.customer + " usage",
            payload_text: row.activeSeats + " active seats · " + row.week,
          })), page.checkpoint);
          return { status: page.more ? "more" : "complete" };
        },
      },
    },
  };
}

Collect selected usage changes alongside customer mail. Agents can compare weekly active seats with renewal dates and open issues.

Customer usage

Weekly active seats from Postgres. Each sync resumes from its saved checkpoint.

Example

Illustrative feed excerpt. Implement the database adapter and configure its credentials before deployment.

Can you also work from my computer and browser?

Install the Mac app for computer use and the Chrome extension for your logged-in tabs.

MacChrome
Connect each customer to their contacts, renewal date, and open issues.
Organize customer recordsCode
lobu.config.ts
import { defineEntityType, defineRelationshipType } from "@lobu/cli/config";

export const customer = defineEntityType({
  key: "customer", name: "Customer",
  properties: {
    domain: { type: "string" },
    accountOwner: { type: "string" },
    renewalDate: { type: "string" },
    openIssue: { type: "string" },
  },
});
export const contact = defineEntityType({ key: "contact", name: "Contact" });
export const contactFor = defineRelationshipType({
  key: "contact-for", name: "Contact For",
  description: "A person is a contact for a customer.",
  rules: [{ source: contact, target: customer }],
});

Your agents can now work with the same customer records and relationships—not separate copies.

Customers

Domain, account owner, renewal date, and open issue. Linked to their contacts.

Created
Contacts

The people connected to each customer record.

Created
Contact For

Contacts → Customers. Shared relationships your agents can query.

Created

Pick up where another person or agent left off.

Save findings and decisions to the workspace, then continue from another agent without copying the conversation across.

Illustrative shared-workspace handoff. No live customer data or actions.

Which customers need our attention, and why?
Customers who need attentionCode
run_sdk
export default async (_ctx, client) => {
  return client.query(`
    SELECT title, payload_text
    FROM events
    WHERE title = 'Meridian renewal'
    ORDER BY occurred_at DESC
    LIMIT 10
  `);
};

Ask in the agent you already have. The answer uses the same workspace. Creating a managed agent is optional.

Works inside the chat you already use
  • Slack
  • ChatGPT
  • Claude
  • Gemini

Meridian needs attention: usage fell 40%, SEC-142 is open, and renewal is September 30. Ask Maya to review the account; churn is not confirmed.

Maya Chen
Save this decision to the workspace: I’ll review Meridian. Alex should check SEC-142 before I contact the customer.
Save Maya’s decisionCode
run_sdk
export default async (_ctx, client) => {
  const workspace = await client.org("acme-co");
  const saved = await workspace.knowledge.save({
    title: "Meridian renewal decision",
    author: "Maya Chen",
    semantic_type: "decision",
    content: "I’ll review Meridian. Alex should check SEC-142 before I contact the customer.",
    idempotency_key: "meridian-renewal-decision:v1",
  });
  return workspace.knowledge.read({ content_ids: [saved.id] });
};

Saved Maya’s decision to Acme Co. Nothing has been sent to the customer.

What did Maya decide about Meridian, and what should I do next?
Continue in Claude with the saved decisionCode
run_sdk
export default async (_ctx, client) => {
  const workspace = await client.org("acme-co");
  return workspace.query(`
    SELECT title, payload_text
    FROM events
    WHERE title = 'Meridian renewal decision'
    ORDER BY occurred_at DESC
    LIMIT 1
  `);
};

Maya will review Meridian. Check SEC-142 and share your findings with her before any customer follow-up.

Saved decision · Maya Chen · Slack. The decision was explicitly saved—not copied from a private chat.

When a renewal comes up, draft the follow-up and wait for me.
Create the renewal follow-upCode
run_sdk
export default async (_ctx, client) => {
  return client.automations.create({
    slug: "renewal-follow-up",
    name: "Renewal follow-up",
    managed_agent_id: "customer-success",
    prompt: "Draft a follow-up for the account owner. Nothing is sent until someone approves it.",
    triggers: [
      { kind: "schedule", cron: "0 9 * * 1-5" },
      { kind: "event", source: "workspace", event_types: ["observation"] },
    ],
  });
};

Creating the Automation. It runs on schedule — and fires immediately when a matching workspace event lands. Nothing is sent until someone approves it.

Renewal follow-up

Weekday morning, plus matching workspace events. Checks the renewal date, usage, and open issues, then drafts a note for the account owner.

Created

First run already in — an overnight event triggered it ahead of the schedule.

First draft

Meridian renewal for Maya Chen. Names the owner, cites the open issue. Waiting for approval.

Ran

Refine the workflow. Keep the history.

Review a result, update the instructions, and use the revised version on the next run.

Don't predict churn. Name the owner and include the open issue.
Version the follow-up instructionsCode
run_sdk
export default async (_ctx, client) => {
  const workspace = await client.org("acme-co");
  const { automations } = await workspace.automations.list({});
  const followUp = automations.find(item => item.slug === "renewal-follow-up");
  if (!followUp) throw new Error("Create the renewal follow-up first.");
  return workspace.automations.createVersion({
    automation_id: followUp.id,
    prompt: "Draft a follow-up for the account owner. Include the account owner and open issue. Do not predict churn. Nothing is sent until someone approves it.",
  });
};

Saved as version 2. The next run will use the revised instructions.

Instructions updated

v2 · Include the account owner and open issue. Do not predict churn.

Updated
Maya Chen
Keep the earlier version so we can see what changed.

The earlier version remains in the history. This updates the renewal follow-up—not every agent in the workspace.

Install to your app to use LobuSlackGoogle ChatClaudeChatGPT

The work stays.
Your agents can change.

Lobu is an open-source workspace for people and AI agents. Connect Claude, ChatGPT, Codex or OpenClaw over MCP, and self-host it or use Lobu Cloud.

Your next agent shouldn’t start from scratch.

Connect it to the same workspace, with the access you choose, so it can build on the knowledge, decisions, and work your team has already saved.

Create your workspace