Skip to main content
Glama

Composio Gateway

A self-hosted admin interface and MCP gateway. Members discover tools, request an exact tool set, and receive a restricted session only after an administrator approves it.

Run

Requires Node.js 22.19 or newer. On first startup, set ADMIN_TOKEN to a long random secret (at least 32 random bytes) in your environment or deployment secret manager. Keep the original in your password manager; only its SHA-256 hash is stored in data/admin.token.sha256.

npm ci
npm start

Open http://127.0.0.1:8788 and enter the original admin token, not its hash. The browser holds it only in memory; reloading locks the interface. A legacy data/admin.token is automatically hashed and removed. Save the original before upgrading; it cannot be recovered from the hash. See admin authentication.

  1. Set COMPOSIO_API_TOKEN to your Composio project API key and redeploy, or enter it in Connection. The catalog contains only apps connected by active gateway members.

  2. Under Members & sessions, create a member bound to their Composio user ID. Copy the member token; it is displayed once. Adding or reactivating members refreshes the catalog.

  3. The member connects to /mcp using that token, searches the catalog, and submits the tools needed for one session.

  4. Under Tools & requests → Session requests, review the member, reason, and exact tool list. Choose Approve request or Reject request. The list refreshes automatically, with a manual refresh button too.

  5. The member checks request status and collects the approved session. Configure a separate MCP connection with its returned URL and bearer token.

The catalog is read-only: there are no global enable/disable toggles. Approval of one request does not authorize another request, another member, or additional tools.

Related MCP server: safe-mcp-bridge-v2

Upgrade from global tool permissions

This is a breaking authentication-flow change. On the first startup of this version, existing execution sessions are revoked. Members and Composio credentials are preserved, but old global enabled/disabled settings no longer authorize execution. PUT /api/admin/policy returns HTTP 410.

An empty {} session-creation payload no longer issues a session. Clients must submit tools, wait for approval, then collect using request_id. Existing session-token MCP transport and individual revocation remain supported for newly approved sessions.

Discover tools and request a session through MCP

Configure an HTTP MCP connection:

  • URL: https://gateway.example.com/mcp

  • Header: Authorization: Bearer <member-token>

It exposes four tools:

Tool

Arguments

Result

COMPOSIO_SEARCH_TOOLS

{"query":"repository","limit":20,"offset":0}

Read-only catalog search; follow next_offset for more results

COMPOSIO_GET_TOOL_SCHEMAS

{"tool_slugs":["GITHUB_GET_REPOSITORY_CONTENT"]}

Input/output metadata for up to 20 tools

GATEWAY_CREATE_SESSION

{"tools":["GITHUB_GET_REPOSITORY_CONTENT"],"reason":"Read files for a code review"}

A pending request with request_id; no session token

GATEWAY_GET_SESSION_REQUEST

{"request_id":"<request-id>"}

Current status, requested tools, and expiry; never credentials

After status becomes approved, call GATEWAY_CREATE_SESSION with only:

{ "request_id": "<request-id>" }

This issues one session with the exact approved tools and returns its credentials once. Repeated calls report issued without returning credentials or creating another session. Store the successful result immediately. If the credentials are lost, submit a new request for approval.

Discovery requires no gateway or upstream execution session and does not grant permission to execute anything. Search is local keyword matching, not Composio semantic search; the member-endpoint schemas differ from upstream meta-tool schemas. Schema lookup uses Composio's read-only metadata API. Both are restricted to the member's currently connected apps and the last synced catalog. If a tool is missing, connect the app and have the admin Sync catalog.

Use tools: [] to request a connection-management-only session for OAuth onboarding. This also requires approval. It cannot execute app tools. After connecting an app and syncing, search and request the actual tools you need.

The same flow through REST

1. Submit a request

curl https://gateway.example.com/api/sessions \
  -H "Authorization: Bearer $GATEWAY_MEMBER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"tools":["GITHUB_GET_REPOSITORY_CONTENT"],"reason":"Review repository files"}'

Returns HTTP 202 and a pending request, including request_id, tools, reason, created_at, and expires_at. No upstream execution session is created at this point.

2. Wait for admin review and check status

curl "https://gateway.example.com/api/session-requests/$REQUEST_ID" \
  -H "Authorization: Bearer $GATEWAY_MEMBER_TOKEN"

Statuses: pending, approved, rejected, expired, or issued. Members can inspect and collect only requests created with their own current credential. Checking status does not create a session. Poll at a reasonable interval, for example every five seconds.

3. Collect after approval

curl https://gateway.example.com/api/sessions \
  -H "Authorization: Bearer $GATEWAY_MEMBER_TOKEN" \
  -H 'Content-Type: application/json' \
  -d "{\"request_id\":\"$REQUEST_ID\"}"

Returns HTTP 201 with the connection details:

{
  "request_id": "<request-id>",
  "status": "issued",
  "tools": ["GITHUB_GET_REPOSITORY_CONTENT"],
  "token": "<gateway-session-token>",
  "token_type": "Bearer",
  "mode": "connected",
  "expires_at": "2026-09-12T22:00:00.000Z",
  "mcp": {
    "type": "http",
    "url": "https://gateway.example.com/mcp",
    "headers": { "Authorization": "Bearer <gateway-session-token>" }
  }
}

Collecting while pending returns HTTP 202 without credentials. Other non-approved states return their status without credentials. Tool lists, identity, and expiry cannot be overridden when collecting. Failed upstream creation leaves approval available to retry; simultaneous collections cannot issue multiple sessions.

Set PUBLIC_URL to return an absolute MCP URL; otherwise resolve /mcp against the gateway origin. Installing or renewing the client's execution connection is the client's responsibility.

Limits and invalidation

  • Request at most 100 tool slugs, with an optional reason of up to 1000 characters.

  • Each member can have at most 10 pending/approved requests and 10 unexpired sessions.

  • Requests must be approved and collected within 24 hours of submission. Approval does not extend this deadline. Recent request records are retained for 7 days, not as a permanent audit log.

  • Session lifetime starts at issuance: one hour by default, configurable from 60 seconds to 24 hours using SESSION_TTL_SECONDS.

  • A successful catalog refresh or project-key replacement revokes execution sessions and invalidates outstanding requests. Member revocation/rotation invalidates that member's sessions and outstanding requests. Stable-key restarts preserve valid requests and sessions.

  • Requests are checked against the member's connected apps both at submission and collection. If a requested tool becomes unavailable, collection fails without executing anything; reconnect or submit a revised request as appropriate.

  • Approving/rejecting one request does not revoke other sessions or change global permissions.

Manage active sessions

Members & sessions → Active sessions lists currently valid sessions, their members, expiry times, approved tools, and non-secret identifiers. Revoke session ends one session without disabling the member or their other sessions. Tokens are never displayed. Expired and revoked sessions are excluded; this is not an audit history.

Member-level Revoke disables the member and all their sessions. New credential revokes existing sessions and replaces the member token. A session can also delete itself:

curl -X DELETE https://gateway.example.com/mcp \
  -H "Authorization: Bearer $GATEWAY_SESSION_TOKEN"

Revocation aborts in-flight gateway requests and attempts upstream cleanup. Local revocation remains effective if Composio is unavailable. An action already accepted by Composio cannot be undone by revoking its session.

Railway and VPS configuration

Variable

Default

Purpose

HOST

127.0.0.1

Bind address

PORT

8788

HTTP port

DATA_DIR

Project data/

Persistent SQLite database and encryption key

PUBLIC_URL

Unset

Public HTTP(S) origin, without a path

SESSION_TTL_SECONDS

3600

Session lifetime, 60–86400 seconds

ADMIN_TOKEN

Unset

Required on fresh install; overrides persisted admin hash

COMPOSIO_API_TOKEN

Unset

Composio project API key; configures at startup and locks UI key edits

For Railway, attach a persistent volume at /app/data, set DATA_DIR=/app/data, set the project key and admin token as separate secrets, and set PUBLIC_URL to the public HTTPS origin. Redeploy to apply variables.

An environment-managed key hides the UI key-entry form and prevents /api/admin/config replacements. Manual refresh remains available. A changed key replaces the encrypted saved key, clears the previous catalog, and scans connected apps; a failed scan never falls back to the old project. An unchanged key preserves the catalog and sessions on restart, except for the one-time approval-flow upgrade described above. Blank, whitespace-containing, non-ASCII, or over-1000-character keys fail startup.

Removing the variable restores UI editability but retains the encrypted saved key. Removing the environment entry from the Node process does not erase Railway's variable store or historical snapshots. Environment variables do not replace persistent storage or connect apps for a member; OAuth belongs to their Composio user ID.

.env is not loaded automatically. Use node --env-file=.env server.mjs if you copy .env.example to .env. On a VPS, use an HTTPS reverse proxy. The gateway does not trust forwarded Host headers to construct session URLs.

docker build -t composio-gateway .
docker run -d --name composio-gateway --restart unless-stopped \
  -p 127.0.0.1:8788:8788 \
  -e PUBLIC_URL=https://gateway.example.com \
  -e ADMIN_TOKEN -e COMPOSIO_API_TOKEN \
  -v composio-gateway-data:/app/data \
  composio-gateway

Security and storage

The installed Composio SDK places the project key in upstream session headers. The gateway never returns that connection directly: it stores it encrypted and issues an opaque gateway token instead. Admin approval sees metadata, not bearer tokens or token hashes.

Composio receives explicit toolkit/tool allowlists. The gateway separately checks each direct tool call and every batch slug against the issued session's immutable approved list and current catalog. Sandbox, proxy execution, and arbitrary forwarding are disabled. Composio's fixed discovery/connection-management meta-tools remain available in execution sessions; batch execution can invoke only approved app tools. Connection-only sessions are restricted to connection-management tools.

Catalog refresh discovers ACTIVE connections for active gateway members and paginates each app using Composio's toolkit_slug filter. Results are filtered locally too. Apps connected only by unregistered/revoked users are excluded. Failed scans preserve the last committed catalog (except authoritative environment-key rotation, which clears old scope first). Scans, approval decisions, session issuance, and member mutations are serialized to prevent scope/authorization races.

Back up the complete data directory, including encryption.key. It contains request metadata, hashed credentials, and AES-256-GCM-encrypted upstream secrets. Keep it private: local encryption does not protect against an administrator who can read both the database and encryption key. Never put real tokens into tool arguments, request reasons, source control, or screenshots.

API summary

Endpoint

Credential

Behavior

GET /health

None

Process health

GET /api/admin/status

Admin

Connection and scan status

POST /api/admin/config

Admin

Set key when not environment-managed; scan

POST /api/admin/refresh

Admin

Rescan; invalidate sessions and outstanding requests on success

GET /api/admin/tools

Admin

Read-only scoped catalog

PUT /api/admin/policy

Admin

Retired; returns HTTP 410

GET /api/admin/session-requests

Admin

Recent requests, identities, tool lists, status

POST /api/admin/session-requests/:id/approve

Admin

Approve the exact pending tool set

POST /api/admin/session-requests/:id/reject

Admin

Reject a pending request

GET /api/admin/sessions

Admin

Active sessions, approved tools, and non-secret IDs

POST /api/admin/sessions/:id/revoke

Admin

Revoke one session

GET /api/admin/members

Admin

Member list without credentials

POST /api/admin/members

Admin

Create member; return credential once

POST /api/admin/members/:id/rotate

Admin

Replace credential and reactivate member

POST /api/admin/members/:id/revoke

Admin

Disable member and invalidate their access

POST /api/sessions

Member

Submit {tools, reason?} or collect {request_id}

GET /api/session-requests/:id

Member

Check own request; never issue credentials

POST /mcp

Member

Read-only discovery, submit/collect requests, check status

POST /mcp

Session

Restricted Streamable HTTP MCP execution

DELETE /mcp

Session

Revoke this session

Validation

npm ci
npx playwright install chromium
npm run check
npm test

For an existing Chromium installation, set PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH. Tests cover desktop/mobile approval and rejection, catalog discovery, exact allowlists, cross-member isolation, REST/MCP approval gates, retries/concurrency, migration, expiry, revocation, and the real SDK's serialization against a local fake server. They do not exercise a live Composio account. The interface is static HTML/CSS/JavaScript; no frontend build step is needed.

Reference: Composio session configuration, sessions via MCP.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    A least-privilege enforcement proxy for MCP servers. It sits between MCP clients and upstream servers, enforcing tool policies, hiding denied tools, requiring human approval for risky actions, and providing a structured audit trail.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A fail-closed policy boundary that translates local stdio MCP clients to authenticated Streamable HTTP servers, enforcing allowlists or read-only modes and redacting credentials from audit trails.
    Apache 2.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables clients to access multiple backend MCP servers through a single endpoint, with OAuth 2.1 authorization, namespaced tools, and secure credential management.
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables per-profile tool filtering and enforcement for one or more upstream MCP servers, exposing only allowed tools and rejecting blocked calls, with Streamable HTTP serving and observability.
    787,252 npm
    MIT