DEV Community

Diego Carlino
Diego Carlino

Posted on

SLOP: A protocol for AI to observe and interact with application state

AI agents interact with apps through two bad options today:

  • Screenshots — expensive, lossy, fragile. The AI parses pixels to recover information the app already had in structured form.
  • Tool calls (MCP, function calling) — the AI can act, but it's flying blind. No awareness of what the user sees or what state the app is in.

I built SLOP (State Layer for Observable Programs) to fix this.

How it works

Apps expose a semantic state tree — structured, meaning-level data about what they currently are. Not pixels. Not DOM elements. Not database rows. Meaning.

An email app doesn't expose <div class="row"> — it exposes messages with subjects, senders, and read status.

AI subscribes to the parts of the tree it cares about and gets pushed incremental updates (JSON Patch). No polling, no redundant full reads.

Contextual actions, not global tools

This is the key difference from MCP.

MCP gives AI a flat list of tools: send_email(), merge_pr(), create_task(). The tools exist whether or not they make sense right now.

SLOP actions live on the nodes they affect. A "reply" action lives on the message it replies to. A "merge" action appears on a PR node — but only when the PR is actually mergeable. Actions come and go as state changes.

The AI always sees exactly what it can do, in context.

What ships

  • 13-doc spec covering state trees, transport (WebSocket, Unix socket, stdio, postMessage), affordances, attention/salience, scaling, and limitations
  • 14 SDK packages — TypeScript (core, client, server, consumer, React, Vue, Solid, Svelte, Angular, TanStack Start), Python, Rust, Go
  • Chrome extension that connects to any SLOP-enabled app
  • Desktop app (Tauri) and CLI inspector
  • Working examples across 4 languages and 5 frontend frameworks

Quick example

Adding SLOP to an app takes a few lines:

import { createSlopServer } from "@slop-ai/server";

const slop = createSlopServer({ id: "my-app", name: "My App" });

// Expose state
slop.register("inbox", {
  type: "collection",
  props: { unread: 3 },
  children: messages.map(m => ({
    id: m.id,
    type: "message",
    props: { subject: m.subject, from: m.from, read: m.read },
    affordances: [
      { id: "reply", label: "Reply", params: { type: "object", properties: { body: { type: "string" } } } },
      ...(m.read ? [] : [{ id: "mark-read", label: "Mark as read" }])
    ]
  }))
});
Enter fullscreen mode Exit fullscreen mode

An AI agent connecting to this sees the inbox, its messages, and exactly which actions are available on each message right now.

Use MCP for general-purpose tools. Use SLOP when AI needs awareness of application state.

Try it

Or find out more

All MIT licensed. Feedback welcome — especially on the spec design and whether the contextual affordance model makes sense for how you're building agents.

Top comments (0)