Skip to content

Commit 540c168

Browse files
feat(api): manual updates
1 parent 1434ac7 commit 540c168

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+5444
-87
lines changed

.stats.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 1
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-8c712fe19f280b0b89ecc8a3ce61e9f6b165cee97ce33f66c66a7a5db339c755.yml
3-
openapi_spec_hash: 1ea71129cc1a1ccc3dc8a99566082311
1+
configured_endpoints: 14
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper%2Fbeeper-desktop-api-9f5190d7df873112f3512b5796cd95341f0fa0d2585488d3e829be80ee6045ce.yml
3+
openapi_spec_hash: ba834200758376aaea47b2a276f64c1b
44
config_hash: f83b2b6eb86f2dd68101065998479cb2

README.md

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ const client = new BeeperDesktop({
2424
accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted
2525
});
2626

27-
const userInfo = await client.token.info();
27+
const page = await client.chats.search({ includeMuted: true, limit: 3, type: 'single' });
28+
const chat = page.items[0];
2829

29-
console.log(userInfo.sub);
30+
console.log(chat.id);
3031
```
3132

3233
### Request & Response types
@@ -41,7 +42,7 @@ const client = new BeeperDesktop({
4142
accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted
4243
});
4344

44-
const userInfo: BeeperDesktop.UserInfo = await client.token.info();
45+
const accounts: BeeperDesktop.AccountListResponse = await client.accounts.list();
4546
```
4647

4748
Documentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.
@@ -54,15 +55,17 @@ a subclass of `APIError` will be thrown:
5455

5556
<!-- prettier-ignore -->
5657
```ts
57-
const userInfo = await client.token.info().catch(async (err) => {
58-
if (err instanceof BeeperDesktop.APIError) {
59-
console.log(err.status); // 400
60-
console.log(err.name); // BadRequestError
61-
console.log(err.headers); // {server: 'nginx', ...}
62-
} else {
63-
throw err;
64-
}
65-
});
58+
const response = await client.messages
59+
.send({ chatID: '1229391', text: 'Hello! Just checking in on the project status.' })
60+
.catch(async (err) => {
61+
if (err instanceof BeeperDesktop.APIError) {
62+
console.log(err.status); // 400
63+
console.log(err.name); // BadRequestError
64+
console.log(err.headers); // {server: 'nginx', ...}
65+
} else {
66+
throw err;
67+
}
68+
});
6669
```
6770

6871
Error codes are as follows:
@@ -94,7 +97,7 @@ const client = new BeeperDesktop({
9497
});
9598

9699
// Or, configure per-request:
97-
await client.token.info({
100+
await client.accounts.list({
98101
maxRetries: 5,
99102
});
100103
```
@@ -111,7 +114,7 @@ const client = new BeeperDesktop({
111114
});
112115

113116
// Override per-request:
114-
await client.token.info({
117+
await client.accounts.list({
115118
timeout: 5 * 1000,
116119
});
117120
```
@@ -120,6 +123,45 @@ On timeout, an `APIConnectionTimeoutError` is thrown.
120123

121124
Note that requests which time out will be [retried twice by default](#retries).
122125

126+
## Auto-pagination
127+
128+
List methods in the BeeperDesktop API are paginated.
129+
You can use the `for await … of` syntax to iterate through items across all pages:
130+
131+
```ts
132+
async function fetchAllMessages(params) {
133+
const allMessages = [];
134+
// Automatically fetches more pages as needed.
135+
for await (const message of client.messages.search({
136+
accountIDs: ['local-telegram_ba_QFrb5lrLPhO3OT5MFBeTWv0x4BI'],
137+
limit: 10,
138+
query: 'deployment',
139+
})) {
140+
allMessages.push(message);
141+
}
142+
return allMessages;
143+
}
144+
```
145+
146+
Alternatively, you can request a single page at a time:
147+
148+
```ts
149+
let page = await client.messages.search({
150+
accountIDs: ['local-telegram_ba_QFrb5lrLPhO3OT5MFBeTWv0x4BI'],
151+
limit: 10,
152+
query: 'deployment',
153+
});
154+
for (const message of page.items) {
155+
console.log(message);
156+
}
157+
158+
// Convenience methods are provided for manually paginating:
159+
while (page.hasNextPage()) {
160+
page = await page.getNextPage();
161+
// ...
162+
}
163+
```
164+
123165
## Advanced Usage
124166

125167
### Accessing raw Response data (e.g., headers)
@@ -134,13 +176,13 @@ Unlike `.asResponse()` this method consumes the body, returning once it is parse
134176
```ts
135177
const client = new BeeperDesktop();
136178

137-
const response = await client.token.info().asResponse();
179+
const response = await client.accounts.list().asResponse();
138180
console.log(response.headers.get('X-My-Header'));
139181
console.log(response.statusText); // access the underlying Response object
140182

141-
const { data: userInfo, response: raw } = await client.token.info().withResponse();
183+
const { data: accounts, response: raw } = await client.accounts.list().withResponse();
142184
console.log(raw.headers.get('X-My-Header'));
143-
console.log(userInfo.sub);
185+
console.log(accounts);
144186
```
145187

146188
### Logging
@@ -220,7 +262,7 @@ parameter. This library doesn't validate at runtime that the request matches the
220262
send will be sent as-is.
221263

222264
```ts
223-
client.token.info({
265+
client.chats.search({
224266
// ...
225267
// @ts-expect-error baz is not yet public
226268
baz: 'undocumented option',

api.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# BeeperDesktop
22

3+
Types:
4+
5+
- <code><a href="./src/resources/top-level.ts">DownloadAssetResponse</a></code>
6+
- <code><a href="./src/resources/top-level.ts">OpenResponse</a></code>
7+
- <code><a href="./src/resources/top-level.ts">SearchResponse</a></code>
8+
9+
Methods:
10+
11+
- <code title="post /v1/app/download-asset">client.<a href="./src/index.ts">downloadAsset</a>({ ...params }) -> DownloadAssetResponse</code>
12+
- <code title="post /v1/app/open">client.<a href="./src/index.ts">open</a>({ ...params }) -> OpenResponse</code>
13+
- <code title="get /v1/search">client.<a href="./src/index.ts">search</a>({ ...params }) -> SearchResponse</code>
14+
315
# Shared
416

517
Types:
@@ -16,19 +28,54 @@ Types:
1628
Types:
1729

1830
- <code><a href="./src/resources/accounts.ts">Account</a></code>
31+
- <code><a href="./src/resources/accounts.ts">AccountListResponse</a></code>
32+
33+
Methods:
34+
35+
- <code title="get /v1/accounts">client.accounts.<a href="./src/resources/accounts.ts">list</a>() -> AccountListResponse</code>
1936

2037
# Contacts
2138

39+
Types:
40+
41+
- <code><a href="./src/resources/contacts.ts">ContactSearchResponse</a></code>
42+
43+
Methods:
44+
45+
- <code title="get /v1/contacts/search">client.contacts.<a href="./src/resources/contacts.ts">search</a>({ ...params }) -> ContactSearchResponse</code>
46+
2247
# Chats
2348

2449
Types:
2550

2651
- <code><a href="./src/resources/chats/chats.ts">Chat</a></code>
52+
- <code><a href="./src/resources/chats/chats.ts">ChatCreateResponse</a></code>
53+
54+
Methods:
55+
56+
- <code title="post /v1/chats">client.chats.<a href="./src/resources/chats/chats.ts">create</a>({ ...params }) -> ChatCreateResponse</code>
57+
- <code title="get /v1/chats/{chatID}">client.chats.<a href="./src/resources/chats/chats.ts">retrieve</a>(chatID, { ...params }) -> Chat</code>
58+
- <code title="post /v1/chats/{chatID}/archive">client.chats.<a href="./src/resources/chats/chats.ts">archive</a>(chatID, { ...params }) -> BaseResponse</code>
59+
- <code title="get /v1/chats/search">client.chats.<a href="./src/resources/chats/chats.ts">search</a>({ ...params }) -> ChatsCursor</code>
2760

2861
## Reminders
2962

63+
Methods:
64+
65+
- <code title="post /v1/chats/{chatID}/reminders">client.chats.reminders.<a href="./src/resources/chats/reminders.ts">create</a>(chatID, { ...params }) -> BaseResponse</code>
66+
- <code title="delete /v1/chats/{chatID}/reminders">client.chats.reminders.<a href="./src/resources/chats/reminders.ts">delete</a>(chatID) -> BaseResponse</code>
67+
3068
# Messages
3169

70+
Types:
71+
72+
- <code><a href="./src/resources/messages.ts">MessageSendResponse</a></code>
73+
74+
Methods:
75+
76+
- <code title="get /v1/messages/search">client.messages.<a href="./src/resources/messages.ts">search</a>({ ...params }) -> MessagesCursor</code>
77+
- <code title="post /v1/messages">client.messages.<a href="./src/resources/messages.ts">send</a>({ ...params }) -> MessageSendResponse</code>
78+
3279
# Token
3380

3481
Types:

packages/mcp-server/README.md

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ You can filter by multiple aspects:
5959
- `--tool` includes a specific tool by name
6060
- `--resource` includes all tools under a specific resource, and can have wildcards, e.g. `my.resource*`
6161
- `--operation` includes just read (get/list) or just write operations
62+
- `--tag` includes a set of endpoints with custom tags provided
6263

6364
### Dynamic tools
6465

@@ -179,7 +180,7 @@ http://localhost:3000?client=cursor&capability=tool-name-length%3D40
179180
import { server, endpoints, init } from "@beeper/desktop-api-mcp/server";
180181

181182
// import a specific tool
182-
import infoToken from "@beeper/desktop-api-mcp/tools/token/info-token";
183+
import downloadAssetClient from "@beeper/desktop-api-mcp/tools/top-level/download-asset-client";
183184

184185
// initialize the server and all endpoints
185186
init({ server, endpoints });
@@ -204,13 +205,56 @@ const myCustomEndpoint = {
204205
};
205206

206207
// initialize the server with your custom endpoints
207-
init({ server: myServer, endpoints: [infoToken, myCustomEndpoint] });
208+
init({ server: myServer, endpoints: [downloadAssetClient, myCustomEndpoint] });
208209
```
209210

210211
## Available Tools
211212

212213
The following tools are available in this MCP server.
213214

215+
### Resource `$client`:
216+
217+
- `download_asset_client` (`write`): Download a Matrix asset using its mxc:// or localmxc:// URL and return the local file URL.
218+
- `open_in_app` (`write`) tags: [app]: Open Beeper Desktop and optionally navigate to a specific chat, message, or pre-fill draft text and attachment.
219+
- `search` (`read`) tags: [app]: Search for chats, participant name matches in groups, and the first page of messages in one call. Use this when the user asks for a specific chat, group, or person.
220+
221+
### Resource `accounts`:
222+
223+
- `get_accounts` (`read`) tags: [accounts]: List connected accounts on this device. Use to pick account context.
224+
225+
### Resource `contacts`:
226+
227+
- `search_contacts` (`read`): Search contacts across on a specific account using the network's search API. Only use for creating new chats.
228+
229+
### Resource `chats`:
230+
231+
- `create_chats` (`write`): Create a single or group chat on a specific account using participant IDs and optional title.
232+
- `get_chat` (`read`) tags: [chats]: Get chat details: metadata, participants (limited), last activity.
233+
- `archive_chat` (`write`) tags: [chats]: Archive or unarchive a chat.
234+
- `search_chats` (`read`) tags: [chats]: Search chats by title/network or participants using Beeper Desktop's renderer algorithm. Optional 'scope'.
235+
236+
### Resource `chats.reminders`:
237+
238+
- `set_chat_reminder` (`write`) tags: [chats]: Set a reminder for a chat at a specific time.
239+
- `clear_chat_reminder` (`write`) tags: [chats]: Clear a chat reminder.
240+
241+
### Resource `messages`:
242+
243+
- `search_messages` (`read`) tags: [messages]: Search messages across chats using Beeper's message index.
244+
- When to use: find messages by text and/or filters (chatIDs, accountIDs, chatType, media type filters, sender, date ranges).
245+
- CRITICAL: Query is LITERAL WORD MATCHING, NOT semantic search! Only finds messages containing these EXACT words.
246+
• ✅ RIGHT: query="dinner" or query="sick" or query="error" (single words users type)
247+
• ❌ WRONG: query="dinner plans tonight" or query="health issues" (phrases/concepts)
248+
• The query matches ALL words provided (in any order). Example: query="flight booking" finds messages with both "flight" AND "booking".
249+
- Performance: provide chatIDs/accountIDs when known. Omitted 'query' returns results based on filters only. Partial matches enabled; 'excludeLowPriority' defaults to true.
250+
- Workflow tip: To search messages in specific conversations: 1) Use find-chats to get chatIDs, 2) Use search-messages with those chatIDs.
251+
- IMPORTANT: Chat names vary widely. ASK the user for clarification:
252+
• "Which chat do you mean by family?" (could be "The Smiths", "Mom Dad Kids", etc.)
253+
• "What's the name of your work chat?" (could be "Team", company name, project name)
254+
• "Who are the participants?" (use scope="participants" in search-chats)
255+
Returns: matching messages and referenced chats.
256+
- `send_message` (`write`) tags: [messages]: Send a text message to a specific chat. Supports replying to existing messages. Returns the sent message ID and a deeplink to the chat
257+
214258
### Resource `token`:
215259

216260
- `info_token` (`read`): Returns information about the authenticated user/token
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
import { Metadata, asTextContentResult } from '@beeper/desktop-api-mcp/tools/types';
4+
5+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
6+
import BeeperDesktop from '@beeper/desktop-api';
7+
8+
export const metadata: Metadata = {
9+
resource: 'accounts',
10+
operation: 'read',
11+
tags: ['accounts'],
12+
httpMethod: 'get',
13+
httpPath: '/v1/accounts',
14+
operationId: 'getAccounts',
15+
};
16+
17+
export const tool: Tool = {
18+
name: 'get_accounts',
19+
description: 'List connected accounts on this device. Use to pick account context.',
20+
inputSchema: {
21+
type: 'object',
22+
properties: {},
23+
required: [],
24+
},
25+
annotations: {
26+
readOnlyHint: true,
27+
},
28+
};
29+
30+
export const handler = async (client: BeeperDesktop, args: Record<string, unknown> | undefined) => {
31+
return asTextContentResult(await client.accounts.list());
32+
};
33+
34+
export default { metadata, tool, handler };
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
import { Metadata, asTextContentResult } from '@beeper/desktop-api-mcp/tools/types';
4+
5+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
6+
import BeeperDesktop from '@beeper/desktop-api';
7+
8+
export const metadata: Metadata = {
9+
resource: 'chats',
10+
operation: 'write',
11+
tags: ['chats'],
12+
httpMethod: 'post',
13+
httpPath: '/v1/chats/{chatID}/archive',
14+
operationId: 'archiveChat',
15+
};
16+
17+
export const tool: Tool = {
18+
name: 'archive_chat',
19+
description: 'Archive or unarchive a chat.',
20+
inputSchema: {
21+
type: 'object',
22+
properties: {
23+
chatID: {
24+
type: 'string',
25+
description:
26+
'The identifier of the chat to archive or unarchive (accepts both chatID and local chat ID)',
27+
},
28+
archived: {
29+
type: 'boolean',
30+
description: 'True to archive, false to unarchive',
31+
},
32+
},
33+
required: ['chatID'],
34+
},
35+
annotations: {},
36+
};
37+
38+
export const handler = async (client: BeeperDesktop, args: Record<string, unknown> | undefined) => {
39+
const { chatID, ...body } = args as any;
40+
return asTextContentResult(await client.chats.archive(chatID, body));
41+
};
42+
43+
export default { metadata, tool, handler };

0 commit comments

Comments
 (0)