Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.mesa.dev/llms.txt

Use this file to discover all available pages before exploring further.

The Mesa TypeScript SDK is the ergonomic client for Mesa in Node.js and JavaScript runtimes. It wraps the generated @mesadev/rest client, resolves the default organization for you, verifies webhooks, and exposes a native virtual filesystem for repo I/O and shell execution. Node.js 18 or newer is required.

Installation

npm install @mesadev/sdk

Create a client

import { Mesa } from '@mesadev/sdk';

const mesa = new Mesa({ apiKey: process.env.MESA_API_KEY });

const repos = await mesa.repos.list({ limit: 50 });
console.log(`found ${repos.repos.length} repos`);
Set MESA_API_KEY in your environment to omit apiKey from the constructor.

Client options

import { Mesa } from '@mesadev/sdk';

const mesa = new Mesa({
  apiKey: 'mk_...',
  apiUrl: 'https://api.mesa.dev/v1',
  vcsUrl: 'https://vcs.mesa.dev',
  org: 'acme',
  fetch: globalThis.fetch,
  userAgent: 'my-app/1.0.0',
  webhookSecret: 'whsec_...',
});
apiKey
string | undefined
API key used as a bearer token. If omitted in Node.js, the SDK reads MESA_API_KEY from the environment. If neither is present, construction throws MissingApiKeyError.
apiUrl
string
REST API base URL. Defaults to https://api.mesa.dev/v1. http and https are accepted. Trailing slashes are stripped.
vcsUrl
string
VCS service URL used by mesa.fs.mount(...). Defaults to https://vcs.mesa.dev. Set this when using a non-default API deployment with MesaFS.
org
string | undefined
Default organization slug. When provided, SDK calls skip /whoami for organization resolution.
fetch
typeof globalThis.fetch | undefined
Custom fetch implementation for REST requests.
userAgent
string | undefined
Appended to the SDK user agent. Node.js uses User-Agent; browser-like runtimes use X-Mesa-User-Agent.
webhookSecret
string | undefined
Signing secret used by mesa.webhooks.receive(...).

Lifecycle

The TypeScript client does not hold an HTTP session and does not need to be closed. Reuse one Mesa instance where practical. mesa.fs.mount(...) creates a temporary scoped API key for each mounted filesystem. The SDK attempts to revoke those keys on process shutdown and garbage collection.

Organization resolution

The SDK chooses an organization in this order:
SourceWhen it applies
Per-call orgThe method input includes org: '...'.
Constructor orgThe client was created with new Mesa({ org: '...' }).
mesa.whoami()No per-call or constructor org was supplied. The result is cached.
const mesa = new Mesa({ org: 'acme' });

await mesa.repos.list();
await mesa.repos.list({ org: 'other-org' });

Resource namespaces

NamespacePurpose
mesa.reposCreate, read, update, delete, pull, and push repositories.
mesa.contentRead files, symlinks, and directory listings without mounting.
mesa.changesCreate, patch, and inspect Mesa changes.
mesa.diffsInspect diffs and conflicts between changes.
mesa.bookmarksManage branch-like bookmark refs.
mesa.apiKeysCreate, list, and revoke Mesa API keys.
mesa.webhookTargetsManage outbound webhook targets.
mesa.webhooksVerify incoming webhook requests and dispatch typed handlers.
mesa.fsMount repos as a virtual filesystem and run Bash commands.
mesa.orgFetch organization metadata.
Sync run endpoints and bulk repository tag updates are available through mesa.raw.

Response objects

High-level SDK methods return response data directly. They do not return generated HTTP wrapper objects.
const repos = await mesa.repos.list();
for (const repo of repos.repos) {
  console.log(repo.name, repo.head_change_id);
}
Generated response aliases such as GetRepoResponse live in @mesadev/rest.

Common types

Import SDK-owned types from @mesadev/sdk.
import type { FsMountOptions, MesaOptions, RepoConfig, WebhookEvent } from '@mesadev/sdk';
TypePurpose
MesaOptionsConstructor options for new Mesa(...).
FsMountOptionsOptions for mesa.fs.mount(...).
RepoConfigPin a mounted repo to a bookmark or change.
MesaFileSystemNative filesystem implementation returned by mesa.fs.mount(...).
ChangeInfoChange metadata returned by mounted filesystem change operations.
ExecResultOutput from fs.bash().exec(...), re-exported from just-bash.
WebhookEventDiscriminated union of webhook event payloads.
High-level REST method input types are inferred from the method signatures. If you need named REST schema types, import them from @mesadev/rest.

Error model

SDK-owned setup and webhook errors extend MesaError and expose a stable code field.
ExceptionCodeMeaning
MissingApiKeyErrorMISSING_API_KEYNo API key was provided and MESA_API_KEY was unavailable.
InvalidApiUrlErrorINVALID_API_URLapiUrl or vcsUrl is malformed or uses a protocol other than http or https.
InvalidOptionsErrorINVALID_OPTIONSLocal options are invalid, such as mounting zero repositories.
OrgResolutionErrorORG_RESOLUTION_FAILEDThe SDK could not resolve the default organization through /whoami.
MissingWebhookSecretErrorMISSING_WEBHOOK_SECRETmesa.webhooks.receive(...) was called without a constructor webhookSecret.
MesaWebhookVerificationErrorWEBHOOK_VERIFICATION_FAILEDWebhook signature, timestamp, JSON parsing, or payload validation failed.
API operations throw Mesa API error payloads directly when the server returns an error response. These payloads are not MesaError instances.

Raw generated client

mesa.raw exposes generated REST operations with authentication, base URL, fetch, and user-agent already wired in. Use it when the high-level SDK does not expose an operation or option yet.
const repo = await mesa.raw.getRepo({
  path: { org: 'acme', repo: 'app' },
});
Raw calls use the generated REST request shape (path, query, body) and return response data directly.

Complete example

import { Buffer } from 'node:buffer';
import { Mesa } from '@mesadev/sdk';

const mesa = new Mesa({ org: 'acme' });

const repo = await mesa.repos.create({ name: 'demo' });

const change = await mesa.changes.create({
  repo: repo.name,
  base_change_id: repo.head_change_id,
  message: 'Add README',
  author: { name: 'Docs Bot', email: 'docs@example.com' },
  files: [
    {
      path: 'README.md',
      content: Buffer.from('# Demo\n').toString('base64'),
    },
  ],
});

await mesa.bookmarks.move({
  repo: repo.name,
  bookmark: repo.default_bookmark,
  change_id: change.id,
});

const fs = await mesa.fs.mount({ repos: [{ name: repo.name }] });
const data = await fs.readFileBuffer(`/acme/${repo.name}/README.md`);
console.log(Buffer.from(data).toString('utf8'));