Skip to content

Repository files navigation

OutSystems LifeTime MCP Server

CI License: MIT Node.js TypeScript MCP

A local Model Context Protocol (MCP) server that exposes the OutSystems LifeTime REST API v2 as conversational tools.
Connect it to Claude Desktop (or any MCP-compatible client) and manage deployments, users, teams and applications through natural language.

Unofficial community project — not affiliated with or endorsed by OutSystems. It drives a powerful administrative API (it can create deployments, modify users, edit database connections and more). Read the Security section before using it.


Tools provided

66 tools across 10 domains, covering the LifeTime REST API v2:

Domain Tools Examples
Environments 10 get_environments, create_environment, set_maintenance_mode
Applications 7 get_applications, get_application_dependencies, tag_running_version
Deployments 7 create_deployment, execute_deployment_command, get_deployment_status
Users 7 list_users, create_user, update_user
Teams 7 list_teams, manage_team_users, manage_team_apps
Roles 6 list_roles, create_role, manage_user_app_role
Modules 4 list_modules, get_module_version
DB connections 12 list_db_connections, update_db_connection, test_db_connection
Configurations 3 get_application_configurations, update_application_configurations
Operations 3 cleanup_old_deployment_plans, get_application_consumers

Prerequisites

  • Docker (recommended) — no Node.js install required on the host
  • An OutSystems LifeTime instance (version 11)
  • A Service Account token — create one in LifeTime → User Management → Service Accounts

Docker setup (recommended)

1. Build the image

docker build -t outsystems-lifetime-mcp .

2. Smoke-test it

# Should print the FATAL env-var error and exit 1 — that means the binary works
docker run --rm outsystems-lifetime-mcp

3. Connect to Claude Desktop

Open (or create) the Claude Desktop config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add the server entry under "mcpServers":

{
  "mcpServers": {
    "outsystems-lifetime": {
      "command": "docker",
      "args": [
        "run", "--rm", "-i",
        "-e", "LIFETIME_BASE_URL",
        "-e", "LIFETIME_API_TOKEN",
        "outsystems-lifetime-mcp"
      ],
      "env": {
        "LIFETIME_BASE_URL": "https://your-lifetime.example.com/lifetimeapi/rest/v2",
        "LIFETIME_API_TOKEN": "your-service-account-token"
      }
    }
  }
}

The -i flag is required — it keeps stdin open so the MCP stdio protocol flows through Docker correctly.
The -e flags forward the env vars from the Claude Desktop process into the container.

  1. Restart Claude Desktop — the tools will appear in the tools panel.

Local Node.js setup (alternative, no Docker)

# Install dependencies and compile
npm install
npm run build

# Run
LIFETIME_BASE_URL="https://your-lifetime.example.com/lifetimeapi/rest/v2" \
LIFETIME_API_TOKEN="your-service-account-token" \
node dist/index.js

Claude Desktop config for the Node.js variant:

{
  "mcpServers": {
    "outsystems-lifetime": {
      "command": "node",
      "args": ["/ABSOLUTE/PATH/TO/outsystems-lifetime-mcp/dist/index.js"],
      "env": {
        "LIFETIME_BASE_URL": "https://your-lifetime.example.com/lifetimeapi/rest/v2",
        "LIFETIME_API_TOKEN": "your-service-account-token"
      }
    }
  }
}

Example deployment workflow (conversational)

You: What environments do I have?
Claude: [calls get_environments] → Development (key: abc-123), Quality (key: def-456), Production (key: ghi-789)

You: Deploy the latest version of "CustomerPortal" from Development to Quality.
Claude: [calls get_applications with IncludeEnvStatus=true]
        [calls create_deployment with source=abc-123, target=def-456, version key]
        [calls execute_deployment_command with command=start]
        Deployment started! DeploymentKey: xyz-000

You: How's the deployment going?
Claude: [calls get_deployment_status] → running — "Publishing CustomerPortal..."

You: Done yet?
Claude: [calls get_deployment_status] → finished_successful ✓

Error handling

The server propagates the LifeTime Errors array verbatim when an API call fails.
For example, a 403 response surfaces as:

{
  "errors": ["Invalid user permissions."],
  "statusCode": 403
}

This lets Claude explain exactly why an operation failed and suggest corrective actions.


Environment variables

Variable Required Description
LIFETIME_BASE_URL Full base URL of the LifeTime API, e.g. https://lt.example.com/lifetimeapi/rest/v2
LIFETIME_API_TOKEN Bearer token from a LifeTime Service Account

Project structure

src/
  index.ts            Entry point — env validation, server wiring, transport
  registry.ts         Tool registry: maps domains → tools + handlers
  types.ts            Shared composition types (ToolModule, HandlerMap)
  api-client.ts       Axios client with auth + LifeTime error extraction
  schemas.ts          Zod schemas for input validation
  tool-helpers.ts     Shared runTool wrapper & result type
  http-server.ts      Streamable HTTP transport (optional, for remote access)
  registry.test.ts    Registry integrity tests (node:test)
  tools/              One module per domain — environments, applications,
                      users, teams, deployments, roles, modules,
                      db-connections, configurations, operations
dist/                 Compiled output (after npm run build)
reference/            Vendored LifeTime REST API v2 Swagger spec (schema source)

Development

npm run typecheck   # type-check without emitting
npm test            # registry integrity tests (node:test)
npm run build       # compile to dist/

# Run directly with tsx (no compile step)
LIFETIME_BASE_URL=... LIFETIME_API_TOKEN=... npm run dev

Security

The enforced boundary is the LifeTime Service Account, not the AI. Per the OutSystems docs, a Service Account "follows the same permission model of regular user accounts, using roles and teams," and all API operations are limited to the permissions associated with that account, enforced by LifeTime server-side. The server can never perform an operation the account isn't granted, and it cannot escalate its own access. Scope the account, and you've scoped the tool.

  • Least privilege is the primary control. Create a dedicated Service Account and assign it a role scoped to exactly what you need — e.g. read-only, or only specific environments (application/deployment permissions are per-environment; DB-connection permissions are set at the environment level). Exclude user/role management if you don't need it. Whatever the role can't do, the AI can't do.
  • Audited & traceable. Every REST call is audited and traceable to the Service Account, viewable in its activity log in LifeTime. Nothing happens off the record.
  • Revocable tokens. Service Account tokens are time-bound (6/12/24 months) and can be invalidated instantly. Treat the token as a credential: keep it in .env (gitignored) or your client's secret store, never commit it, and rotate if exposed.
  • Lock down HTTP mode. The optional Streamable HTTP transport must run behind HTTP_BEARER_TOKEN; never expose an unauthenticated endpoint to a network or tunnel.
  • Prefer non-production first. Point it at a Development/Test LifeTime before trusting it against Production.

Several tools perform destructive or irreversible actions (e.g. create_deployment / execute_deployment_command, create_user / update_user, delete_role, update_db_connection, set_maintenance_mode) — the Service Account's role is what gates access to them.

A note on "human in the loop": most MCP clients prompt before running a tool, which is a useful extra layer — but it's a client-side setting (auto-approve disables it), not something this server enforces. Don't rely on it as your primary control; rely on the Service Account's scoped permissions, which are enforced server-side and audited.

No credentials are logged, and the server only talks to the LifeTime URL you configure.


Compatibility

  • OutSystems 11 (O11) self-managed / cloud, via the LifeTime REST API v2 (/lifetimeapi/rest/v2). Schemas were derived from the v2 Swagger spec in reference/.
  • Not for OutSystems Developer Cloud (ODC) — ODC has its own APIs and MCP tooling (see below).
  • Requires Node.js >= 18 (or Docker).

Related projects

The OutSystems MCP space is split between ODC (cloud) and LifeTime / O11 (self-managed). Most tooling targets ODC; this project focuses on LifeTime.

Project Target Approach
this project LifeTime / O11 Official REST API v2 — full read/write, 66 tools
OutSystems/outsystems-mcp ODC Official remote MCP
rpgomes-code/outsystems-mcp-extended ODC Community server wrapping ODC REST APIs

Not to be confused with the unrelated Forge component also named "MCP Server (O11)", which turns an O11 app into an MCP endpoint rather than managing LifeTime.


Contributing

See CONTRIBUTING.md for the dev workflow and how to add tools.


License

MIT © Paulo Ricardo Monteiro

About

MCP server exposing the OutSystems LifeTime REST API v2 as conversational tools — manage deployments, environments, users, teams, roles and applications (66 tools).

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages