Membrane CLI
A command-line interface for working with Membrane in local development environment.
Installation
npm install -g @membranehq/cli
yarn global add @membranehq/cli
bun install -g @membranehq/cli
pnpm install -g @membranehq/cli
Quick Start
membrane init
membrane init --key <key> --secret <secret>
membrane pull
membrane push
See the Configuration section below for alternative ways to configure credentials.
Authentication
Use membrane login to authenticate via browser-based OAuth. This stores your access token, refresh token, and the API URI locally.
membrane login
membrane login --apiUri http://localhost:9000
membrane login --non-interactive
membrane login --apiUri http://localhost:9000 start
membrane login complete <authorization-code>
membrane status
membrane logout
The --apiUri flag sets the API endpoint for this and all subsequent commands. Once logged in, the CLI remembers the API URI so you don't need to specify it again.
During login you select a default workspace and tenant. These defaults are saved in .membrane/config.json (project-level) and in the global ~/.membrane/credentials.json (so commands run outside any project still have a fallback). Tenant API commands like search, connection, and action use these defaults unless you pass --workspaceKey / --tenantKey.
How CLI commands authenticate
Commands fall into three groups based on which token type they need. The right client is chosen automatically — you only need to be logged in (membrane login) or have the relevant env vars set.
- Account commands (
status, logout) — call account-level APIs with the platform-user OAuth JWT from membrane login.
- Tenant API commands (
connect, search, request, action, connection, connection-request, agent-session) — call workspace/tenant APIs with a tenant-scoped JWT derived on demand from your platform-user token via POST /org-workspaces/{id}/access-token. Derived tokens are cached in ~/.membrane/credentials.json and refreshed automatically when expired. Set MEMBRANE_TOKEN to bypass derivation entirely with a pre-minted bearer token.
- Workspace management commands (
pull, push, sync, diff, init, mcp, open, test, codegen) — call workspace-management APIs with a workspace admin JWT minted locally from workspaceKey + workspaceSecret (read from membrane.config.yml or MEMBRANE_WORKSPACE_KEY/MEMBRANE_WORKSPACE_SECRET env vars). Set MEMBRANE_TOKEN to bypass minting and use a pre-supplied bearer token.
Connecting External Apps
Use membrane connect to create a connection to a third-party service via browser-based OAuth. Requires prior authentication via membrane login.
membrane connect --integrationKey hubspot
membrane connect --integrationKey hubspot --workspaceKey my-workspace --tenantKey my-customer
membrane connect --connectorId 123
membrane connect --connectionId abc
membrane connect --integrationKey hubspot --no-browser
Tenant API commands
These commands call workspace APIs using the token from membrane login. They use your default workspace and tenant from login unless you pass --workspaceKey and --tenantKey. You can also pass a bearer token with MEMBRANE_TOKEN (see Configuration).
Search workspace elements
membrane search "slack" --elementType connector
membrane search "invoice" --limit 20 --json
Proxy HTTP requests to an external application through a connection
Make an HTTP request via the Membrane connection proxy (similar to curl):
membrane request <connectionId> /v1/resource
membrane request <connectionId> /items?page=1 -X GET
membrane request <connectionId> /items -X POST -d '{"name":"example"}' --json
Use -H 'Header: value' (repeatable), --query key=value, --pathParam id=123, and --rawData to send --data as a plain string.
Manage connections
membrane connection list
membrane connection get <id>
membrane connection get <id> --wait
membrane connection ensure https://slack.com
membrane connection create "Connect to Slack"
Manage actions (tools)
membrane action list
membrane action list --connectionId <id> --intent "send email"
membrane action get <id> --wait --json
membrane action create "Summarize the latest tickets"
membrane action run <actionId> --connectionId <id> --input '{"query":"..."}'
Connection requests (OAuth flows)
Lower-level control of connection requests (browser connect is usually simpler):
membrane connection-request create --integrationKey hubspot
membrane connection-request get <requestId>
Agent sessions
membrane agent-session list
membrane agent-session create --message "Add a HubSpot connector for contacts"
membrane agent-session get <sessionId> --wait
membrane agent-session send <sessionId> --message "Also add list sync"
membrane agent-session messages <sessionId>
membrane agent-session abort <sessionId>
Use --agent <name> with create to pick a specific agent when supported.
Model Context Protocol (MCP)
Run an MCP server over stdio that exposes Membrane API operations as tools (for editors and agents that speak MCP):
membrane mcp
Requires MEMBRANE_ACCESS_TOKEN, or MEMBRANE_WORKSPACE_KEY and MEMBRANE_WORKSPACE_SECRET (or values in membrane.config.yml / after membrane init).
Experimental commands
These may change or behave differently in future releases.
Real-time sync (TUI)
membrane sync --watch
membrane sync --watch --rps 5
Interactive configuration
membrane config
Code generation
From local workspace actions, generate OpenAPI or TypeScript. Currently only schema generation is supported, so --schemasOnly is required:
membrane codegen \
--actions list-files,get-file-by-id \
--out src/generated \
--target openapi \
--schemasOnly
--target is openapi or typescript.
Integration tests
membrane test run connectors/hubspot
membrane test run actions/create-contact --fix
See membrane test run --help for path examples.
Open workspace in console
membrane open uses workspace credentials (not OAuth login tokens). It requires MEMBRANE_WORKSPACE_KEY and MEMBRANE_WORKSPACE_SECRET in environment variables or membrane.config.yml (for example, after membrane init).
membrane open
Synchronizing Workspace
Use membrane init to configure workspace credentials, then membrane pull and membrane push to synchronize workspace elements between local files and the remote workspace.
membrane init --key <key> --secret <secret>
membrane pull [--force]
membrane push [--force]
membrane diff
Configuration
The CLI can be configured using either environment variables or a configuration file (membrane.config.yml). Environment variables take precedence over the configuration file.
Environment Variables
export MEMBRANE_WORKSPACE_KEY=<your-workspace-key>
export MEMBRANE_WORKSPACE_SECRET=<your-workspace-secret>
export MEMBRANE_API_URI=https://api.your-membrane-instance.com
export MEMBRANE_CONSOLE_URI=https://console.your-membrane-instance.com
export MEMBRANE_TEST_CUSTOMER_ID=<test-customer-id>
export MEMBRANE_ACCESS_TOKEN=<token>
export MEMBRANE_TOKEN=<token>
MEMBRANE_ACCESS_TOKEN and MEMBRANE_TOKEN are not interchangeable:
MEMBRANE_ACCESS_TOKEN is used by membrane mcp to call the API directly (typically a workspace-scoped access token).
MEMBRANE_TOKEN is a pre-minted bearer token. It's accepted by both tenant API commands (where it bypasses the platform-user→tenant derivation) and workspace management commands like pull/push (where it bypasses the local key+secret JWT mint). Pass whichever flavor of token you have — the API call will reject it if it lacks the required scope.
Configuration File
The CLI uses a configuration file at membrane.config.yml:
workspaceKey: <your-workspace-key>
workspaceSecret: <your-workspace-secret>
apiUri: https://api.your-membrane-instance.com
consoleUri: https://console.your-membrane-instance.com
testCustomerId: test-customer
Note: When both environment variables and configuration file are present, environment variables take precedence.
Self-Hosting: For details on self-hosting Membrane, see Self-Hosting Documentation.
Version Control
membrane.config.yml contains secrets. You should exclude it from version control.
membrane folder can and should be stored in version control to keep your integration configurations versioned.
Transferring elements between workspaces with pull and push
The CLI provides a pull and push command to transfer workspace elements between environments. You'd typically use this to move integrations, actions, flows, and other configurations from development to production.
How it works:
Workspace elements (integrations, actions, data sources, flows, field mappings, etc.) are stored as YAML files in the ./membrane directory. Each element has a unique UUID that identifies it across workspaces.
When you pull, the CLI:
- Exports all elements from the remote workspace as YAML
- Compares them with your local
./membrane directory by UUID
- Identifies what's new, changed, or deleted in the remote workspace
- Downloads connector source code for custom connectors
- Updates your local files to match the remote state
When you push, the CLI:
- Packages your local
./membrane directory as an export
- Compares it with the current state of the remote workspace
- Identifies what's new, changed, or deleted locally
- Uploads connector source code for custom connectors
- Applies the changes to the remote workspace
Changes are applied in dependency order (integrations before integration-level elements, parents before children) to maintain referential integrity. Conflicts occur when an element exists in only one location; use --force to resolve by preferring the source.
When you diff, the CLI:
- Compares current local state with the remote workspace
- Displays a unified diff of all changes
Useful for previewing what push would do before actually applying changes.
Example:
export MEMBRANE_WORKSPACE_KEY="dev-workspace-key"
export MEMBRANE_WORKSPACE_SECRET="dev-workspace-secret"
membrane pull
export MEMBRANE_WORKSPACE_KEY="prod-workspace-key"
export MEMBRANE_WORKSPACE_SECRET="prod-workspace-secret"
membrane push
License
MIT