bluesky_thread
Fetch the full conversation around any Bluesky post: see parent posts above and reply tree below. Understand the context before replying. Free, no credentials needed for public threads.
Instructions
Fetch the full conversation around a Bluesky post: parent posts above, reply tree below. Use this before bluesky_reply to understand the conversation. FREE. No credentials required for public threads. Returns: { thread: { post, parent?, replies?: thread[] } }. Common errors: post URI not found (VALIDATION_ERROR), AppView 5xx (PLATFORM_ERROR).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| uri | Yes | AT-URI of the post to fetch context for (e.g. at://did:plc:.../app.bsky.feed.post/xyz). | |
| depth | No | How many reply levels below to include (default 6). | |
| parent_height | No | How many parent levels above to include (default 80). |
Implementation Reference
- src/index.ts:278-282 (registration)Registration of the 'bluesky_thread' tool on the MCP server, with description and invocation of handleBlueskyThread.
server.tool("bluesky_thread", "Fetch the full conversation around a Bluesky post: parent posts above, reply tree below. Use this before bluesky_reply to understand the conversation. FREE. No credentials required for public threads. Returns: { thread: { post, parent?, replies?: thread[] } }. Common errors: post URI not found (VALIDATION_ERROR), AppView 5xx (PLATFORM_ERROR).", blueskyThreadSchema.shape, async (input) => { const parsed = blueskyThreadSchema.parse(input); const result = await handleBlueskyThread(parsed); return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }; }); - src/tools/broadcast-tools.ts:299-304 (schema)Zod schema for bluesky_thread input: uri (AT-URI string), optional depth (0-1000, default 6), optional parent_height (0-1000, default 80).
/** Zod schema for the `bluesky_thread` tool input. */ export const blueskyThreadSchema = z.object({ uri: z.string().describe("AT-URI of the post to fetch context for (e.g. at://did:plc:.../app.bsky.feed.post/xyz)."), depth: z.number().int().min(0).max(1000).optional().describe("How many reply levels below to include (default 6)."), parent_height: z.number().int().min(0).max(1000).optional().describe("How many parent levels above to include (default 80)."), }); - src/tools/broadcast-tools.ts:306-317 (handler)Handler function handleBlueskyThread that validates input via schema and delegates to getBlueskyThread in the broadcast layer.
/** * Fetch the full conversation around a post so a reply can be drafted in * context. Unauthenticated. */ export async function handleBlueskyThread( input: z.infer<typeof blueskyThreadSchema> ) { return getBlueskyThread(input.uri, { depth: input.depth, parentHeight: input.parent_height, }); } - src/broadcast/bluesky.ts:575-609 (helper)Core implementation getBlueskyThread: makes an unauthenticated GET request to the Bluesky AppView's getPostThread XRPC endpoint, normalizes the response.
export async function getBlueskyThread( uri: string, options?: { depth?: number; parentHeight?: number } ): Promise<ToolResult<BlueskyThread>> { if (!uri.startsWith("at://")) { return makeError("VALIDATION_ERROR", `Expected an at-uri, got: ${uri}`); } const depth = options?.depth ?? 6; const parentHeight = options?.parentHeight ?? 80; const params = new URLSearchParams(); params.set("uri", uri); params.set("depth", String(depth)); params.set("parentHeight", String(parentHeight)); const result = await httpRequest( `${PUBLIC_APPVIEW}/xrpc/app.bsky.feed.getPostThread?${params.toString()}`, { method: "GET" } ); if (!result.success) { return makeError(result.error.code, result.error.message, { platform: "bluesky", retryable: result.error.retryable, }); } const data = result.data as { thread?: unknown }; const normalized = normalizeThreadNode(data.thread); if (!normalized) { return makeError("NOT_FOUND", `Thread not found or unviewable: ${uri}`, { platform: "bluesky", }); } return makeSuccess(normalized); } - src/broadcast/bluesky.ts:71-84 (helper)Type definitions: BlueskyThreadPost (uri, cid, author, text, indexedAt, url) and BlueskyThread (post, parent?, replies[]) used by the tool.
export interface BlueskyThreadPost { uri: string; cid: string; author: { did: string; handle: string; displayName?: string }; text: string; indexedAt: string; url: string; } export interface BlueskyThread { post: BlueskyThreadPost; parent?: BlueskyThread; replies: BlueskyThread[]; }