get_conversation_messages
Read the messages of a Bluesky direct-message conversation (chat.bsky.convo.getMessages), newest first. Every call is proxied to the Bluesky chat service (did:web:api.bsky.chat) — DMs are not served by the PDS.
This tool is read-only by default: fetching messages does not change the conversation's read state. Set markRead: true to also clear the unread count via chat.bsky.convo.updateRead.
Authentication
Required: Yes (Private tool)
Direct messages additionally require that the app password used for the session was created with "Allow access to your direct messages" enabled (bsky.app → Settings → Privacy and Security → App Passwords). Without it, the chat service rejects every call with 401 "Bad token scope".
Parameters
convoId (required)
- Type:
string - Description: Id of the conversation to read, from
list_conversationsor asend_direct_messageresponse
limit (optional)
- Type:
number - Default:
50 - Constraints: 1-100
- Description: Maximum number of messages to return per page
cursor (optional)
- Type:
string - Description: Pagination cursor from the previous response; omit for the newest page
markRead (optional)
- Type:
boolean - Default:
false - Description: When
true, mark the whole conversation read after fetching (clears itsunreadCountinlist_conversations). Whenfalse(the default), reading is side-effect free.
Response
Tool results are returned as stringified JSON text. The shape below is illustrative.
{
success: boolean;
convoId: string;
messages: Array<{
id?: string;
senderDid?: string; // DID of the sender; match against the conversation members
text?: string; // Absent when the message was deleted
sentAt?: string; // ISO 8601 timestamp
deleted: boolean; // True for deleted messages (id/sender/sentAt are kept)
hasEmbed: boolean; // True when the message embeds a shared post (not expanded)
}>;
cursor?: string; // Absent when there are no older messages
hasMore: boolean;
markedRead: boolean; // Whether this call marked the conversation read
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
Messages are returned newest first; paginate with cursor to walk back in time.
Examples
Read the Latest Messages
{
"convoId": "3kx...abc",
"limit": 30
}2
3
4
Read and Mark the Conversation Read
{
"convoId": "3kx...abc",
"markRead": true
}2
3
4
Get Older Messages
{
"convoId": "3kx...abc",
"cursor": "cursor_from_previous_response"
}2
3
4
Error Handling
Common Errors
Authentication Required
{
"error": "Authentication required",
"code": "AUTHENTICATION_FAILED"
}2
3
4
App Password Without DM Access
A 401 "Bad token scope" from the chat service means the current app password was created without direct-message access. The error message includes guidance to create a new app password with "Allow access to your direct messages" enabled.
Invalid Conversation Id
{
"error": "Invalid parameters: convoId: convoId is required",
"code": "VALIDATION_ERROR"
}2
3
4
Pagination
Pass the cursor from the previous response to fetch older messages, and check hasMore before requesting another page. limit accepts 1-100 (default 50).
Related Tools
- list_conversations - List conversations and find conversation ids
- send_direct_message - Send a direct message