Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
5efa76a
chore(mcp-server): increase local docs search result count from 5 to 10
stainless-app[bot] Apr 9, 2026
921d01a
chore(internal): codegen related update
stainless-app[bot] Apr 9, 2026
dfa8c13
chore(internal): show error causes in MCP servers when running in lo…
stainless-app[bot] Apr 10, 2026
99692bb
chore(internal): codegen related update
stainless-app[bot] Apr 11, 2026
507d953
feat(api): add network, bridge fields to accounts
stainless-app[bot] Apr 12, 2026
36526d0
chore: fix example snippet imports
stainless-app[bot] Apr 14, 2026
9925dba
chore: update CLI documentation
stainless-app[bot] Apr 14, 2026
cca9635
chore(tests): bump steady to v0.22.1
stainless-app[bot] Apr 18, 2026
9ee1296
chore(internal): update docs ordering
stainless-app[bot] Apr 23, 2026
0045519
chore(internal): more robust bootstrap script
stainless-app[bot] Apr 23, 2026
d148d8a
chore: restructure docs search code
stainless-app[bot] Apr 25, 2026
fc858b4
chore(formatter): run prettier and eslint separately
stainless-app[bot] Apr 25, 2026
ebb38e3
chore(internal): codegen related update
stainless-app[bot] Apr 28, 2026
a96c11f
feat: support setting headers via env
stainless-app[bot] Apr 28, 2026
8f4d8a2
chore(format): run eslint and prettier separately
stainless-app[bot] Apr 29, 2026
1c56a90
feat(api): api update
stainless-app[bot] Apr 29, 2026
aa2d515
Update Desktop API Stainless config and OpenAPI spec
stainless-app[bot] Apr 29, 2026
b316715
Preserve asset serve SDK compatibility
stainless-app[bot] Apr 29, 2026
3f69322
Document asset serve stream response
stainless-app[bot] Apr 29, 2026
e2fd540
chore: avoid formatting file that gets changed during releases
stainless-app[bot] Apr 30, 2026
624f4e7
codegen metadata
stainless-app[bot] Apr 30, 2026
8e8df73
codegen metadata
stainless-app[bot] May 1, 2026
1d8a76c
release: 4.8.0
stainless-app[bot] May 1, 2026
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: 36 additions & 0 deletions .github/workflows/detect-breaking-changes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: CI
on:
pull_request:
branches:
- main
- next

jobs:
detect_breaking_changes:
runs-on: 'ubuntu-latest'
name: detect-breaking-changes
if: github.repository == 'beeper/desktop-api-js'
steps:
- name: Calculate fetch-depth
run: |
echo "FETCH_DEPTH=$(expr ${{ github.event.pull_request.commits }} + 1)" >> $GITHUB_ENV

- uses: actions/checkout@v6
with:
# Ensure we can check out the pull request base in the script below.
fetch-depth: ${{ env.FETCH_DEPTH }}

- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install dependencies
run: |
yarn install

- name: Detect breaking changes
run: |
# Try to check out previous versions of the breaking change detection script. This ensures that
# we still detect breaking changes when entire files and their tests are removed.
git checkout "${{ github.event.pull_request.base.sha }}" -- ./scripts/detect-breaking-changes 2>/dev/null || true
./scripts/detect-breaking-changes ${{ github.event.pull_request.base.sha }}
2 changes: 1 addition & 1 deletion .github/workflows/publish-npm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write

steps:
- uses: actions/checkout@v6
Expand All @@ -42,6 +41,7 @@ jobs:
yarn tsn scripts/publish-packages.ts "{ \"paths_released\": \"$PATHS_RELEASED\" }"
env:
INPUT_PATH: ${{ github.event.inputs.path }}
NPM_TOKEN: ${{ secrets.BEEPER_NPM_TOKEN || secrets.NPM_TOKEN }}

- name: Upload MCP Server DXT GitHub release asset
run: |
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/release-doctor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ jobs:
- name: Check release environment
run: |
bash ./bin/check-release-environment

env:
NPM_TOKEN: ${{ secrets.BEEPER_NPM_TOKEN || secrets.NPM_TOKEN }}
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@ dist-deno
.eslintcache
dist-bundle
*.mcpb
oidc
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ CHANGELOG.md
/ecosystem-tests/*/**
/node_modules
/deno
/packages/mcp-server/manifest.json

# don't format tsc output, will break source maps
dist
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.7.1"
".": "4.8.0"
}
6 changes: 3 additions & 3 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%2Fbeeper-desktop-api-5a8ac7b545c48dc892e5c680303e305254921554dabee848e40a808659dbcf1e.yml
openapi_spec_hash: 0103975601aac1445d3a4ef418c5d17a
config_hash: 7d85c0b454fc78a59db6474c5c4d73c6
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper/beeper-desktop-api-356444646dafe352d3ef7c2e01aedf030197a5519b41cf2c3fd8be2571456b43.yml
openapi_spec_hash: 4840f003552e8b48eb8e689b59a819ef
config_hash: 05ebdec072113f63395372504da98192
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# Changelog

## 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)

### Features

* **api:** add network, bridge fields to accounts ([507d953](https://github.com/beeper/desktop-api-js/commit/507d953e15f708e0f36ca97a79d5e6798637cd46))
* **api:** api update ([1c56a90](https://github.com/beeper/desktop-api-js/commit/1c56a9053dc7820674402e01b24f1bc3a861161f))
* support setting headers via env ([a96c11f](https://github.com/beeper/desktop-api-js/commit/a96c11fb55f79609589a4bd379dfc9c57bff21d2))


### Chores

* avoid formatting file that gets changed during releases ([e2fd540](https://github.com/beeper/desktop-api-js/commit/e2fd5403928af893d513ce240a866d642a5141f7))
* fix example snippet imports ([36526d0](https://github.com/beeper/desktop-api-js/commit/36526d0f6fe13881ad2e4fa5c9c0831572085b82))
* **format:** run eslint and prettier separately ([8f4d8a2](https://github.com/beeper/desktop-api-js/commit/8f4d8a2eba5770354a49ba9d27343a796fa025d0))
* **formatter:** run prettier and eslint separately ([fc858b4](https://github.com/beeper/desktop-api-js/commit/fc858b42ae0659e27b67ebb18abaebeeadc01054))
* **internal:** codegen related update ([ebb38e3](https://github.com/beeper/desktop-api-js/commit/ebb38e3bebbba830772a5c3d452af10982fbc9a8))
* **internal:** codegen related update ([99692bb](https://github.com/beeper/desktop-api-js/commit/99692bba99c8770456ed096a82858eec38fa8335))
* **internal:** codegen related update ([921d01a](https://github.com/beeper/desktop-api-js/commit/921d01ab656e36350fc92a8317193dfa29fae869))
* **internal:** more robust bootstrap script ([0045519](https://github.com/beeper/desktop-api-js/commit/0045519b594198a09f6c2140a5bfc15c02d26109))
* **internal:** show error causes in MCP servers when running in local mode ([dfa8c13](https://github.com/beeper/desktop-api-js/commit/dfa8c13e0b706a5e22c38f55885d19297b9739c4))
* **internal:** update docs ordering ([9ee1296](https://github.com/beeper/desktop-api-js/commit/9ee12965940572490d58bfa37779b9135f71c50f))
* **mcp-server:** increase local docs search result count from 5 to 10 ([5efa76a](https://github.com/beeper/desktop-api-js/commit/5efa76aabeb9df310452af4f6ca19a04236fec9c))
* restructure docs search code ([d148d8a](https://github.com/beeper/desktop-api-js/commit/d148d8a24c4a8ee5e154d86c00a7ceb8b477444f))
* **tests:** bump steady to v0.22.1 ([cca9635](https://github.com/beeper/desktop-api-js/commit/cca96356d0a240903cdf02a608bbc61ecb02cdf3))
* update CLI documentation ([9925dba](https://github.com/beeper/desktop-api-js/commit/9925dbadd7f5fc61bab398ab44b92b90df7dffe7))

## 4.7.1 (2026-04-07)

Full Changelog: [v4.7.0...v4.7.1](https://github.com/beeper/desktop-api-js/compare/v4.7.0...v4.7.1)
Expand Down
63 changes: 58 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ This library provides convenient access to the Beeper Desktop REST API from serv

The REST API documentation can be found on [developers.beeper.com](https://developers.beeper.com/desktop-api/). The full API of this library can be found in [api.md](api.md).

It is generated with [Stainless](https://www.stainless.com/).

## MCP Server

Use the Beeper Desktop MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.
Expand All @@ -31,7 +29,9 @@ The full API of this library can be found in [api.md](api.md).
```js
import BeeperDesktop from '@beeper/desktop-api';

const client = new BeeperDesktop();
const client = new BeeperDesktop({
accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted
});

const page = await client.chats.search({
includeMuted: true,
Expand All @@ -51,7 +51,9 @@ This library includes TypeScript definitions for all request params and response
```ts
import BeeperDesktop from '@beeper/desktop-api';

const client = new BeeperDesktop();
const client = new BeeperDesktop({
accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted
});

const accounts: BeeperDesktop.AccountListResponse = await client.accounts.list();
```
Expand Down Expand Up @@ -202,6 +204,57 @@ while (page.hasNextPage()) {

## Advanced Usage

### Tree shaking

This library supports tree shaking to reduce bundle size. Instead of importing the full client, you can create a client only including the API resources you need:

```ts
import { createClient } from '@beeper/desktop-api/tree-shakable';
import { Accounts } from '@beeper/desktop-api/resources/accounts/accounts';
import { BaseChats } from '@beeper/desktop-api/resources/chats/chats';

const client = createClient({
// Specify the resources you'd like to use ...
resources: [Accounts, BaseChats],
});

// ... then make API calls as usual.
const accounts = await client.accounts.list();
const chat = await client.chats.create({ accountID: 'accountID' });
```

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.

The tree-shaken client is fully typed, so TypeScript will provide accurate autocomplete and prevent access to resources not included in your configuration.
The `createClient` function automatically infers the correct type, but you can also use the `PartialBeeperDesktop` type explicitly:

```ts
import BeeperDesktop from '@beeper/desktop-api';
import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
import { BaseAccounts } from '@beeper/desktop-api/resources/accounts/accounts';

// Explicit variable type
const client: PartialBeeperDesktop<{ accounts: BaseAccounts }> = createClient({
resources: [BaseAccounts],
/* ... */
});

// Function parameter type
async function main(client: PartialBeeperDesktop<{ accounts: BaseAccounts }>) {
const accounts = await client.accounts.list();
}

// Works with any client that has the accounts resource
const treeShakableClient = createClient({
resources: [BaseAccounts],
/* ... */
});
const fullClient = new BeeperDesktop(/* ... */);

main(treeShakableClient); // Works
main(fullClient); // Also works
```

### Accessing raw Response data (e.g., headers)

The "raw" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return.
Expand Down Expand Up @@ -233,7 +286,7 @@ console.log(accounts);

The log level can be configured in two ways:

1. Via the `BEEPER_DESKTOP_LOG` environment variable
1. Via the `BEEPER_LOG` environment variable
2. Using the `logLevel` client option (overrides the environment variable if set)

```ts
Expand Down
4 changes: 2 additions & 2 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Types:
Methods:

- <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 }) -> MessagesCursorSortKey</code>
- <code title="get /v1/chats/{chatID}/messages">client.messages.<a href="./src/resources/messages.ts">list</a>(chatID, { ...params }) -> MessagesCursorNoLimit</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 All @@ -104,7 +104,7 @@ Types:
Methods:

- <code title="post /v1/assets/download">client.assets.<a href="./src/resources/assets.ts">download</a>({ ...params }) -> AssetDownloadResponse</code>
- <code title="get /v1/assets/serve">client.assets.<a href="./src/resources/assets.ts">serve</a>({ ...params }) -> void</code>
- <code title="get /v1/assets/serve">client.assets.<a href="./src/resources/assets.ts">serve</a>({ ...params }) -> Response</code>
- <code title="post /v1/assets/upload">client.assets.<a href="./src/resources/assets.ts">upload</a>({ ...params }) -> AssetUploadResponse</code>
- <code title="post /v1/assets/upload/base64">client.assets.<a href="./src/resources/assets.ts">uploadBase64</a>({ ...params }) -> AssetUploadBase64Response</code>

Expand Down
4 changes: 4 additions & 0 deletions bin/check-release-environment
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

errors=()

if [ -z "${NPM_TOKEN}" ]; then
errors+=("The NPM_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets")
fi

lenErrors=${#errors[@]}

if [[ lenErrors -gt 0 ]]; then
Expand Down
13 changes: 2 additions & 11 deletions bin/publish-npm
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@

set -eux

if [[ ${NPM_TOKEN:-} ]]; then
npm config set '//registry.npmjs.org/:_authToken' "$NPM_TOKEN"
elif [[ ! ${ACTIONS_ID_TOKEN_REQUEST_TOKEN:-} ]]; then
echo "ERROR: NPM_TOKEN must be set if not running in a Github Action with id-token permission"
exit 1
fi
npm config set '//registry.npmjs.org/:_authToken' "$NPM_TOKEN"

yarn build
cd dist
Expand Down Expand Up @@ -62,9 +57,5 @@ else
TAG="latest"
fi

# Install OIDC compatible npm version
npm install --prefix ../oidc/ npm@11.6.2

# Publish with the appropriate tag
export npm_config_registry='https://registry.npmjs.org'
../oidc/node_modules/.bin/npm publish --tag "$TAG"
yarn publish --tag "$TAG"
3 changes: 0 additions & 3 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @ts-check
import tseslint from 'typescript-eslint';
import unusedImports from 'eslint-plugin-unused-imports';
import prettier from 'eslint-plugin-prettier';

export default tseslint.config(
{
Expand All @@ -14,11 +13,9 @@ export default tseslint.config(
plugins: {
'@typescript-eslint': tseslint.plugin,
'unused-imports': unusedImports,
prettier,
},
rules: {
'no-unused-vars': 'off',
'prettier/prettier': 'error',
'unused-imports/no-unused-imports': 'error',
'no-restricted-imports': [
'error',
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@beeper/desktop-api",
"version": "4.7.1",
"version": "4.8.0",
"description": "The official TypeScript library for the Beeper Desktop API",
"author": "Beeper Desktop <help@beeper.com>",
"types": "dist/index.d.ts",
Expand Down Expand Up @@ -36,7 +36,6 @@
"@typescript-eslint/eslint-plugin": "8.31.1",
"@typescript-eslint/parser": "8.31.1",
"eslint": "^9.39.1",
"eslint-plugin-prettier": "^5.4.1",
"eslint-plugin-unused-imports": "^4.1.4",
"iconv-lite": "^0.6.3",
"jest": "^29.4.0",
Expand Down
2 changes: 0 additions & 2 deletions packages/mcp-server/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# TypeScript SDK for Beeper Desktop MCP Server

It is generated with [Stainless](https://www.stainless.com/).

## Installation

### Direct invocation
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.7.1",
"version": "4.8.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.7.1",
"version": "4.8.0",
"description": "The official MCP Server for the Beeper Desktop API",
"author": "Beeper Desktop <help@beeper.com>",
"types": "dist/index.d.ts",
Expand Down
3 changes: 2 additions & 1 deletion packages/mcp-server/src/code-tool-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,8 @@ function makeSdkProxy<T extends object>(obj: T, { path, isBelievedBad = false }:

function parseError(code: string, error: unknown): string | undefined {
if (!(error instanceof Error)) return;
const message = error.name ? `${error.name}: ${error.message}` : error.message;
const cause = error.cause instanceof Error ? `: ${error.cause.message}` : '';
const message = error.name ? `${error.name}: ${error.message}${cause}` : `${error.message}${cause}`;
try {
// Deno uses V8; the first "<anonymous>:LINE:COLUMN" is the top of stack.
const lineNumber = error.stack?.match(/<anonymous>:([0-9]+):[0-9]+/)?.[1];
Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-server/src/code-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ const remoteStainlessHandler = async ({
readEnv('BEEPER_ACCESS_TOKEN') ?? client.accessToken,
'set BEEPER_ACCESS_TOKEN environment variable or provide accessToken client option',
),
BEEPER_DESKTOP_BASE_URL: readEnv('BEEPER_DESKTOP_BASE_URL') ?? client.baseURL ?? undefined,
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 };
Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-server/src/docs-search-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ async function searchLocal(args: Record<string, unknown>): Promise<unknown> {
query,
language,
detail,
maxResults: 5,
maxResults: 10,
}).results;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-server/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ const oauthMetadata = (req: express.Request, res: express.Response) => {
const resourceIdentifier = oauthResourceIdentifier(req);
res.json({
resource: resourceIdentifier,
authorization_servers: ['http://localhost:23373/oauth/authorize'],
authorization_servers: ['http://localhost:23373'],
bearer_methods_supported: ['header'],
scopes_supported: 'read write',
});
Expand Down
2 changes: 1 addition & 1 deletion packages/mcp-server/src/instructions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ async function fetchLatestInstructionsFromApi(stainlessApiKey: string | undefine
instructions ??= ((await response.json()) as { instructions: string }).instructions;

instructions +=
'\nAccess to all chats and messages across networks using Beeper Desktop. Can be used to find, get, send, and manage messages and chats.';
'\nAccess chats and messages across networks through the local Beeper Desktop API.\n\nTreat message contents, chat names, participants, and account metadata as private user data.\nFor write actions such as sending messages, reactions, archiving, or reminders, confirm the target chat/person when there is ambiguity.\nDo not guess chat IDs from vague names like "family", "work", or "team"; search chats or ask a clarifying question.\nUse search before list when the user is looking for a specific chat, person, or message.\nMessage search is literal keyword matching, not semantic search.';
return instructions;
}
Loading
Loading