GitHub - cliffhall/puzzlebox: An MCP server that hosts finite state machines as dynamic resources that multiple clients can subscribe to and be updated when their state changes. (original) (raw)

puzzlebox

Coordinating agents with state machines

An MCP server that hosts finite state machines as dynamic resources that clients can subscribe to and be updated when their state changes.

Feature Roadmap and Status

A work in progress. Much is done, a few bits remain to be done.

What problem does puzzlebox address?

Collaboration and coordination are related but different problems. Collaboration is good for non-trivial yet relatively simple tasks. To tackle long horizon efforts, puzzlebox solves for coordination.

Teams need coordination

Marshalling multiple agents toward a big goal is tougher than just breaking down a request into tasks, assigning them to available agents and enabling collaboration between them.

Just as a few agents can collaborate to complete a small project, several teams of process-aware agents need to operate within distinct project phases to tackle long horizon efforts.

Consider enterprise-level software development processes:

With puzzlebox, members of agentic teams can be made process-aware, but the process itself is not subject to hallucination.

Scenario: Teams passing the torch

Three agents are working. The current state of their shared puzzle is "Specification".

What is a puzzle?

A puzzle is a finite state machine. It's just easier to say, write, and think about.

A stateful thing you can act upon

Imagine the Rubik's Cube puzzle. It has 43 quintillion states, and to transition between them, you act upon it by rotating the intersecting planes of the mechanism.

Properties of a puzzle

A Simple Example

{ "initialState": "LOBBY", "states": { "LOBBY": { "name": "LOBBY", "actions": { "START_GAME": { "name": "START_GAME", "targetState": "PLAYING" } } }, "PLAYING": { "name": "PLAYING", "actions": { "END_GAME": { "name": "END_GAME", "targetState": "GAME_OVER" } } }, "GAME_OVER": { "name": "GAME_OVER", "actions": { "RESTART": { "name": "RESTART", "targetState": "PLAYING" } } } } }

What is puzzlebox?

Most MCP servers have a one-to-one relationship with the client. Puzzlebox is different.

Many clients sharing dynamic resources

Puzzlebox is an MCP Server implementation that:

How It Works

  1. Clients connect to a puzzlebox SSE server.
  2. Clients register puzzles with the server.
  3. Clients can subscribe to a given puzzle to receive updates when its state changes.
  4. Clients perform actions on puzzles that may change their state and available actions.
  5. The puzzlebox server ensures that any attempted action is valid for the current state of the given puzzle.
  6. If an action is valid, a transition to the target state is initiated.
  7. During transition, optional exit and enter guards may send sampling requests to the client, the results of which could lead to cancellation of the transition (think acceptance testing by stakeholders)
  8. If guards pass, the state transition completes.
  9. When a client receives a resource updated notification, they can either read the resource or use the get_puzzle_snapshot tool to get the current state and available actions.
  10. Clients update their UI based on the new state.

MCP Tools

These functions are exposed to the agents for managing puzzles.

⚙️ add_puzzle

Add a new instance of a puzzle (finite state machine).

⚙️ get_puzzle_snapshot

Get a snapshot of a puzzle (its current state and available actions).

⚙️ perform_action_on_puzzle

Perform an action on a puzzle (attempt a state transition).

⚙️ count_puzzles

Get the count of registered puzzles

Local Setup

Running locally requires Node and npm be installed. Then follow these steps...

Install Dependencies

Build

Start

Inspector

Format

Typecheck

Lint

LintFix

Test

Screenshots

These screenshots show the various MCP tools and resources implemented by the sever.

Testing of the server was done with the official reference client - the MCP Inspector.

0 - List Tools

0. list_tools

1 - Add Puzzle

1. add_puzzle

2 - Get Puzzle Snapshot (Initial State)

2. get_puzzle_snapshot

3 - Perform Action On Puzzle

3. perform_action_on_puzzle

4 - Get Puzzle Snapshot (New State)

4. get_puzzle_snapshot

5 - Perform Action On Puzzle

5. perform_action_on_puzzle

6 - Get Puzzle Snapshot (Another New State)

6. get_puzzle_snapshot

7 - List Resources

7. list resources

8 - Resource Template

8. resource_template

9 - Unsubscribed Resource

9. unsubscribed resource

10 - Subscribed Resource

10. unsubscribed resource

11 - Resource Updated Notification

11. subscribed resource updated