read
Retrieve recent messages from the most recent OpenCode session on a specified instance. Use this to review conversation history without sending a new message.
Instructions
Read the last few messages from the most recent opencode session on an instance. Use this to see what has been happening without sending a new message.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| instance | Yes | Instance name (exact or fuzzy substring match) | |
| message_limit | No | Max number of messages to retrieve (default 10) |
Implementation Reference
- src/tools/simplified.ts:354-368 (registration)Registration of the 'read' tool with its name, description, and Zod schema for parameters (instance and message_limit). Registered via server.tool().
server.tool( 'read', 'Read the last few messages from the most recent opencode session on an instance. Use this to see what has been happening without sending a new message.', { instance: z .string() .describe('Instance name (exact or fuzzy substring match)'), message_limit: z .number() .optional() .default(10) .describe( 'Max number of messages to retrieve (default 10)', ), }, - src/tools/simplified.ts:369-474 (handler)Handler function for the 'read' tool. Resolves the instance, finds the most recent session, fetches messages via GET /session/{id}/message?limit={limit}, formats them (role, time, text parts, tool parts), and returns the formatted text.
async ({ instance: query, message_limit }) => { try { const { instance } = registry.resolveInstance(query) const baseUrl = instance.url // Find the most recently updated session const session = await findMostRecentSession(baseUrl) if (!session) { return { content: [ { type: 'text', text: `No sessions found on ${instance.name}.`, }, ], } } // Fetch recent messages const msgRes = await fetch( `${baseUrl}/session/${session.id}/message?limit=${message_limit}`, ) if (!msgRes.ok) { return { content: [ { type: 'text', text: `Failed to fetch messages from ${instance.name}.`, }, ], isError: true, } } const messages = (await msgRes.json()) as Array<{ info: { role: string time: { created: number } } parts: Array<{ type: string text?: string tool?: string state?: { status: string } }> }> if (messages.length === 0) { return { content: [ { type: 'text', text: `Session "${session.title ?? '(untitled)'}" on ${instance.name} has no messages.`, }, ], } } // Check status const { busySessionId } = await getInstanceStatus(baseUrl) const status = busySessionId === session.id ? 'busy' : 'idle' const lines = [ `**${instance.name}** — "${session.title ?? '(untitled)'}" (${status})`, '', ] for (const msg of messages) { const role = msg.info.role === 'user' ? 'User' : 'Assistant' const time = new Date( msg.info.time.created, ).toLocaleTimeString() const textParts = msg.parts .filter((p) => p.type === 'text' && p.text) .map((p) => p.text!) .join('\n') const toolParts = msg.parts .filter((p) => p.type === 'tool') .map( (p) => ` [tool: ${p.tool} → ${p.state?.status ?? '?'}]`, ) lines.push(`**${role}** (${time}):`) if (textParts) lines.push(textParts) if (toolParts.length > 0) lines.push(toolParts.join('\n')) lines.push('') } return { content: [{ type: 'text', text: lines.join('\n') }], } } catch (err) { return { content: [ { type: 'text', text: `Error: ${(err as Error).message}` }, ], isError: true, } } }, ) - src/tools/simplified.ts:357-368 (schema)Zod schema defining inputs for the 'read' tool: 'instance' (required string) and 'message_limit' (optional number, default 10).
{ instance: z .string() .describe('Instance name (exact or fuzzy substring match)'), message_limit: z .number() .optional() .default(10) .describe( 'Max number of messages to retrieve (default 10)', ), }, - src/tools/simplified.ts:90-103 (helper)Helper function findMostRecentSession() used by the 'read' tool to locate the most recently updated session on an instance before fetching messages.
async function findMostRecentSession( baseUrl: string, ): Promise<SessionInfo | undefined> { try { const res = await fetch(`${baseUrl}/session`) if (!res.ok) return undefined const sessions = (await res.json()) as SessionInfo[] if (sessions.length === 0) return undefined sessions.sort((a, b) => b.time.updated - a.time.updated) return sessions[0] } catch { return undefined } }