{"id":"96da0194-ee83-41d4-b6ad-7c6469893673","slug":"sortie","kind":"mcp","name":"sortie","summary":"Semantic execution debugger for Solana. Reconstructs CPI trees, decodes failures (0x1771 → 'slippage exceeded'), profiles compute. MCP server for AI agents.","owner":"srivtx","repoUrl":"https://github.com/srivtx/sortie","license":"MIT","licenseTier":"permissive","trust":"community","stars":0,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-06-20T00:03:17.000Z","addedAt":"2026-10-21T04:43:03.687Z","logoUrl":"https://avatars.githubusercontent.com/u/78023279?u=45dcff9fd7867f9030cb52ea4451156d512a5c6b&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["cloud-infra","developer-tools","memory-knowledge"],"tags":["claude-code","debugging","devtools","geyser","indexer","solana","solana-ai","solana-indexer"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-23T04:05:09.865Z","sample":false,"url":"https://conduits.dev/tools/sortie","language":"TypeScript","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"<div align=\"center\">\n\n<a href=\"./public/logo.svg\"><img src=\"./public/logo.svg\" width=\"120\" alt=\"SORTIE\" /></a>\n\n# SORTIE\n\n**Semantic execution debugger for Solana transactions.**\n\nDecode failures (`0x1771` → \"slippage tolerance exceeded\"). Trace CPI trees. Profile\ncompute. Let AI agents inspect transactions through MCP.\n\n[![Live](https://img.shields.io/badge/demo-sortie--six.vercel.app-blue)](https://sortie.srivtx.xyz)\n[![Version](https://img.shields.io/badge/version-0.1.0-blue)](./CHANGELOG.md)\n[![License MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE)\n[![Solana](https://img.shields.io/badge/Solana-9945ff?logo=solana&logoColor=white)](https://solana.com)\n[![Next.js](https://img.shields.io/badge/Next.js-14-black?logo=next.js)](https://nextjs.org)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5-3178c6?logo=typescript&logoColor=white)](https://www.typescriptlang.org)\n\n[Live demo](https://sortie-six.vercel.app) · [Report bug](https://github.com/srivtx/sortie/issues) · [Request feature](https://github.com/srivtx/sortie/issues)\n\n</div>\n\n---\n\n## What it does\n\nWhen a Solana transaction fails on mainnet, the raw error is useless:\n`InstructionE...: custom program error: 0x1771`. SORTIE does the work you\nshouldn't have to:\n\n1. **Decodes the error** — maps the program ID + instruction index + error\n   code to a human-readable string. \"Slippage tolerance exceeded on output\n   token.\" Covers 12+ protocols (Jupiter, Raydium, Orca, Drift, Meteora,\n   Kamino, Mango, Marinade, Sanctum, SPL Token, System, Associated Token).\n2. **Reconstructs the CPI tree** — the full call stack with parent/child\n   relationships. Failed branches highlighted. Per-instruction status, compute,\n   error. Drag to explore.\n3. **Profiles compute** — per-step CU breakdown. Hot spots, by-program totals,\n   optimization hints when something eats >80% of the budget.\n4. **Streams live failures** — recent failed transactions on mainnet,\n   sampled from a public RPC. Refreshes every 15s. Click any to debug.\n5. **Exposes it to AI agents via MCP** — JSON-RPC 2.0 endpoint at\n   `/api/mcp`. Four tools: `explain_failure`, `analyze_transaction`,\n   `list_protocols`, `get_recent_failures`. Works with Claude Code, Codex,\n   any MCP-compatible client.\n\n## Quick start\n\n```bash\ngit clone https://github.com/srivtx/sortie.git\ncd sortie\nnpm install\nnpm run dev\n# → http://localhost:3000\n```\n\nOpen `http://localhost:3000` for the live failure feed. Paste any Solana\ntransaction signature (or click one in the feed) to debug it.\n\n## MCP setup\n\nThe MCP endpoint is at `http://localhost:3000/api/mcp`. Configure your AI\nagent:\n\n```json\n{\n  \"mcpServers\": {\n    \"sortie\": {\n      \"url\": \"http://localhost:3000/api/mcp\",\n      \"transport\": \"http\"\n    }\n  }\n}\n```\n\nFour tools:\n\n| Tool | What it does |\n|---|---|\n| `explain_failure` | Decode a transaction error: program, instruction, error code, likely cause |\n| `analyze_transaction` | Full analysis: CPI tree, compute profile, step-by-step timeline |\n| `list_protocols` | List all supported protocols and their decoders |\n| `get_recent_failures` | Recent failures across the network (filter by program) |\n\nA live playground is at `/mcp-demo` — try each tool from your browser.\n\n## Architecture\n\n```\nsortie/\n├── app/\n│   ├── page.tsx                    # live failure feed (home)\n│   ├── tx/[signature]/page.tsx     # transaction detail (5 tabs: timeline / tree / profile / logs / raw)\n│   ├── mcp-demo/page.tsx           # MCP playground\n│   └── api/\n│       ├── mcp/route.ts            # MCP JSON-RPC 2.0 server\n│       ├── recent-failures/        # live failure sampler\n│       └── transaction/[signature]/ # transaction fetcher\n├── components/                     # reusable UI primitives\n│   ├── CpiFlow.tsx                 # React Flow CPI tree\n│   ├── ExecutionTimeline.tsx       # step-by-step walk\n│   ├── ComputeProfiler.tsx         # CU breakdown + hot spots\n│   ├── FailureAnalysis.tsx         # auto-categorized errors\n│   ├── RecentFailures.tsx          # live feed component\n│   ├── CopyButton.tsx              # one-click clipboard\n│   └── ThemeToggle.tsx             # light/dark\n├── lib/\n│   ├── ir/                         # intermediate representation\n│   │   ├── types.ts                # ExecutionStep, Action, etc.\n│   │   └── builder.ts              # parse raw tx → IR\n│   └── parser/                     # Solana-specific parsers\n│       ├── transaction.ts          # main entry\n│       ├── instructions.ts         # instruction decoding\n│       ├── errors.ts               # error code → human readable\n│       ├── logs.ts                 # program log parsing\n│       ├── balances.ts             # balance change extraction\n│       └── protocols/              # per-program decoders\n├── public/                         # logo, favicon\n└── tailwind.config.ts              # design tokens\n```\n\n### Data flow\n\n```\nPublic RPC → Solana transaction\n  ↓\nlib/parser/transaction.ts\n  ↓\nIntermediate Representation (IR): tree of ExecutionSteps\n  ↓\nComponents render the IR:\n  CpiFlow         → the call tree\n  ExecutionTimeline → chronological steps\n  ComputeProfiler → CU breakdown\n  FailureAnalysis → error categorization\n```\n\nThe IR is the key abstraction. Add a new program decoder → it\nautomatically works in every view (live feed, timeline, CPI tree,\nfailure decoder).\n\n## Adding a new program decoder\n\n```ts\n// lib/parser/protocols/my-program.ts\nimport { ProtocolDecoder } from './types';\n\nexport const myProgram: ProtocolDecoder = {\n  programId: 'MyProgram11111111111111111111111111111111',\n  decodeError: (code: number) => {\n    const errors: Record<number, string> = {\n      0: 'Success',\n      1: 'Insufficient liquidity',\n      2: 'Slippage exceeded',\n    };\n    return errors[code] ?? `Unknown error: 0x${code.toString(16)}`;\n  },\n  decodeInstruction: (data: Buffer) => ({\n    type: 'swap',\n    params: { /* parsed fields */ },\n  }),\n};\n```\n\nRegister it in `lib/parser/protocols/index.ts`. It shows up in the live\nfeed, the failure decoder, the timeline, and the MCP tool responses —\neverywhere.\n\n## Tech stack\n\n- **Framework:** Next.js 14 (App Router)\n- **UI:** React 18, TypeScript 5 (strict mode)\n- **Styling:** Tailwind CSS 3 with custom design tokens (CSS variables for\n  light/dark theming)\n- **Visualization:** React Flow (CPI tree)\n- **Icons:** Lucide React\n- **Data:** Public Solana RPC (no API key required for read-only calls)\n- **MCP:** Hand-rolled JSON-RPC 2.0 server (no SDK — small surface, full\n  control)\n\n## Supported programs\n\n- **Jupiter** — aggregator, slippage errors\n- **Raydium** — AMM, pool errors\n- **Orca** — AMM (Whirlpools)\n- **SPL Token** — token program, transfer errors\n- **System Program** — account creation, transfers\n- **Associated Token** — ATA derivation\n- **Marinade** — liquid staking\n- **Mango** — perp dex\n- **Meteora** — DLMM\n- **Drift** — perpetuals\n- **Kamino** — lending\n- **Sanctum** — LSTs\n\nOpen an issue or PR to add more. See\n[`CONTRIBUTING.md`](./CONTRIBUTING.md) for the protocol-decoder spec.\n\n## Development\n\n```bash\nnpm install        # install deps\nnpm run dev        # dev server\nnpm run build      # production build\nnpm start          # serve production build\nnpm run lint       # next lint\nnpx tsc --noEmit   # type-check\n```\n\n### Conventions\n\n- **TypeScript strict** — `\"strict\": true` in `tsconfig.json`. No `any`\n  in committed code.\n- **Server components by default** — only `'use client'` when you need\n  state, effects, or browser APIs.\n- **Design tokens via CSS variables** — colors in `:root` in\n  `app/globals.css`, exposed via `tailwind.config.ts`. Theme switching\n  works without re-renders.\n- **No external state library** — local state, URL state, server state\n  via fetch. Add Zustand/Redux only if you actually need it.\n- **Public RPC by default** — no API key needed for read-only calls.\n  For production, switch to Helius/QuickNode.\n\n## Deployment\n\nDeploys to Vercel with zero config:\n\n```bash\nvercel\n```\n\nOr any Next.js-compatible host. The MCP endpoint is a standard Next.js\nAPI route — works on Vercel, Netlify, Cloudflare Pages, your own Node\nserver.\n\n**Environment variables:** none required for the public RPC. If you\nwant a private RPC:\n\n```bash\n# .env.local\nSOLANA_RPC_URL=https://mainnet.helius-rpc.com/?api-key=YOUR_KEY\n```\n\nThen update `lib/parser/transaction.ts` to use it.\n\n## Performance\n\n- Transaction parsing: < 50ms for typical transactions (10-20 instructions)\n- CPI tree render: < 100ms for trees up to ~100 nodes\n- Live failure feed: 15s refresh interval, 4 RPC calls/min (well under\n  public RPC limits)\n- MCP server: stateless, ~2s for a full `analyze_transaction` call\n\n## Contributing\n\nSee [`CONTRIBUTING.md`](./CONTRIBUTING.md) for the full guide on adding\nprogram decoders, reporting issues, and the PR process.\n\n## License\n\n[MIT](./LICENSE) — Copyright (c) 2026 [srivtx](https://github.com/srivtx)\n\n## Acknowledgments\n\n- [Solana](https://solana.com) — the chain\n- [React Flow](https://reactflow.dev) — the tree visualization\n- [Anza](https://anza.xyz) (formerly Solana Labs) — the RPC and tooling\n- [Helius](https://helius.xyz) — reference docs and transaction parsing\n  examples\n- The Solana developer community — bug reports, feedback, and protocols\n  to decode\n\n## Contact\n\n- GitHub: [@srivtx](https://github.com/srivtx)\n- Issues: [github.com/srivtx/sortie/issues](https://github.com/srivtx/sortie/issues)\n- Live demo: [sortie-six.vercel.app](https://sortie-six.vercel.app)\n\n---\n\n<sub>Built for the [Superteam Earn](https://superteam.fun) \"Ship useful\nagent skills\" bounty. Released under MIT.</sub>\n"}