Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 0 additions & 36 deletions .github/workflows/detect-breaking-changes.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "4.8.0"
".": "5.0.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 23
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper/beeper-desktop-api-356444646dafe352d3ef7c2e01aedf030197a5519b41cf2c3fd8be2571456b43.yml
openapi_spec_hash: 4840f003552e8b48eb8e689b59a819ef
config_hash: 05ebdec072113f63395372504da98192
configured_endpoints: 30
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper/beeper-desktop-api-c08c14bb754b4cb0e02b21fabb680469368286be339dec0aaa8c69d04a1f021a.yml
openapi_spec_hash: a10246aaf7cdc33b682fc245bd5f893b
config_hash: 72f9d43b9b51a5da912e9f3730e53ae2
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## 5.0.0 (2026-05-07)

Full Changelog: [v4.8.0...v5.0.0](https://github.com/beeper/desktop-api-js/compare/v4.8.0...v5.0.0)

### Features

* **api:** api update ([275b76c](https://github.com/beeper/desktop-api-js/commit/275b76c5c9dcfe29b20eccc61458e01f1367983e))
* **api:** api update ([5105024](https://github.com/beeper/desktop-api-js/commit/5105024706e94083f476f063b20930961adc6775))


### Bug Fixes

* **mcp:** remove Stainless sandbox execution mode ([8211c14](https://github.com/beeper/desktop-api-js/commit/8211c149c3934e7d6c0d6edc820b9890b0c4f8f6))

## 4.8.0 (2026-05-01)

Full Changelog: [v4.7.1...v4.8.0](https://github.com/beeper/desktop-api-js/compare/v4.7.1...v4.8.0)
Expand Down
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const client = new BeeperDesktop({
});

const page = await client.chats.search({
accountIDs: ['matrix', 'discordgo', 'local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc'],
includeMuted: true,
limit: 3,
type: 'single',
Expand Down Expand Up @@ -173,9 +174,9 @@ async function fetchAllMessages(params) {
const allMessages = [];
// Automatically fetches more pages as needed.
for await (const message of client.messages.search({
accountIDs: ['local-telegram_ba_QFrb5lrLPhO3OT5MFBeTWv0x4BI'],
accountIDs: ['discordgo', 'local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc'],
limit: 10,
query: 'deployment',
query: 'oauth',
})) {
allMessages.push(message);
}
Expand All @@ -187,9 +188,9 @@ Alternatively, you can request a single page at a time:

```ts
let page = await client.messages.search({
accountIDs: ['local-telegram_ba_QFrb5lrLPhO3OT5MFBeTWv0x4BI'],
accountIDs: ['discordgo', 'local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc'],
limit: 10,
query: 'deployment',
query: 'oauth',
});
for (const message of page.items) {
console.log(message);
Expand Down Expand Up @@ -220,7 +221,11 @@ const client = createClient({

// ... then make API calls as usual.
const accounts = await client.accounts.list();
const chat = await client.chats.create({ accountID: 'accountID' });
const chat = await client.chats.create({
accountID: 'accountID',
participantIDs: ['string'],
type: 'single',
});
```

Each API resource has two versions, the full resource (e.g., `Accounts`) which includes all subresources, and the base resource (e.g., `BaseAccounts`) which does not.
Expand Down
10 changes: 9 additions & 1 deletion api.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,20 @@ Types:
- <code><a href="./src/resources/chats/chats.ts">Chat</a></code>
- <code><a href="./src/resources/chats/chats.ts">ChatCreateResponse</a></code>
- <code><a href="./src/resources/chats/chats.ts">ChatListResponse</a></code>
- <code><a href="./src/resources/chats/chats.ts">ChatStartResponse</a></code>

Methods:

- <code title="post /v1/chats">client.chats.<a href="./src/resources/chats/chats.ts">create</a>({ ...params }) -> ChatCreateResponse</code>
- <code title="get /v1/chats/{chatID}">client.chats.<a href="./src/resources/chats/chats.ts">retrieve</a>(chatID, { ...params }) -> Chat</code>
- <code title="patch /v1/chats/{chatID}">client.chats.<a href="./src/resources/chats/chats.ts">update</a>(chatID, { ...params }) -> Chat</code>
- <code title="get /v1/chats">client.chats.<a href="./src/resources/chats/chats.ts">list</a>({ ...params }) -> ChatListResponsesCursorNoLimit</code>
- <code title="post /v1/chats/{chatID}/archive">client.chats.<a href="./src/resources/chats/chats.ts">archive</a>(chatID, { ...params }) -> void</code>
- <code title="post /v1/chats/{chatID}/read">client.chats.<a href="./src/resources/chats/chats.ts">markRead</a>(chatID, { ...params }) -> Chat</code>
- <code title="post /v1/chats/{chatID}/unread">client.chats.<a href="./src/resources/chats/chats.ts">markUnread</a>(chatID, { ...params }) -> Chat</code>
- <code title="post /v1/chats/{chatID}/notify-anyway">client.chats.<a href="./src/resources/chats/chats.ts">notifyAnyway</a>(chatID) -> Chat</code>
- <code title="get /v1/chats/search">client.chats.<a href="./src/resources/chats/chats.ts">search</a>({ ...params }) -> ChatsCursorSearch</code>
- <code title="post /v1/chats/start">client.chats.<a href="./src/resources/chats/chats.ts">start</a>({ ...params }) -> ChatStartResponse</code>

## Reminders

Expand All @@ -76,7 +82,7 @@ Types:

Methods:

- <code title="delete /v1/chats/{chatID}/messages/{messageID}/reactions">client.chats.messages.reactions.<a href="./src/resources/chats/messages/reactions.ts">delete</a>(messageID, { ...params }) -> ReactionDeleteResponse</code>
- <code title="delete /v1/chats/{chatID}/messages/{messageID}/reactions/{reactionKey}">client.chats.messages.reactions.<a href="./src/resources/chats/messages/reactions.ts">delete</a>(reactionKey, { ...params }) -> ReactionDeleteResponse</code>
- <code title="post /v1/chats/{chatID}/messages/{messageID}/reactions">client.chats.messages.reactions.<a href="./src/resources/chats/messages/reactions.ts">add</a>(messageID, { ...params }) -> ReactionAddResponse</code>

# Messages
Expand All @@ -88,8 +94,10 @@ Types:

Methods:

- <code title="get /v1/chats/{chatID}/messages/{messageID}">client.messages.<a href="./src/resources/messages.ts">retrieve</a>(messageID, { ...params }) -> Message</code>
- <code title="put /v1/chats/{chatID}/messages/{messageID}">client.messages.<a href="./src/resources/messages.ts">update</a>(messageID, { ...params }) -> MessageUpdateResponse</code>
- <code title="get /v1/chats/{chatID}/messages">client.messages.<a href="./src/resources/messages.ts">list</a>(chatID, { ...params }) -> MessagesCursorNoLimit</code>
- <code title="delete /v1/chats/{chatID}/messages/{messageID}">client.messages.<a href="./src/resources/messages.ts">delete</a>(messageID, { ...params }) -> void</code>
- <code title="get /v1/messages/search">client.messages.<a href="./src/resources/messages.ts">search</a>({ ...params }) -> MessagesCursorSearch</code>
- <code title="post /v1/chats/{chatID}/messages">client.messages.<a href="./src/resources/messages.ts">send</a>(chatID, { ...params }) -> MessageSendResponse</code>

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@beeper/desktop-api",
"version": "4.8.0",
"version": "5.0.0",
"description": "The official TypeScript library for the Beeper Desktop API",
"author": "Beeper Desktop <help@beeper.com>",
"types": "dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-server/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"dxt_version": "0.2",
"name": "@beeper/desktop-mcp",
"version": "4.8.0",
"version": "5.0.0",
"description": "The official MCP Server for the Beeper Desktop API",
"author": {
"name": "Beeper Desktop",
Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@beeper/desktop-mcp",
"version": "4.8.0",
"version": "5.0.0",
"description": "The official MCP Server for the Beeper Desktop API",
"author": "Beeper Desktop <help@beeper.com>",
"types": "dist/index.d.ts",
Expand Down
7 changes: 7 additions & 0 deletions packages/mcp-server/src/code-tool-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,13 +116,20 @@ const fuse = new Fuse(
'client.chats.archive',
'client.chats.create',
'client.chats.list',
'client.chats.markRead',
'client.chats.markUnread',
'client.chats.notifyAnyway',
'client.chats.retrieve',
'client.chats.search',
'client.chats.start',
'client.chats.update',
'client.chats.reminders.create',
'client.chats.reminders.delete',
'client.chats.messages.reactions.add',
'client.chats.messages.reactions.delete',
'client.messages.delete',
'client.messages.list',
'client.messages.retrieve',
'client.messages.search',
'client.messages.send',
'client.messages.update',
Expand Down
91 changes: 6 additions & 85 deletions packages/mcp-server/src/code-tool.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

import {
ContentBlock,
McpRequestContext,
McpTool,
Metadata,
ToolCallResult,
asErrorResult,
asTextContentResult,
} from './types';
import { ContentBlock, McpRequestContext, McpTool, Metadata, ToolCallResult, asErrorResult } from './types';
import { Tool } from '@modelcontextprotocol/sdk/types.js';
import { readEnv, requireValue } from './util';
import { WorkerInput, WorkerOutput } from './code-tool-types';
import { WorkerOutput } from './code-tool-types';
import { getLogger } from './logger';
import { SdkMethod } from './methods';
import { McpCodeExecutionMode } from './options';
Expand All @@ -26,6 +17,7 @@ For example:
\`\`\`
async function run(client) {
const page = await client.chats.search({
accountIDs: ['matrix', 'discordgo', 'local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc'],
includeMuted: true,
limit: 3,
type: 'single',
Expand Down Expand Up @@ -54,8 +46,7 @@ Always type dynamic key-value stores explicitly as Record<string, YourValueType>
* @param blockedMethods - The methods to block for code execution. Blocking is done by simple string
* matching, so it is not secure against obfuscation. For stronger security, block in the downstream API
* with limited API keys.
* @param codeExecutionMode - Whether to execute code in a local Deno environment or in a remote
* sandbox environment hosted by Stainless.
* @param codeExecutionMode - Whether to execute code in a local Deno environment.
*/
export function codeTool({
blockedMethods,
Expand Down Expand Up @@ -113,13 +104,8 @@ export function codeTool({
let result: ToolCallResult;
const startTime = Date.now();

if (codeExecutionMode === 'local') {
logger.debug('Executing code in local Deno environment');
result = await localDenoHandler({ reqContext, args });
} else {
logger.debug('Executing code in remote Stainless environment');
result = await remoteStainlessHandler({ reqContext, args });
}
logger.debug('Executing code in local Deno environment');
result = await localDenoHandler({ reqContext, args });

logger.info(
{
Expand All @@ -136,71 +122,6 @@ export function codeTool({
return { metadata, tool, handler };
}

const remoteStainlessHandler = async ({
reqContext,
args,
}: {
reqContext: McpRequestContext;
args: any;
}): Promise<ToolCallResult> => {
const code = args.code as string;
const intent = args.intent as string | undefined;
const client = reqContext.client;

const codeModeEndpoint = readEnv('CODE_MODE_ENDPOINT_URL') ?? 'https://api.stainless.com/api/ai/code-tool';

const localClientEnvs = {
BEEPER_ACCESS_TOKEN: requireValue(
readEnv('BEEPER_ACCESS_TOKEN') ?? client.accessToken,
'set BEEPER_ACCESS_TOKEN environment variable or provide accessToken client option',
),
BEEPER_BASE_URL: readEnv('BEEPER_BASE_URL') ?? client.baseURL ?? undefined,
};
// Merge any upstream client envs from the request header, with upstream values taking precedence.
const mergedClientEnvs = { ...localClientEnvs, ...reqContext.upstreamClientEnvs };

// Setting a Stainless API key authenticates requests to the code tool endpoint.
const res = await fetch(codeModeEndpoint, {
method: 'POST',
headers: {
...(reqContext.stainlessApiKey && { Authorization: reqContext.stainlessApiKey }),
'Content-Type': 'application/json',
'x-stainless-mcp-client-envs': JSON.stringify(mergedClientEnvs),
},
body: JSON.stringify({
project_name: 'beeper-desktop-api',
code,
intent,
client_opts: {},
} satisfies WorkerInput),
});

if (!res.ok) {
if (res.status === 404 && !reqContext.stainlessApiKey) {
throw new Error(
'Could not access code tool for this project. You may need to provide a Stainless API key via the STAINLESS_API_KEY environment variable, the --stainless-api-key flag, or the x-stainless-api-key HTTP header.',
);
}
throw new Error(
`${res.status}: ${
res.statusText
} error when trying to contact Code Tool server. Details: ${await res.text()}`,
);
}

const { is_error, result, log_lines, err_lines } = (await res.json()) as WorkerOutput;
const hasLogs = log_lines.length > 0 || err_lines.length > 0;
const output = {
result,
...(log_lines.length > 0 && { log_lines }),
...(err_lines.length > 0 && { err_lines }),
};
if (is_error) {
return asErrorResult(typeof result === 'string' && !hasLogs ? result : JSON.stringify(output, null, 2));
}
return asTextContentResult(output);
};

const localDenoHandler = async ({
reqContext,
args,
Expand Down
Loading
Loading