( mcp: McpServer, server: ReactotronServer, commandBuffer: Command[], serverRedactionConfig: McpRedactionServerConfig )
| 84 | } |
| 85 | |
| 86 | export function registerResources( |
| 87 | mcp: McpServer, |
| 88 | server: ReactotronServer, |
| 89 | commandBuffer: Command[], |
| 90 | serverRedactionConfig: McpRedactionServerConfig |
| 91 | ) { |
| 92 | mcp.registerResource("timeline", "reactotron://timeline", { |
| 93 | description: "Read this first to understand what's happening in the app. Returns summarized debug events (type, timestamp, and a short preview) newest-first. Payloads are stripped to keep the response small. Use the timeline_by_type resource template to get full event data filtered by type (e.g. reactotron://timeline/api.response).", |
| 94 | mimeType: "application/json", |
| 95 | }, async (uri) => { |
| 96 | const redactor = createRedactor(server, serverRedactionConfig) |
| 97 | const meta = connectionMeta(server) |
| 98 | const events = filterByClient(commandBuffer, server) |
| 99 | const summarized = [...events].reverse().map((cmd) => |
| 100 | redactor.redact(summarizeCommand(cmd), cmd.clientId) |
| 101 | ) |
| 102 | return json(uri, { _meta: meta, eventCount: events.length, events: summarized }, |
| 103 | "Events are summarized. Use the timeline_by_type resource (e.g. reactotron://timeline/api.response) to get full payloads for a specific event type.") |
| 104 | }) |
| 105 | |
| 106 | mcp.registerResource("timeline_by_type", |
| 107 | new ResourceTemplate("reactotron://timeline/{type}", { |
| 108 | list: async () => { |
| 109 | const types = [...new Set(commandBuffer.map((c) => c.type))] |
| 110 | return { |
| 111 | resources: types.map((t) => ({ |
| 112 | uri: `reactotron://timeline/${t}`, |
| 113 | name: `timeline:${t}`, |
| 114 | })), |
| 115 | } |
| 116 | }, |
| 117 | complete: { |
| 118 | type: async (value) => { |
| 119 | const types = [...new Set(commandBuffer.map((c) => c.type))] |
| 120 | return types.filter((t) => t.startsWith(value)) |
| 121 | }, |
| 122 | }, |
| 123 | }), |
| 124 | { |
| 125 | description: "Timeline events filtered by command type, with full payloads. Available types depend on what the app has sent (e.g. api.response, log, state.values.response, benchmark.report). Read the timeline resource first to see which types are present.", |
| 126 | mimeType: "application/json", |
| 127 | }, |
| 128 | async (uri, { type }) => { |
| 129 | const redactor = createRedactor(server, serverRedactionConfig) |
| 130 | const meta = connectionMeta(server) |
| 131 | const events = filterByClient(commandBuffer, server) |
| 132 | .filter((c) => c.type === type) |
| 133 | const redactedEvents = [...events].reverse().map((cmd) => |
| 134 | redactor.redact(cmd, cmd.clientId) |
| 135 | ) |
| 136 | return json(uri, { _meta: meta, type, eventCount: events.length, events: redactedEvents }, |
| 137 | `Too many ${type} events to return in full. Try clear_timeline to reset, then reproduce the issue to capture fewer events.`) |
| 138 | } |
| 139 | ) |
| 140 | |
| 141 | mcp.registerResource("state", "reactotron://state/current", { |
| 142 | description: "Latest cached Redux/MST state snapshot. May be stale — use the request_state tool for a fresh snapshot. Returns no_state_received if the app hasn't sent state yet.", |
| 143 | mimeType: "application/json", |
no test coverage detected