# O11 Lt Mcp

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

- **Type:** MCP server
- **Install:** `agentstack add mcp-promonteiro89-o11-lt-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [promonteiro89](https://agentstack.voostack.com/s/promonteiro89)
- **Installs:** 0
- **Category:** [Cloud & Infrastructure](https://agentstack.voostack.com/c/cloud-infrastructure)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [promonteiro89](https://github.com/promonteiro89)
- **Source:** https://github.com/promonteiro89/o11-lt-mcp

## Install

```sh
agentstack add mcp-promonteiro89-o11-lt-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# OutSystems LifeTime MCP Server

[](https://github.com/promonteiro89/o11-lt-mcp/actions/workflows/ci.yml)
[](LICENSE)
[](https://nodejs.org)
[](https://www.typescriptlang.org)
[](https://modelcontextprotocol.io)

A local [Model Context Protocol](https://modelcontextprotocol.io) (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](#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

```bash
docker build -t outsystems-lifetime-mcp .
```

### 2. Smoke-test it

```bash
# 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"`:

```json
{
  "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.

4. **Restart Claude Desktop** — the tools will appear in the tools panel.

---

## Local Node.js setup (alternative, no Docker)

```bash
# 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:

```json
{
  "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:

```json
{
  "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

```bash
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](https://success.outsystems.com/Documentation/11_x_platform/Reference/OutSystems_APIs/LifeTime_API_v2/REST_API_Authentication),
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/`](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](https://github.com/OutSystems/outsystems-mcp) | ODC | Official remote MCP |
| [rpgomes-code/outsystems-mcp-extended](https://github.com/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](CONTRIBUTING.md) for the dev workflow and how to add tools.

---

## License

[MIT](LICENSE) © Paulo Ricardo Monteiro

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [promonteiro89](https://github.com/promonteiro89)
- **Source:** [promonteiro89/o11-lt-mcp](https://github.com/promonteiro89/o11-lt-mcp)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** yes
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-promonteiro89-o11-lt-mcp
- Seller: https://agentstack.voostack.com/s/promonteiro89
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
