tx

PRD-007: Multi-Interface Integration

CLI, TypeScript API, MCP server, and Agent SDK integration for different consumers

Status: Draft Priority: P0 (Must Have) Owner: TBD Last Updated: 2025-01-28


Problem Statement

Different consumers need different interfaces:

  • Humans want CLI for quick commands
  • Claude Code needs MCP tools
  • Agent SDK needs programmatic API
  • Scripts need JSON output

We need multiple interfaces that all use the same core logic:

  • CLI for human interaction
  • TypeScript API for embedding
  • MCP server for Claude Code
  • JSON mode for scripting

Interface Matrix

InterfaceConsumerProtocolOutput Format
CLI (tx)Humans, scriptsstdin/stdoutText or JSON
TypeScript APICustom agentsFunction callsEffect types
MCP ServerClaude CodeJSON-RPC over stdioMCP format
Agent SDKAnthropic SDKTool definitionsSDK format

CLI Design

Human-Friendly Output (Default)

$ tx ready
3 ready tasks:
  tx-a1b2 [850] Implement JWT validation (unblocks 2)
    blocked by: (none)
    blocks: tx-c3d4, tx-e5f6
  tx-c3d4 [720] Add login endpoint
    blocked by: (none)
    blocks: tx-g7h8
  tx-e5f6 [650] Write auth tests
    blocked by: (none)
    blocks: (none)

JSON Output for Scripts

$ tx ready --json
[
  {
    "id": "tx-a1b2",
    "title": "Implement JWT validation",
    "score": 850,
    "blockedBy": [],
    "blocks": ["tx-c3d4", "tx-e5f6"],
    "isReady": true
  }
]

Pipe-Friendly

$ tx ready --json | jq '.[0].id' | xargs tx show

MCP Tools

Core Tools (Phase 2)

ToolDescriptionAgent Use Case
tx_readyGet ready tasks"What should I work on?"
tx_addCreate taskDecomposing work
tx_doneComplete taskMarking progress
tx_updateUpdate taskChanging status/score
tx_listList tasksUnderstanding scope
tx_showGet task detailsReading requirements
tx_blockAdd dependencyStructuring work order
tx_unblockRemove dependencyAdjusting work order
tx_childrenList child tasksUnderstanding subtask structure
tx_treeShow task subtreeSeeing full decomposition
tx_deleteDelete a taskCleanup

Extended Tools (Phase 3+)

ToolDescriptionAgent Use Case
tx_blockersShow what blocks a taskUnderstanding blockers
tx_blockingShow what task blocksUnderstanding impact
tx_scoreGet/set task scorePrioritization
tx_pathShow ancestors to rootUnderstanding context
tx_dedupeFind duplicate tasksCleanup
tx_compactCompact completed tasksMaintenance

CRITICAL: All tools returning tasks MUST include full dependency info (blockedBy, blocks, children, isReady).

CRITICAL: The MCP server MUST NOT require ANTHROPIC_API_KEY. Core tools (ready, add, done, update, list, show, block, etc.) use AppMinimalLive which has no LLM dependency. Only dedupe/compact tools need the API key and should fail gracefully without it.


Requirements

CLI Requirements

IDRequirementImplementation
I-001All commands support --json flagGlobal option
I-002Exit codes: 0 = success, 1 = error, 2 = not foundConsistent
I-003Consistent argument patternstx <verb> <id> [options]
I-004Help text for all commandstx <command> --help

API Requirements

IDRequirementImplementation
I-005All operations return Effect<T, E>Effect-TS
I-006Errors are typedTagged errors
I-007Composable with Effect Layer systemLayer pattern
I-008Tree-shakeable exportsESM modules

MCP Requirements

IDRequirementImplementation
I-009Tools have clear descriptions for LLMDetailed docs
I-010Input validation with helpful errorsZod schemas
I-011Structured output for parsingJSON responses
I-012Text output for human readabilityFormatted text
I-013All dependency info returnedblockedBy, blocks, children, isReady

Agent SDK Requirements

IDRequirementImplementation
I-014Compatible with @anthropic-ai/claude-agent-sdkTool format
I-015Tools follow SDK naming conventionstx_* prefix
I-016Supports tool confirmation patternsAsync handlers

MCP Tool Schema

All tools that return task data use TaskWithDeps:

const TaskWithDepsSchema = z.object({
  id: z.string(),
  title: z.string(),
  description: z.string(),
  status: z.string(),
  score: z.number(),
  parentId: z.string().nullable(),
  createdAt: z.string(),
  updatedAt: z.string(),
  completedAt: z.string().nullable(),
  blockedBy: z.array(z.string()).describe("Task IDs that block this task"),
  blocks: z.array(z.string()).describe("Task IDs this task blocks"),
  children: z.array(z.string()).describe("Child task IDs"),
  isReady: z.boolean().describe("Whether task can be worked on")
})

Claude Code Configuration

Add to .claude/settings.json:

{
  "mcpServers": {
    "tx": {
      "command": "npx",
      "args": ["tx", "mcp-server"],
      "env": {
        "TX_DB": ".tx/tasks.db"
      }
    }
  }
}

API Examples

TypeScript API

import { Effect } from "effect"
import { TaskService, ReadyService, AppLive } from "tx"

const program = Effect.gen(function* () {
  const taskService = yield* TaskService
  const readyService = yield* ReadyService

  // Create task
  const task = yield* taskService.create({
    title: "Implement feature",
    score: 700
  })

  // Get ready tasks (includes deps)
  const ready = yield* readyService.getReady(5)
  // ready[0].blockedBy, ready[0].blocks, ready[0].isReady

  // Get task with deps
  const full = yield* taskService.getWithDeps(task.id)
  // full.blockedBy, full.blocks, full.children, full.isReady
})

Effect.runPromise(program.pipe(Effect.provide(AppLive)))

MCP Tool Response

MCP tools return content array only (per MCP spec). Structured data is embedded as JSON within the text content:

{
  "content": [
    {
      "type": "text",
      "text": "3 ready task(s):\n- tx-a1b2 [850]: Implement JWT validation\n  blocked by: (none)\n  blocks: tx-c3d4, tx-e5f6"
    },
    {
      "type": "text",
      "text": "{\"tasks\":[{\"id\":\"tx-a1b2\",\"title\":\"Implement JWT validation\",\"score\":850,\"blockedBy\":[],\"blocks\":[\"tx-c3d4\",\"tx-e5f6\"],\"children\":[],\"isReady\":true}]}"
    }
  ]
}

Note: structuredContent is NOT part of the MCP specification. Data is returned as a second text content block containing JSON for programmatic parsing, plus a human-readable first block.


Exit Codes

CodeMeaningExample
0Successtx done tx-123
1Error (validation, runtime)Invalid input
2Not foundtx show tx-nonexistent

Initialization (tx init)

The tx init command creates the project workspace:

$ tx init
Initialized tx database at .tx/tasks.db

What tx init Does

  1. Creates .tx/ directory
  2. Creates tasks.db SQLite database with WAL mode enabled
  3. Runs all migrations (creates tables, indexes)
  4. Creates .tx/.gitignore (ignores tasks.db by default)
  5. Optionally creates .tx/config.json for project-specific settings

Idempotency

Running tx init on an existing project is safe — migrations are versioned and skip already-applied steps.


On this page