Skip to content

Toolcraft: add lifecycle-aware typed streaming commands #508

Description

@kamilio

Summary

Toolcraft commands currently model one finite request/response operation. progress() can emit diagnostics while a handler runs, but there is no typed, lifecycle-aware way for a command to produce an ongoing sequence of values across the CLI, SDK, and MCP surfaces.

This blocks integrations that need realtime watches or subscriptions from using the shared Toolcraft command tree.

Tested against toolcraft@0.0.102.

Use case

A device integration needs to subscribe to state changes and keep emitting typed events until the caller cancels or disconnects. Keeping this outside Toolcraft duplicates CLI signal handling, SDK cancellation, MCP lifecycle handling, schemas, and cleanup logic.

Proposed direction

Add a streaming command primitive, or allow a command handler to return a typed AsyncIterable/stream declaration with an event schema.

The surface should define:

  • cancellation through an AbortSignal or equivalent;
  • deterministic cleanup when an SDK consumer stops iteration, a CLI receives SIGINT, or an MCP client disconnects;
  • bounded buffering and backpressure behavior;
  • a schema for each emitted event;
  • progress/reconnect/status events without conflating them with data events;
  • error and terminal-event semantics;
  • secret/credential refresh hooks for long-running sessions.

Expected surface behavior

  • SDK: return an async iterable with cancellation and cleanup.
  • CLI: render events until interrupted, with an NDJSON-compatible mode.
  • MCP: use an explicit subscription/notification lifecycle rather than holding a normal tool response open indefinitely.

Acceptance criteria

  1. One command definition can expose a typed stream to supported surfaces.
  2. Cancellation releases handler resources exactly once.
  3. Slow consumers cannot create unbounded memory growth.
  4. Event schemas are available to adapters and tests.
  5. The testing harness can drive, cancel, and assert a finite prefix of a stream.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions