#
tokens: 46991/50000 52/56 files (page 1/4)
lines: off (toggle) GitHub
raw markdown copy
This is page 1 of 4. Use http://codebase.md/stumason/coolify-mcp?lines=false&page={x} to view the full context.

# Directory Structure

```
├── .cursor
│   └── rules
│       ├── 000-cursor-rules.mdc
│       ├── 801-feature-workflow.mdc
│       ├── 802-coolify-mcp-workflow.mdc
│       └── 803-npm-publish-workflow.mdc
├── .eslintrc.json
├── .github
│   └── workflows
│       └── ci.yml
├── .gitignore
├── .lintstagedrc.json
├── .markdownlint-cli2.jsonc
├── .prettierrc
├── .repomixignore
├── debug.js
├── docs
│   ├── coolify-openapi.yaml
│   ├── features
│   │   ├── 001-core-server-setup.md
│   │   ├── 002-server-info-resource.md
│   │   ├── 003-project-management.md
│   │   ├── 004-environment-management.md
│   │   ├── 005-application-deployment.md
│   │   ├── 006-database-management.md
│   │   ├── 007-service-management.md
│   │   ├── 008-mcp-resources-implementation.md
│   │   ├── 009-mcp-prompts-implementation.md
│   │   ├── 010-private-key-management.md
│   │   ├── 011-team-management.md
│   │   ├── 012-backup-management.md
│   │   ├── 013-npx-config-fix.md
│   │   └── future-adrs.md
│   ├── mcp-example-clients.md
│   ├── mcp-js-readme.md
│   └── openapi-chunks
│       ├── applications-api.yaml
│       ├── databases-api.yaml
│       ├── deployments-api.yaml
│       ├── private-keys-api.yaml
│       ├── projects-api.yaml
│       ├── resources-api.yaml
│       ├── schemas.yaml
│       ├── servers-api.yaml
│       ├── services-api.yaml
│       ├── teams-api.yaml
│       └── untagged-api.yaml
├── jest.config.js
├── package-lock.json
├── package.json
├── README.md
├── repomix-output.xml
├── src
│   ├── __tests__
│   │   ├── coolify-client.test.ts
│   │   └── resources
│   │       ├── application-resources.test.ts
│   │       ├── database-resources.test.ts
│   │       ├── deployment-resources.test.ts
│   │       └── service-resources.test.ts
│   ├── index.ts
│   ├── lib
│   │   ├── coolify-client.ts
│   │   ├── mcp-server.ts
│   │   └── resource.ts
│   ├── resources
│   │   ├── application-resources.ts
│   │   ├── database-resources.ts
│   │   ├── deployment-resources.ts
│   │   ├── index.ts
│   │   └── service-resources.ts
│   └── types
│       └── coolify.ts
└── tsconfig.json
```

# Files

--------------------------------------------------------------------------------
/.repomixignore:
--------------------------------------------------------------------------------

```
.cursor/
.github/
.husky/
docs/
package-lock.json


```

--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------

```
{
  "semi": true,
  "trailingComma": "all",
  "singleQuote": true,
  "printWidth": 100,
  "tabWidth": 2
}

```

--------------------------------------------------------------------------------
/.lintstagedrc.json:
--------------------------------------------------------------------------------

```json
{
  "src/**/*.ts": ["eslint --fix", "prettier --write"],
  "*.json": ["prettier --write"],
  "*.md": ["prettier --write", "markdownlint-cli2"]
}

```

--------------------------------------------------------------------------------
/.markdownlint-cli2.jsonc:
--------------------------------------------------------------------------------

```
{
  "config": {
    "line-length": false,
    "no-duplicate-heading": false,
    "no-inline-html": false,
  },
  "ignores": ["node_modules", "dist"],
}

```

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
# Dependencies
node_modules/

# Build output
dist/
build/
/lib/
coverage/

# IDE and editor files
.idea/
.vscode/
*.swp
*.swo
.DS_Store
Thumbs.db

# Environment variables
.env
.env.local
.env.*.local

# Logs
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Test coverage
coverage/
.nyc_output/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity 
```

--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------

```json
{
  "env": {
    "node": true,
    "es2021": true
  },
  "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": ["@typescript-eslint"],
  "rules": {
    "@typescript-eslint/explicit-function-return-type": "warn",
    "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
    "@typescript-eslint/no-explicit-any": "warn"
  }
}

```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
# Coolify MCP Server

A Model Context Protocol (MCP) server implementation for [Coolify](https://coolify.io/), enabling AI assistants to interact with your Coolify instances through natural language.

## Example Prompts

Here are example prompts you can use with MCP-compatible AI assistants to interact with your Coolify instance:

### Server Management

```
# List and Inspect Servers
- Show me all Coolify servers in my instance
- What's the status of server {uuid}?
- Show me the resources running on server {uuid}
- What domains are configured for server {uuid}?
- Can you validate the connection to server {uuid}?

# Resource Monitoring
- How much CPU and memory is server {uuid} using?
- List all resources running on server {uuid}
- Show me the current status of all servers
```

### Project Management

```
# Project Operations
- List all my Coolify projects
- Create a new project called "my-webapp" with description "My web application"
- Show me the details of project {uuid}
- Update project {uuid} to change its name to "new-name"
- Delete project {uuid}

# Environment Management
- Show me the environments in project {uuid}
- Get details of the production environment in project {uuid}
- What variables are set in the staging environment of project {uuid}?
```

### Application and Service Management

```
# Application Management
- List all applications
- Show me details of application {uuid}
- Create a new application called "my-nodejs-app"
- Delete application {uuid}

# Service Operations
- Show me all running services
- Create a new WordPress service:
  - Name: my-blog
  - Project UUID: {project_uuid}
  - Server UUID: {server_uuid}
  - Type: wordpress-with-mysql
- What's the status of service {uuid}?
- Delete service {uuid} and clean up its resources
```

### Database Management

```
# Database Operations
- List all databases
- Show me the configuration of database {uuid}
- Update database {uuid}:
  - Increase memory limit to 1GB
  - Change public port to 5432
  - Update password
- Delete database {uuid} and clean up volumes

# Database Types
- Create a PostgreSQL database
- Set up a Redis instance
- Configure a MongoDB database
- Initialize a MySQL database
```

### Deployment Management

```
# Deployment Operations
- Show me all active deployments
- What's the status of deployment {uuid}?
- Deploy application {uuid}
- Force rebuild and deploy application {uuid}
- List recent deployments for application {uuid}
```

## Installation

### Prerequisites

- Node.js >= 18
- A running Coolify instance
- Coolify API access token

### Setup in AI Tools

#### Claude Desktop

```json
"coolify": {
    "command": "npx",
    "args": [
        "-y", "@masonator/coolify-mcp"
    ],
    "env": {
        "COOLIFY_ACCESS_TOKEN": "0|your-secret-token",
        "COOLIFY_BASE_URL": "https://your-coolify-instance.com"
    }
}
```

#### Cursor

```bash
env COOLIFY_ACCESS_TOKEN:0|your-secret-token COOLIFY_BASE_URL:https://your-coolify-instance.com npx -y @stumason/coolify-mcp
```

## Development

### Local Setup

```bash
# Clone the repository
git clone https://github.com/stumason/coolify-mcp.git
cd coolify-mcp

# Install dependencies
npm install

# Build the project
npm run build

# Run tests
npm test
```

### Environment Variables

```bash
# Required
COOLIFY_ACCESS_TOKEN=your_access_token_here

# Optional (defaults to http://localhost:3000)
COOLIFY_BASE_URL=https://your.coolify.instance
```

## API Reference

### Resource Types

#### Application

```typescript
interface Application {
  uuid: string;
  name: string;
  // Additional properties based on your Coolify instance
}
```

#### Service

```typescript
interface Service {
  id: number;
  uuid: string;
  name: string;
  type: ServiceType; // Various types like 'wordpress', 'mysql', etc.
  status: 'running' | 'stopped' | 'error';
  project_uuid: string;
  environment_uuid: string;
  server_uuid: string;
  domains?: string[];
}
```

#### Database

```typescript
interface Database {
  id: number;
  uuid: string;
  name: string;
  type: 'postgresql' | 'mysql' | 'mongodb' | 'redis' | /* other types */;
  status: 'running' | 'stopped' | 'error';
  is_public: boolean;
  public_port?: number;
  // Additional configuration based on database type
}
```

#### Deployment

```typescript
interface Deployment {
  id: number;
  uuid: string;
  application_uuid: string;
  status: string;
  created_at: string;
  updated_at: string;
}
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

## License

MIT

## Support

For support, please:

1. Check the [issues](https://github.com/stumason/coolify-mcp/issues) page
2. Create a new issue if needed
3. Join the Coolify community

```

--------------------------------------------------------------------------------
/docs/features/012-backup-management.md:
--------------------------------------------------------------------------------

```markdown

```

--------------------------------------------------------------------------------
/src/resources/index.ts:
--------------------------------------------------------------------------------

```typescript
export * from './database-resources.js';
export * from './deployment-resources.js';
export * from './application-resources.js';
export * from './service-resources.js';

```

--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------

```javascript
/** @type {import('ts-jest').JestConfigWithTsJest} */
export default {
  preset: 'ts-jest',
  testEnvironment: 'node',
  moduleNameMapper: {
    '^(\\.{1,2}/.*)\\.js$': '$1',
  },
  transform: {
    '^.+\\.tsx?$': [
      'ts-jest',
      {
        useESM: true,
      },
    ],
  },
  extensionsToTreatAsEsm: ['.ts'],
  testPathIgnorePatterns: ['/node_modules/', '/dist/', '\\.d\\.ts$'],
};

```

--------------------------------------------------------------------------------
/debug.js:
--------------------------------------------------------------------------------

```javascript
import { CoolifyMcpServer } from './dist/lib/mcp-server.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

// Enable debug logging
process.env.DEBUG = '*';

const server = new CoolifyMcpServer({
    baseUrl: 'https://coolify.dev',  // Replace with your actual Coolify URL
    accessToken: 'your-actual-token'   // Replace with your actual Coolify token
});

const transport = new StdioServerTransport();
await server.connect(transport); 
```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "declaration": true,
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "allowJs": true,
    "resolveJsonModule": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist", "tests"]
}

```

--------------------------------------------------------------------------------
/docs/openapi-chunks/resources-api.yaml:
--------------------------------------------------------------------------------

```yaml
openapi: 3.1.0
info:
  title: Coolify
  version: '0.1'
paths:
  /resources:
    get:
      tags:
        - Resources
      summary: List
      description: Get all resources.
      operationId: list-resources
      responses:
        '200':
          description: Get all resources
          content:
            application/json:
              schema:
                type: string
              example: Content is very complex. Will be implemented later.
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []

```

--------------------------------------------------------------------------------
/docs/features/001-core-server-setup.md:
--------------------------------------------------------------------------------

```markdown
# ADR 001: Core Server Setup

## Context

Need basic MCP server implementation that can authenticate with Coolify and handle basic operations.

## Implementation Checklist

- [x] Project structure setup

  - [x] TypeScript configuration
  - [x] ESLint + Prettier
  - [x] Jest/Vitest setup
  - [x] Basic GitHub Actions CI

- [x] Core MCP Server

  - [x] Basic server class implementation
  - [x] Environment configuration (COOLIFY_ACCESS_TOKEN, COOLIFY_BASE_URL)
  - [x] Coolify API client wrapper
  - [x] Error handling structure

- [x] Testing Infrastructure
  - [x] Mock Coolify API responses
  - [x] Basic integration test framework

## Dependencies

- None (This is our first implementation)

```

--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------

```yaml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x, 20.x]

    steps:
      - uses: actions/checkout@v4

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Security audit
        run: npm audit --audit-level=high

      - name: Format check
        run: npx prettier --check .

      - name: Lint
        run: npm run lint

      - name: Build
        run: npm run build

      - name: Test
        run: npm test

```

--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------

```typescript
#!/usr/bin/env node

import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CoolifyMcpServer } from './lib/mcp-server.js';
import { CoolifyConfig } from './types/coolify.js';

declare const process: NodeJS.Process;

async function main(): Promise<void> {
  const config: CoolifyConfig = {
    baseUrl: process.env.COOLIFY_BASE_URL || 'http://localhost:3000',
    accessToken: process.env.COOLIFY_ACCESS_TOKEN || '',
  };

  if (!config.accessToken) {
    throw new Error('COOLIFY_ACCESS_TOKEN environment variable is required');
  }

  const server = new CoolifyMcpServer(config);
  const transport = new StdioServerTransport();

  await server.connect(transport);
}

main().catch((error) => {
  console.error('Fatal error:', error);
  process.exit(1);
});

```

--------------------------------------------------------------------------------
/src/resources/deployment-resources.ts:
--------------------------------------------------------------------------------

```typescript
import { Resource } from '../lib/resource.js';
import { CoolifyClient } from '../lib/coolify-client.js';
import { Deployment } from '../types/coolify.js';

export class DeploymentResources {
  private client: CoolifyClient;

  constructor(client: CoolifyClient) {
    this.client = client;
  }

  @Resource('coolify/deployments/list')
  async listDeployments(): Promise<Deployment[]> {
    // TODO: Implement listDeployments in CoolifyClient
    throw new Error('Not implemented');
  }

  @Resource('coolify/deployments/{id}')
  async getDeployment(_id: string): Promise<Deployment> {
    // TODO: Implement getDeployment in CoolifyClient
    throw new Error('Not implemented');
  }

  @Resource('coolify/deploy')
  async deploy(params: { uuid: string; forceRebuild?: boolean }): Promise<Deployment> {
    return this.client.deployApplication(params.uuid);
  }
}

```

--------------------------------------------------------------------------------
/src/lib/resource.ts:
--------------------------------------------------------------------------------

```typescript
import 'reflect-metadata';

/**
 * Metadata key for storing the resource URI
 */
const RESOURCE_URI_KEY = Symbol('resourceUri');

/**
 * Decorator for marking methods as MCP resources.
 * @param uri The URI pattern for the resource
 */
export function Resource(uri: string): MethodDecorator {
  return function (
    target: object,
    propertyKey: string | symbol,
    descriptor: PropertyDescriptor,
  ): PropertyDescriptor {
    // Store the URI pattern in the method's metadata
    Reflect.defineMetadata(RESOURCE_URI_KEY, uri, target, propertyKey);
    return descriptor;
  };
}

/**
 * Get the resource URI for a decorated method
 * @param target The class instance or constructor
 * @param propertyKey The method name
 * @returns The resource URI or undefined if not a resource
 */
export function getResourceUri(target: object, propertyKey: string | symbol): string | undefined {
  return Reflect.getMetadata(RESOURCE_URI_KEY, target, propertyKey);
}

```

--------------------------------------------------------------------------------
/src/resources/service-resources.ts:
--------------------------------------------------------------------------------

```typescript
import { Resource } from '../lib/resource.js';
import { CoolifyClient } from '../lib/coolify-client.js';
import { Service, CreateServiceRequest, DeleteServiceOptions } from '../types/coolify.js';

export class ServiceResources {
  private client: CoolifyClient;

  constructor(client: CoolifyClient) {
    this.client = client;
  }

  @Resource('coolify/services/list')
  async listServices(): Promise<Service[]> {
    return this.client.listServices();
  }

  @Resource('coolify/services/{id}')
  async getService(id: string): Promise<Service> {
    return this.client.getService(id);
  }

  @Resource('coolify/services/create')
  async createService(data: CreateServiceRequest): Promise<{ uuid: string; domains: string[] }> {
    return this.client.createService(data);
  }

  @Resource('coolify/services/{id}/delete')
  async deleteService(id: string, options?: DeleteServiceOptions): Promise<{ message: string }> {
    return this.client.deleteService(id, options);
  }
}

```

--------------------------------------------------------------------------------
/docs/features/002-server-info-resource.md:
--------------------------------------------------------------------------------

```markdown
# ADR 002: Server Information Resources

## Context

First useful feature - ability to get server information and status through MCP resources.

## API Endpoints Used

- GET `/servers` (Line ~500)

  - Lists all servers
  - Response: Array of Server objects
  - Auth: Bearer token required

- GET `/servers/{uuid}` (Line ~550)

  - Get server details
  - Response: Server object with status
  - Auth: Bearer token required

- GET `/servers/{uuid}/status` (Line ~600)
  - Get server health and resource usage
  - Response: ServerStatus object
  - Auth: Bearer token required

## Implementation Checklist

- [x] Basic Resource Implementation

  - [x] Server info resource (resources://coolify/server/info)
    - [x] Basic server details
    - [x] Version information
  - [x] Server status resource (resources://coolify/server/status)
    - [x] Health check
    - [x] Resource usage

- [x] Resource Testing
  - [x] Unit tests for resource formatters
  - [x] Integration tests with mock data
  - [x] Live test with real Coolify instance

## Dependencies

- ADR 001 (Core Server Setup)

```

--------------------------------------------------------------------------------
/src/resources/database-resources.ts:
--------------------------------------------------------------------------------

```typescript
import { Resource } from '../lib/resource.js';
import { CoolifyClient } from '../lib/coolify-client.js';
import { Database, DatabaseUpdateRequest } from '../types/coolify.js';

export class DatabaseResources {
  private client: CoolifyClient;

  constructor(client: CoolifyClient) {
    this.client = client;
  }

  @Resource('coolify/databases/list')
  async listDatabases(): Promise<Database[]> {
    return this.client.listDatabases();
  }

  @Resource('coolify/databases/{id}')
  async getDatabase(id: string): Promise<Database> {
    return this.client.getDatabase(id);
  }

  @Resource('coolify/databases/{id}/update')
  async updateDatabase(id: string, data: DatabaseUpdateRequest): Promise<Database> {
    return this.client.updateDatabase(id, data);
  }

  @Resource('coolify/databases/{id}/delete')
  async deleteDatabase(
    id: string,
    options?: {
      deleteConfigurations?: boolean;
      deleteVolumes?: boolean;
      dockerCleanup?: boolean;
      deleteConnectedNetworks?: boolean;
    },
  ): Promise<{ message: string }> {
    return this.client.deleteDatabase(id, options);
  }
}

```

--------------------------------------------------------------------------------
/src/resources/application-resources.ts:
--------------------------------------------------------------------------------

```typescript
import { Resource } from '../lib/resource.js';
import { CoolifyClient } from '../lib/coolify-client.js';
import { Application, CreateApplicationRequest } from '../types/coolify.js';

export class ApplicationResources {
  private client: CoolifyClient;

  constructor(client: CoolifyClient) {
    this.client = client;
  }

  @Resource('coolify/applications/list')
  async listApplications(): Promise<Application[]> {
    // TODO: Implement listApplications in CoolifyClient
    throw new Error('Not implemented');
  }

  @Resource('coolify/applications/{id}')
  async getApplication(_id: string): Promise<Application> {
    // TODO: Implement getApplication in CoolifyClient
    throw new Error('Not implemented');
  }

  @Resource('coolify/applications/create')
  async createApplication(_data: CreateApplicationRequest): Promise<{ uuid: string }> {
    // TODO: Implement createApplication in CoolifyClient
    throw new Error('Not implemented');
  }

  @Resource('coolify/applications/{id}/delete')
  async deleteApplication(_id: string): Promise<{ message: string }> {
    // TODO: Implement deleteApplication in CoolifyClient
    throw new Error('Not implemented');
  }
}

```

--------------------------------------------------------------------------------
/src/__tests__/resources/application-resources.test.ts:
--------------------------------------------------------------------------------

```typescript
import { ApplicationResources } from '../../resources/application-resources.js';
import { CoolifyClient } from '../../lib/coolify-client.js';
import { jest } from '@jest/globals';

jest.mock('../../lib/coolify-client.js');

describe('ApplicationResources', () => {
  let resources: ApplicationResources;
  let mockClient: jest.Mocked<CoolifyClient>;

  beforeEach(() => {
    mockClient = {
      deployApplication: jest.fn(),
    } as unknown as jest.Mocked<CoolifyClient>;

    resources = new ApplicationResources(mockClient);
  });

  describe('listApplications', () => {
    it('should throw not implemented error', async () => {
      await expect(resources.listApplications()).rejects.toThrow('Not implemented');
    });
  });

  describe('getApplication', () => {
    it('should throw not implemented error', async () => {
      await expect(resources.getApplication('test-id')).rejects.toThrow('Not implemented');
    });
  });

  describe('createApplication', () => {
    it('should throw not implemented error', async () => {
      await expect(resources.createApplication({ name: 'test-app' })).rejects.toThrow(
        'Not implemented',
      );
    });
  });

  describe('deleteApplication', () => {
    it('should throw not implemented error', async () => {
      await expect(resources.deleteApplication('test-id')).rejects.toThrow('Not implemented');
    });
  });
});

```

--------------------------------------------------------------------------------
/docs/features/011-team-management.md:
--------------------------------------------------------------------------------

```markdown
# ADR 011: Team Management

## Context

Implementation of team management features through MCP resources, allowing users to manage teams and team members in Coolify.

## API Endpoints Used

- GET `/teams` (List)

  - Lists all teams
  - Response: Array of Team objects
  - Auth: Bearer token required

- GET `/teams/{id}` (Get)

  - Get team details by ID
  - Response: Team object
  - Auth: Bearer token required

- GET `/teams/{id}/members` (List Members)

  - Get team members by team ID
  - Response: Array of User objects
  - Auth: Bearer token required

- GET `/teams/current` (Get Current)

  - Get currently authenticated team
  - Response: Team object
  - Auth: Bearer token required

- GET `/teams/current/members` (Get Current Members)
  - Get currently authenticated team members
  - Response: Array of User objects
  - Auth: Bearer token required

## Implementation Checklist

- [ ] Basic Team Management

  - [ ] List teams resource
  - [ ] Get team details
  - [ ] List team members
  - [ ] Get current team
  - [ ] Get current team members

- [ ] Team Features

  - [ ] Team information display
  - [ ] Member list management
  - [ ] Team permissions handling
  - [ ] Current team context

- [ ] Resource Testing
  - [ ] Unit tests for team operations
  - [ ] Integration tests with mock data
  - [ ] Live test with real Coolify instance
  - [ ] Permission testing

## Dependencies

- ADR 001 (Core Server Setup)
- ADR 002 (Server Information Resources)

```

--------------------------------------------------------------------------------
/docs/features/003-project-management.md:
--------------------------------------------------------------------------------

```markdown
# ADR 003: Project Management

## Context

Basic project management functionality - first interactive feature allowing users to create and manage projects.

## API Endpoints Used

- GET `/projects` (Line ~800)

  - Lists all projects
  - Response: Array of Project objects
  - Auth: Bearer token required

- POST `/projects` (Line ~850)

  - Create new project
  - Request body: { name: string, description?: string }
  - Response: Project object
  - Auth: Bearer token required

- GET `/projects/{uuid}` (Line ~900)

  - Get project details
  - Response: Project object with relationships
  - Auth: Bearer token required

- DELETE `/projects/{uuid}` (Line ~950)

  - Delete project
  - Response: 204 No Content
  - Auth: Bearer token required

- PUT `/projects/{uuid}` (Line ~1000)
  - Update project
  - Request body: { name?: string, description?: string }
  - Response: Updated Project object
  - Auth: Bearer token required

## Implementation Checklist

- [x] Project List Resource

  - [x] resources://coolify/projects/list implementation
  - [x] Pagination support
  - [x] Basic filtering

- [x] Project Management Tools

  - [x] createProject tool
  - [x] deleteProject tool
  - [x] updateProject tool

- [x] Project Detail Resource

  - [x] resources://coolify/projects/{id} implementation
  - [x] Project status and configuration

- [x] Testing
  - [x] CRUD operation tests
  - [x] Error handling tests
  - [x] Resource format tests

## Dependencies

- ADR 001 (Core Server Setup)
- ADR 002 (Server Information Resources)

```

--------------------------------------------------------------------------------
/docs/features/010-private-key-management.md:
--------------------------------------------------------------------------------

```markdown
# ADR 010: Private Key Management

## Context

Implementation of private key management features through MCP resources, allowing users to manage SSH keys for server access and deployment.

## API Endpoints Used

- GET `/security/keys` (List)

  - Lists all private keys
  - Response: Array of PrivateKey objects
  - Auth: Bearer token required

- POST `/security/keys` (Create)

  - Create a new private key
  - Required fields:
    - private_key
  - Optional fields:
    - name
    - description
  - Response: { uuid: string }
  - Auth: Bearer token required

- GET `/security/keys/{uuid}` (Get)

  - Get private key details
  - Response: PrivateKey object
  - Auth: Bearer token required

- PATCH `/security/keys` (Update)

  - Update a private key
  - Required fields:
    - private_key
  - Optional fields:
    - name
    - description
  - Response: { uuid: string }
  - Auth: Bearer token required

- DELETE `/security/keys/{uuid}` (Delete)
  - Delete a private key
  - Response: { message: string }
  - Auth: Bearer token required

## Implementation Checklist

- [ ] Basic Key Management

  - [ ] List private keys resource
  - [ ] Get private key details
  - [ ] Create private key
  - [ ] Update private key
  - [ ] Delete private key

- [ ] Security Features

  - [ ] Secure key storage
  - [ ] Key validation
  - [ ] Usage tracking
  - [ ] Access control

- [ ] Resource Testing
  - [ ] Unit tests for key operations
  - [ ] Integration tests with mock data
  - [ ] Live test with real Coolify instance
  - [ ] Security testing

## Dependencies

- ADR 001 (Core Server Setup)
- ADR 002 (Server Information Resources)

```

--------------------------------------------------------------------------------
/docs/features/004-environment-management.md:
--------------------------------------------------------------------------------

```markdown
# ADR 004: Environment Management

## Context

Environment management within projects - allows retrieving environment information and deploying applications within environments.

## API Endpoints Used

- GET `/projects/{uuid}/{environment_name_or_uuid}`

  - Get environment details by project UUID and environment name/UUID
  - Response: Environment object
  - Auth: Bearer token required

- POST `/applications/{uuid}/deploy`
  - Deploy an application using its UUID
  - Response: Deployment object
  - Auth: Bearer token required

Note: Environment creation and management is handled through the Projects API. Environments are created and configured as part of project setup.

## Implementation Status

### Completed

- [x] Environment Detail Resource

  - [x] GET project environment endpoint implemented
  - [x] Client method: `getProjectEnvironment`
  - [x] MCP tool: `get_project_environment`

- [x] Application Deployment
  - [x] Deploy application endpoint implemented
  - [x] Client method: `deployApplication`
  - [x] MCP tool: `deploy_application`

### Environment Schema

```typescript
interface Environment {
  id: number;
  name: string;
  project_id: number;
  created_at: string;
  updated_at: string;
  description: string;
}
```

## Dependencies

- ADR 001 (Core Server Setup)
- ADR 003 (Project Management)

## Notes

- Environment management is tightly coupled with projects in the Coolify API
- Environment variables are managed at the application level during application creation/updates
- Direct environment CRUD operations are not available through dedicated endpoints
- Environment information can be retrieved through the project endpoints

```

--------------------------------------------------------------------------------
/docs/features/006-database-management.md:
--------------------------------------------------------------------------------

```markdown
# ADR 006: Database Management

## Context

Implementation of database management features through MCP resources, allowing users to manage various types of databases (PostgreSQL, MySQL, MariaDB, MongoDB, Redis, etc.).

## API Endpoints Used

- GET `/databases` (List)

  - Lists all databases
  - Response: Array of Database objects
  - Auth: Bearer token required

- GET `/databases/{uuid}` (Get)

  - Get database details
  - Response: Database object
  - Auth: Bearer token required

- DELETE `/databases/{uuid}` (Delete)

  - Delete database
  - Optional query params:
    - delete_configurations (boolean, default: true)
    - delete_volumes (boolean, default: true)
    - docker_cleanup (boolean, default: true)
    - delete_connected_networks (boolean, default: true)
  - Auth: Bearer token required

- PATCH `/databases/{uuid}` (Update)
  - Update database configuration
  - Supports various database types:
    - PostgreSQL
    - MariaDB
    - MySQL
    - MongoDB
    - Redis
    - KeyDB
    - Clickhouse
    - Dragonfly

## Implementation Checklist

- [x] Basic Database Management

  - [x] List databases resource
  - [x] Get database details
  - [x] Delete database
  - [x] Update database configuration

- [x] Database Type Support

  - [x] PostgreSQL configuration
  - [x] MariaDB configuration
  - [x] MySQL configuration
  - [x] MongoDB configuration
  - [x] Redis configuration
  - [x] KeyDB configuration
  - [x] Clickhouse configuration
  - [x] Dragonfly configuration

- [x] Resource Testing
  - [x] Unit tests for database operations
  - [x] Integration tests with mock data
  - [x] Live test with real Coolify instance

## Dependencies

- ADR 001 (Core Server Setup)
- ADR 002 (Server Information Resources)

```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "@masonator/coolify-mcp",
  "scope": "@masonator",
  "version": "0.2.8",
  "description": "MCP server implementation for Coolify",
  "type": "module",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.cjs",
      "types": "./dist/index.d.ts"
    }
  },
  "bin": {
    "coolify-mcp": "dist/index.js"
  },
  "files": [
    "dist"
  ],
  "scripts": {
    "build": "tsc && shx chmod +x dist/*.js",
    "dev": "tsc --watch",
    "test": "NODE_OPTIONS=--experimental-vm-modules jest",
    "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch",
    "test:coverage": "NODE_OPTIONS=--experimental-vm-modules jest --coverage",
    "lint": "eslint . --ext .ts",
    "lint:fix": "eslint . --ext .ts --fix",
    "format": "prettier --write .",
    "format:check": "prettier --check .",
    "prepare": "husky",
    "prepublishOnly": "npm test && npm run lint",
    "start": "node dist/index.js"
  },
  "keywords": [
    "coolify",
    "mcp",
    "model-context-protocol"
  ],
  "author": "Stuart Mason",
  "license": "MIT",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.6.1",
    "reflect-metadata": "^0.2.2",
    "zod": "^3.24.2"
  },
  "devDependencies": {
    "@types/debug": "^4.1.12",
    "@types/jest": "^29.5.14",
    "@types/node": "^20.17.23",
    "@typescript-eslint/eslint-plugin": "^7.18.0",
    "@typescript-eslint/parser": "^7.18.0",
    "eslint": "^8.56.0",
    "eslint-config-prettier": "^9.1.0",
    "husky": "^9.0.11",
    "jest": "^29.7.0",
    "lint-staged": "^15.2.2",
    "markdownlint-cli2": "^0.12.1",
    "prettier": "^3.5.3",
    "shx": "^0.3.4",
    "ts-jest": "^29.2.6",
    "typescript": "^5.8.2"
  },
  "engines": {
    "node": ">=18"
  }
}

```

--------------------------------------------------------------------------------
/docs/features/009-mcp-prompts-implementation.md:
--------------------------------------------------------------------------------

```markdown
# ADR 009: MCP Prompts Implementation

## Context

Create reusable prompt templates for common Coolify workflows to make interactions more efficient.

## Implementation Checklist

- [ ] Deployment Prompts

  - [ ] "deploy-application" prompt
    ```typescript
    {
      applicationId: string,
      version?: string,
      environment?: string
    }
    ```
  - [ ] "rollback-deployment" prompt
    ```typescript
    {
      applicationId: string,
      deploymentId: string
    }
    ```

- [ ] Configuration Prompts

  - [ ] "configure-database" prompt
    ```typescript
    {
      databaseId: string,
      settings: DatabaseSettings
    }
    ```
  - [ ] "configure-environment" prompt
    ```typescript
    {
      environmentId: string,
      variables: Record<string, string>
    }
    ```

- [ ] Service Management Prompts

  - [ ] "setup-service" prompt
    ```typescript
    {
      environmentId: string,
      serviceType: string,
      configuration: ServiceConfig
    }
    ```
  - [ ] "troubleshoot-service" prompt
    ```typescript
    {
      serviceId: string,
      issueType?: "connectivity" | "performance" | "logs"
    }
    ```

- [ ] Resource Management Prompts

  - [ ] "optimize-resources" prompt
    ```typescript
    {
      resourceId: string,
      resourceType: "application" | "service" | "database"
    }
    ```
  - [ ] "backup-management" prompt
    ```typescript
    {
      resourceId: string,
      operation: "create" | "restore" | "list"
    }
    ```

- [ ] Testing
  - [ ] Prompt validation tests
  - [ ] Response formatting tests
  - [ ] Error handling tests
  - [ ] Integration tests with actual commands

## Dependencies

- ADR 001 (Core Server Setup)
- ADR 005 (Application Deployment)
- ADR 006 (Database Management)
- ADR 007 (Service Management)
- ADR 008 (MCP Resources Implementation)

```

--------------------------------------------------------------------------------
/src/__tests__/resources/deployment-resources.test.ts:
--------------------------------------------------------------------------------

```typescript
import { DeploymentResources } from '../../resources/deployment-resources.js';
import { CoolifyClient } from '../../lib/coolify-client.js';
import { jest } from '@jest/globals';

jest.mock('../../lib/coolify-client.js');

describe('DeploymentResources', () => {
  let mockClient: jest.Mocked<CoolifyClient>;
  let resources: DeploymentResources;
  const mockDeployment = {
    id: 1,
    uuid: 'test-uuid',
    status: 'running',
    created_at: '2024-01-01',
    updated_at: '2024-01-01',
    application_uuid: 'app-uuid',
    environment_uuid: 'env-uuid',
  };

  beforeEach(() => {
    mockClient = {
      deployApplication: jest.fn(),
    } as unknown as jest.Mocked<CoolifyClient>;
    resources = new DeploymentResources(mockClient);
  });

  describe('listDeployments', () => {
    it('should throw not implemented error', async () => {
      await expect(resources.listDeployments()).rejects.toThrow('Not implemented');
    });
  });

  describe('getDeployment', () => {
    it('should throw not implemented error', async () => {
      await expect(resources.getDeployment('test-id')).rejects.toThrow('Not implemented');
    });
  });

  describe('deploy', () => {
    it('should deploy an application', async () => {
      mockClient.deployApplication.mockResolvedValue(mockDeployment);

      const result = await resources.deploy({ uuid: 'test-uuid' });

      expect(result).toEqual(mockDeployment);
      expect(mockClient.deployApplication).toHaveBeenCalledWith('test-uuid');
    });

    it('should handle deployment errors', async () => {
      const error = new Error('Deployment failed');
      mockClient.deployApplication.mockRejectedValue(error);

      await expect(resources.deploy({ uuid: 'test-uuid' })).rejects.toThrow('Deployment failed');
      expect(mockClient.deployApplication).toHaveBeenCalledWith('test-uuid');
    });
  });
});

```

--------------------------------------------------------------------------------
/docs/features/005-application-deployment.md:
--------------------------------------------------------------------------------

```markdown
# ADR 005: Application Deployment

## Context

Core application deployment functionality - allows deploying and managing applications within environments.

## API Endpoints Used

- GET `/applications` (Line 10)

  - Lists all applications
  - Query params: environment_uuid (optional)
  - Response: Array of Application objects
  - Auth: Bearer token required
  - ✅ Implemented

- POST `/applications/public` (Line 31)

  - Create new application from public repository
  - Request body: {
    project_uuid: string,
    environment_uuid: string,
    git_repository: string,
    git_branch: string,
    build_pack: "nixpacks" | "static" | "dockerfile" | "dockercompose",
    ports_exposes: string,
    name?: string,
    ...additional configuration
    }
  - Response: Application object
  - Auth: Bearer token required
  - ✅ Implemented

- GET `/applications/{uuid}` (Line ~1600)

  - Get application details
  - Response: Application object with status
  - Auth: Bearer token required
  - ✅ Implemented

- DELETE `/applications/{uuid}` (Line ~1650)

  - Delete application
  - Response: 204 No Content
  - Auth: Bearer token required
  - ✅ Implemented

- POST `/applications/{uuid}/deploy` (Line ~1700)

  - Trigger application deployment
  - Response: Deployment object
  - Auth: Bearer token required
  - ✅ Implemented

## Implementation Checklist

- [x] Application List Resource

  - [x] resources://coolify/applications/list
  - [x] Filter by environment/project
  - [x] Status information

- [x] Application Management Tools

  - [x] createApplication tool
  - [x] deployApplication tool
  - [x] configureApplication tool
  - [x] deleteApplication tool

- [x] Application Monitoring

  - [x] resources://coolify/applications/{id}/status
  - [x] Basic metrics

- [x] Testing
  - [x] Deployment workflow tests
  - [x] Configuration management tests

## Dependencies

- ADR 001 (Core Server Setup)
- ADR 004 (Environment Management)

```

--------------------------------------------------------------------------------
/docs/features/future-adrs.md:
--------------------------------------------------------------------------------

```markdown
# Future ADR Considerations

Based on available Coolify API endpoints, here are potential future features to implement:

## Deployment Management

- Webhook integration for GitHub, GitLab, Bitbucket, Gitea

  - POST `/webhooks/github/{uuid}` (Line ~4000)
  - POST `/webhooks/gitlab/{uuid}` (Line ~4050)
  - POST `/webhooks/bitbucket/{uuid}` (Line ~4100)
  - POST `/webhooks/gitea/{uuid}` (Line ~4150)

- Build pack support

  - POST `/applications/{uuid}/buildpack` (Line ~4200)
  - GET `/buildpacks/templates` (Line ~4250)

- Custom deployment commands
  - POST `/applications/{uuid}/commands/pre-deploy` (Line ~4300)
  - POST `/applications/{uuid}/commands/post-deploy` (Line ~4350)

## Resource Management

- Resource limits management

  - PUT `/applications/{uuid}/limits` (Line ~4400)
  - PUT `/services/{uuid}/limits` (Line ~4450)
  - GET `/resources/usage` (Line ~4500)

- Health check configuration
  - PUT `/applications/{uuid}/health` (Line ~4550)
  - GET `/applications/{uuid}/health/status` (Line ~4600)

## Network Management

- Domain management

  - POST `/domains` (Line ~4650)
  - GET `/domains/{uuid}/verify` (Line ~4700)
  - PUT `/domains/{uuid}/ssl` (Line ~4750)

- SSL/TLS configuration
  - POST `/certificates` (Line ~4800)
  - GET `/certificates/{uuid}/status` (Line ~4850)

## Build Management

- Build server configuration
  - POST `/build-servers` (Line ~4900)
  - GET `/build-servers/{uuid}/status` (Line ~4950)
  - PUT `/build-servers/{uuid}/cache` (Line ~5000)

## Team Management

- Team member management

  - POST `/teams` (Line ~5050)
  - POST `/teams/{uuid}/members` (Line ~5100)
  - PUT `/teams/{uuid}/permissions` (Line ~5150)

- API key management
  - POST `/api-keys` (Line ~5200)
  - GET `/api-keys/{uuid}/usage` (Line ~5250)

## Monitoring and Logging

- Resource usage monitoring

  - GET `/monitoring/resources` (Line ~5300)
  - GET `/monitoring/alerts` (Line ~5350)

- Centralized logging
  - GET `/logs/aggregate` (Line ~5400)
  - POST `/logs/search` (Line ~5450)

Each of these could be developed into full ADRs once the core functionality is stable. The line numbers reference the OpenAPI specification for implementation details.

```

--------------------------------------------------------------------------------
/docs/features/007-service-management.md:
--------------------------------------------------------------------------------

```markdown
# ADR 007: Service Management

## Context

Implementation of one-click service management features through MCP resources, allowing users to deploy and manage various pre-configured services.

## API Endpoints Used

- GET `/services` (List)

  - Lists all services
  - Response: Array of Service objects
  - Auth: Bearer token required

- POST `/services` (Create)

  - Create a one-click service
  - Required fields:
    - server_uuid
    - project_uuid
    - environment_name/uuid
    - type (one of many supported service types)
  - Optional fields:
    - name
    - description
    - destination_uuid
    - instant_deploy
  - Auth: Bearer token required

- GET `/services/{uuid}` (Get)

  - Get service details
  - Response: Service object
  - Auth: Bearer token required

- DELETE `/services/{uuid}` (Delete)
  - Delete service
  - Optional query params:
    - delete_configurations (boolean, default: true)
    - delete_volumes (boolean, default: true)
    - docker_cleanup (boolean, default: true)
    - delete_connected_networks (boolean, default: true)
  - Auth: Bearer token required

## Supported Service Types

- Development Tools:

  - code-server
  - gitea (with various DB options)
  - docker-registry

- CMS & Documentation:

  - wordpress (with various DB options)
  - ghost
  - mediawiki
  - dokuwiki

- Monitoring & Analytics:

  - grafana
  - umami
  - glances
  - uptime-kuma

- Collaboration & Communication:

  - rocketchat
  - chatwoot
  - nextcloud

- Database Management:

  - phpmyadmin
  - nocodb
  - directus

- And many more specialized services

## Implementation Checklist

- [x] Basic Service Management

  - [x] List services resource
  - [x] Get service details
  - [x] Create service
  - [x] Delete service

- [x] Service Type Support

  - [x] Development tools deployment
  - [x] CMS system deployment
  - [x] Monitoring tools deployment
  - [x] Collaboration tools deployment
  - [x] Database tools deployment

- [x] Resource Testing
  - [x] Unit tests for service operations
  - [x] Integration tests with mock data
  - [x] Live test with real Coolify instance

## Dependencies

- ADR 001 (Core Server Setup)
- ADR 002 (Server Information Resources)
- ADR 003 (Project Management)

```

--------------------------------------------------------------------------------
/docs/features/008-mcp-resources-implementation.md:
--------------------------------------------------------------------------------

```markdown
# ADR 008: MCP Resources Implementation

## Context

Implement MCP resources for managing Coolify entities through the available API endpoints.

## API Endpoints Used

- Database Management:

  - GET `/databases` - List databases
  - GET `/databases/{uuid}` - Get database details
  - POST `/databases/{type}` - Create database
  - PATCH `/databases/{uuid}` - Update database
  - DELETE `/databases/{uuid}` - Delete database

- Deployment Management:

  - GET `/deployments` - List deployments
  - GET `/deployments/{uuid}` - Get deployment details
  - GET `/deploy` - Deploy by tag or uuid

- Application Management:

  - GET `/applications` - List applications
  - GET `/applications/{uuid}` - Get application details
  - POST `/applications/public` - Create public application
  - DELETE `/applications/{uuid}` - Delete application

- Service Management:
  - GET `/services` - List services
  - GET `/services/{uuid}` - Get service details
  - POST `/services` - Create service
  - DELETE `/services/{uuid}` - Delete service

## Implementation Checklist

- [ ] Database Resources

  - [ ] resources://coolify/databases/list
  - [ ] resources://coolify/databases/{id}
  - [ ] resources://coolify/databases/create/{type}
  - [ ] resources://coolify/databases/{id}/update
  - [ ] resources://coolify/databases/{id}/delete

- [ ] Deployment Resources

  - [ ] resources://coolify/deployments/list
  - [ ] resources://coolify/deployments/{id}
  - [ ] resources://coolify/deploy
    - Support for tag-based deployment
    - Support for UUID-based deployment
    - Force rebuild option

- [ ] Application Resources

  - [ ] resources://coolify/applications/list
  - [ ] resources://coolify/applications/{id}
  - [ ] resources://coolify/applications/create
  - [ ] resources://coolify/applications/{id}/delete

- [ ] Service Resources

  - [ ] resources://coolify/services/list
  - [ ] resources://coolify/services/{id}
  - [ ] resources://coolify/services/create
  - [ ] resources://coolify/services/{id}/delete

- [ ] Testing
  - [ ] Database operation tests
  - [ ] Deployment operation tests
  - [ ] Application operation tests
  - [ ] Service operation tests
  - [ ] Error handling tests
  - [ ] Permission validation tests

## Dependencies

- ADR 001 (Core Server Setup)
- ADR 005 (Application Deployment)
- ADR 006 (Database Management)
- ADR 007 (Service Management)

```

--------------------------------------------------------------------------------
/src/__tests__/resources/database-resources.test.ts:
--------------------------------------------------------------------------------

```typescript
import { DatabaseResources } from '../../resources/database-resources.js';
import { CoolifyClient } from '../../lib/coolify-client.js';
import { PostgresDatabase } from '../../types/coolify.js';
import { jest } from '@jest/globals';

jest.mock('../../lib/coolify-client.js');

describe('DatabaseResources', () => {
  let mockClient: jest.Mocked<CoolifyClient>;
  let resources: DatabaseResources;
  const mockDatabase: PostgresDatabase = {
    id: 1,
    uuid: 'test-uuid',
    name: 'test-db',
    description: 'test description',
    type: 'postgresql',
    status: 'running',
    created_at: '2024-01-01',
    updated_at: '2024-01-01',
    is_public: false,
    image: 'postgres:latest',
    postgres_user: 'test',
    postgres_password: 'test',
    postgres_db: 'test',
  };

  beforeEach(() => {
    mockClient = {
      listDatabases: jest.fn(),
      getDatabase: jest.fn(),
      updateDatabase: jest.fn(),
      deleteDatabase: jest.fn(),
    } as unknown as jest.Mocked<CoolifyClient>;
    resources = new DatabaseResources(mockClient);
  });

  describe('listDatabases', () => {
    it('should return a list of databases', async () => {
      mockClient.listDatabases.mockResolvedValue([mockDatabase]);

      const result = await resources.listDatabases();

      expect(result).toEqual([mockDatabase]);
      expect(mockClient.listDatabases).toHaveBeenCalled();
    });
  });

  describe('getDatabase', () => {
    it('should return a database by uuid', async () => {
      mockClient.getDatabase.mockResolvedValue(mockDatabase);

      const result = await resources.getDatabase('test-uuid');

      expect(result).toEqual(mockDatabase);
      expect(mockClient.getDatabase).toHaveBeenCalledWith('test-uuid');
    });
  });

  describe('updateDatabase', () => {
    it('should update a database', async () => {
      const updateData = {
        name: 'updated-db',
        description: 'updated description',
      };

      mockClient.updateDatabase.mockResolvedValue({ ...mockDatabase, ...updateData });

      const result = await resources.updateDatabase('test-uuid', updateData);

      expect(result).toEqual({ ...mockDatabase, ...updateData });
      expect(mockClient.updateDatabase).toHaveBeenCalledWith('test-uuid', updateData);
    });
  });

  describe('deleteDatabase', () => {
    it('should delete a database', async () => {
      const mockResponse = { message: 'Database deleted successfully' };
      mockClient.deleteDatabase.mockResolvedValue(mockResponse);

      const result = await resources.deleteDatabase('test-uuid', {});

      expect(result).toEqual(mockResponse);
      expect(mockClient.deleteDatabase).toHaveBeenCalledWith('test-uuid', {});
    });
  });
});

```

--------------------------------------------------------------------------------
/docs/openapi-chunks/untagged-api.yaml:
--------------------------------------------------------------------------------

```yaml
openapi: 3.1.0
info:
  title: Coolify
  version: '0.1'
paths:
  /version:
    get:
      summary: Version
      description: Get Coolify version.
      operationId: version
      responses:
        '200':
          description: Returns the version of the application
          content:
            application/json:
              schema:
                type: string
              example: v4.0.0
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /enable:
    get:
      summary: Enable API
      description: Enable API (only with root permissions).
      operationId: enable-api
      responses:
        '200':
          description: Enable API.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: API enabled.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '403':
          description: You are not allowed to enable the API.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: You are not allowed to enable the API.
                type: object
      security:
        - bearerAuth: []
  /disable:
    get:
      summary: Disable API
      description: Disable API (only with root permissions).
      operationId: disable-api
      responses:
        '200':
          description: Disable API.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: API disabled.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '403':
          description: You are not allowed to disable the API.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: You are not allowed to disable the API.
                type: object
      security:
        - bearerAuth: []
  /health:
    get:
      summary: Healthcheck
      description: Healthcheck endpoint.
      operationId: healthcheck
      responses:
        '200':
          description: Healthcheck endpoint.
          content:
            application/json:
              schema:
                type: string
              example: OK
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'

```

--------------------------------------------------------------------------------
/src/__tests__/resources/service-resources.test.ts:
--------------------------------------------------------------------------------

```typescript
import { ServiceResources } from '../../resources/service-resources.js';
import { CoolifyClient } from '../../lib/coolify-client.js';
import { Service, ServiceType } from '../../types/coolify.js';
import { jest } from '@jest/globals';

jest.mock('../../lib/coolify-client.js');

describe('ServiceResources', () => {
  let mockClient: jest.Mocked<CoolifyClient>;
  let resources: ServiceResources;
  const mockService: Service = {
    id: 1,
    uuid: 'test-uuid',
    name: 'test-service',
    description: 'test description',
    type: 'code-server',
    status: 'running',
    created_at: '2024-01-01',
    updated_at: '2024-01-01',
    project_uuid: 'project-uuid',
    environment_name: 'test-env',
    environment_uuid: 'env-uuid',
    server_uuid: 'server-uuid',
    domains: ['test.com'],
  };

  beforeEach(() => {
    mockClient = {
      listServices: jest.fn(),
      getService: jest.fn(),
      createService: jest.fn(),
      deleteService: jest.fn(),
    } as unknown as jest.Mocked<CoolifyClient>;
    resources = new ServiceResources(mockClient);
  });

  describe('listServices', () => {
    it('should return a list of services', async () => {
      mockClient.listServices.mockResolvedValue([mockService]);

      const result = await resources.listServices();

      expect(result).toEqual([mockService]);
      expect(mockClient.listServices).toHaveBeenCalled();
    });
  });

  describe('getService', () => {
    it('should return a service by uuid', async () => {
      mockClient.getService.mockResolvedValue(mockService);

      const result = await resources.getService('test-uuid');

      expect(result).toEqual(mockService);
      expect(mockClient.getService).toHaveBeenCalledWith('test-uuid');
    });
  });

  describe('createService', () => {
    it('should create a new service', async () => {
      const createData = {
        name: 'new-service',
        type: 'code-server' as ServiceType,
        project_uuid: 'project-uuid',
        environment_name: 'test-env',
        environment_uuid: 'env-uuid',
        server_uuid: 'server-uuid',
      };

      const mockResponse = {
        uuid: 'new-uuid',
        domains: ['new-service.test.com'],
      };

      mockClient.createService.mockResolvedValue(mockResponse);

      const result = await resources.createService(createData);

      expect(result).toEqual(mockResponse);
      expect(mockClient.createService).toHaveBeenCalledWith(createData);
    });
  });

  describe('deleteService', () => {
    it('should delete a service', async () => {
      const mockResponse = { message: 'Service deleted' };
      mockClient.deleteService.mockResolvedValue(mockResponse);

      const result = await resources.deleteService('test-uuid');

      expect(result).toEqual(mockResponse);
      expect(mockClient.deleteService).toHaveBeenCalledWith('test-uuid', undefined);
    });
  });
});

```

--------------------------------------------------------------------------------
/docs/openapi-chunks/deployments-api.yaml:
--------------------------------------------------------------------------------

```yaml
openapi: 3.1.0
info:
  title: Coolify
  version: '0.1'
paths:
  /deployments:
    get:
      tags:
        - Deployments
      summary: List
      description: List currently running deployments
      operationId: list-deployments
      responses:
        '200':
          description: Get all currently running deployments.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ApplicationDeploymentQueue'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /deployments/{uuid}:
    get:
      tags:
        - Deployments
      summary: Get
      description: Get deployment by UUID.
      operationId: get-deployment-by-uuid
      parameters:
        - name: uuid
          in: path
          description: Deployment UUID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Get deployment by UUID.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApplicationDeploymentQueue'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /deploy:
    get:
      tags:
        - Deployments
      summary: Deploy
      description: Deploy by tag or uuid. `Post` request also accepted.
      operationId: deploy-by-tag-or-uuid
      parameters:
        - name: tag
          in: query
          description: Tag name(s). Comma separated list is also accepted.
          schema:
            type: string
        - name: uuid
          in: query
          description: Resource UUID(s). Comma separated list is also accepted.
          schema:
            type: string
        - name: force
          in: query
          description: Force rebuild (without cache)
          schema:
            type: boolean
      responses:
        '200':
          description: Get deployment(s) UUID's
          content:
            application/json:
              schema:
                properties:
                  deployments:
                    type: array
                    items:
                      properties:
                        message:
                          type: string
                        resource_uuid:
                          type: string
                        deployment_uuid:
                          type: string
                      type: object
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []

```

--------------------------------------------------------------------------------
/docs/openapi-chunks/teams-api.yaml:
--------------------------------------------------------------------------------

```yaml
openapi: 3.1.0
info:
  title: Coolify
  version: '0.1'
paths:
  /teams:
    get:
      tags:
        - Teams
      summary: List
      description: Get all teams.
      operationId: list-teams
      responses:
        '200':
          description: List of teams.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Team'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /teams/{id}:
    get:
      tags:
        - Teams
      summary: Get
      description: Get team by TeamId.
      operationId: get-team-by-id
      parameters:
        - name: id
          in: path
          description: Team ID
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: List of teams.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Team'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /teams/{id}/members:
    get:
      tags:
        - Teams
      summary: Members
      description: Get members by TeamId.
      operationId: get-members-by-team-id
      parameters:
        - name: id
          in: path
          description: Team ID
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: List of members.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /teams/current:
    get:
      tags:
        - Teams
      summary: Authenticated Team
      description: Get currently authenticated team.
      operationId: get-current-team
      responses:
        '200':
          description: Current Team.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Team'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /teams/current/members:
    get:
      tags:
        - Teams
      summary: Authenticated Team Members
      description: Get currently authenticated team members.
      operationId: get-current-team-members
      responses:
        '200':
          description: Currently authenticated team members.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []

```

--------------------------------------------------------------------------------
/docs/openapi-chunks/private-keys-api.yaml:
--------------------------------------------------------------------------------

```yaml
openapi: 3.1.0
info:
  title: Coolify
  version: '0.1'
paths:
  /security/keys:
    get:
      tags:
        - Private Keys
      summary: List
      description: List all private keys.
      operationId: list-private-keys
      responses:
        '200':
          description: Get all private keys.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PrivateKey'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
    post:
      tags:
        - Private Keys
      summary: Create
      description: Create a new private key.
      operationId: create-private-key
      requestBody:
        required: true
        content:
          application/json:
            schema:
              required:
                - private_key
              properties:
                name:
                  type: string
                description:
                  type: string
                private_key:
                  type: string
              type: object
              additionalProperties: false
      responses:
        '201':
          description: The created private key's UUID.
          content:
            application/json:
              schema:
                properties:
                  uuid:
                    type: string
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
    patch:
      tags:
        - Private Keys
      summary: Update
      description: Update a private key.
      operationId: update-private-key
      requestBody:
        required: true
        content:
          application/json:
            schema:
              required:
                - private_key
              properties:
                name:
                  type: string
                description:
                  type: string
                private_key:
                  type: string
              type: object
              additionalProperties: false
      responses:
        '201':
          description: The updated private key's UUID.
          content:
            application/json:
              schema:
                properties:
                  uuid:
                    type: string
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /security/keys/{uuid}:
    get:
      tags:
        - Private Keys
      summary: Get
      description: Get key by UUID.
      operationId: get-private-key-by-uuid
      parameters:
        - name: uuid
          in: path
          description: Private Key UUID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Get all private keys.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PrivateKey'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          description: Private Key not found.
      security:
        - bearerAuth: []
    delete:
      tags:
        - Private Keys
      summary: Delete
      description: Delete a private key.
      operationId: delete-private-key-by-uuid
      parameters:
        - name: uuid
          in: path
          description: Private Key UUID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Private Key deleted.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Private Key deleted.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          description: Private Key not found.
      security:
        - bearerAuth: []

```

--------------------------------------------------------------------------------
/docs/openapi-chunks/projects-api.yaml:
--------------------------------------------------------------------------------

```yaml
openapi: 3.1.0
info:
  title: Coolify
  version: '0.1'
paths:
  /projects:
    get:
      tags:
        - Projects
      summary: List
      description: List projects.
      operationId: list-projects
      responses:
        '200':
          description: Get all projects.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Project'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
    post:
      tags:
        - Projects
      summary: Create
      description: Create Project.
      operationId: create-project
      requestBody:
        description: Project created.
        required: true
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: The name of the project.
                description:
                  type: string
                  description: The description of the project.
              type: object
      responses:
        '201':
          description: Project created.
          content:
            application/json:
              schema:
                properties:
                  uuid:
                    type: string
                    example: og888os
                    description: The UUID of the project.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /projects/{uuid}:
    get:
      tags:
        - Projects
      summary: Get
      description: Get project by UUID.
      operationId: get-project-by-uuid
      parameters:
        - name: uuid
          in: path
          description: Project UUID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Project details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          description: Project not found.
      security:
        - bearerAuth: []
    delete:
      tags:
        - Projects
      summary: Delete
      description: Delete project by UUID.
      operationId: delete-project-by-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the application.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Project deleted.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Project deleted.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
    patch:
      tags:
        - Projects
      summary: Update
      description: Update Project.
      operationId: update-project-by-uuid
      requestBody:
        description: Project updated.
        required: true
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: The name of the project.
                description:
                  type: string
                  description: The description of the project.
              type: object
      responses:
        '201':
          description: Project updated.
          content:
            application/json:
              schema:
                properties:
                  uuid:
                    type: string
                    example: og888os
                  name:
                    type: string
                    example: Project Name
                  description:
                    type: string
                    example: Project Description
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /projects/{uuid}/{environment_name_or_uuid}:
    get:
      tags:
        - Projects
      summary: Environment
      description: Get environment by name or UUID.
      operationId: get-environment-by-name-or-uuid
      parameters:
        - name: uuid
          in: path
          description: Project UUID
          required: true
          schema:
            type: string
        - name: environment_name_or_uuid
          in: path
          description: Environment name or UUID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Environment details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Environment'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []

```

--------------------------------------------------------------------------------
/src/lib/coolify-client.ts:
--------------------------------------------------------------------------------

```typescript
import {
  CoolifyConfig,
  ErrorResponse,
  ServerInfo,
  ServerResources,
  ServerDomain,
  ValidationResponse,
  Project,
  CreateProjectRequest,
  UpdateProjectRequest,
  Environment,
  Deployment,
  Database,
  DatabaseUpdateRequest,
  Service,
  CreateServiceRequest,
  DeleteServiceOptions,
} from '../types/coolify.js';

export class CoolifyClient {
  private baseUrl: string;
  private accessToken: string;

  constructor(config: CoolifyConfig) {
    if (!config.baseUrl) {
      throw new Error('Coolify base URL is required');
    }
    if (!config.accessToken) {
      throw new Error('Coolify access token is required');
    }
    this.baseUrl = config.baseUrl.replace(/\/$/, '');
    this.accessToken = config.accessToken;
  }

  private async request<T>(path: string, options: RequestInit = {}): Promise<T> {
    try {
      const url = `${this.baseUrl}/api/v1${path}`;
      const response = await fetch(url, {
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${this.accessToken}`,
        },
        ...options,
      });

      const data = await response.json();

      if (!response.ok) {
        const error = data as ErrorResponse;
        throw new Error(error.message || `HTTP ${response.status}: ${response.statusText}`);
      }

      return data as T;
    } catch (error) {
      if (error instanceof TypeError && error.message.includes('fetch')) {
        throw new Error(
          `Failed to connect to Coolify server at ${this.baseUrl}. Please check if the server is running and the URL is correct.`,
        );
      }
      throw error;
    }
  }

  async listServers(): Promise<ServerInfo[]> {
    return this.request<ServerInfo[]>('/servers');
  }

  async getServer(uuid: string): Promise<ServerInfo> {
    return this.request<ServerInfo>(`/servers/${uuid}`);
  }

  async getServerResources(uuid: string): Promise<ServerResources> {
    return this.request<ServerResources>(`/servers/${uuid}/resources`);
  }

  async getServerDomains(uuid: string): Promise<ServerDomain[]> {
    return this.request<ServerDomain[]>(`/servers/${uuid}/domains`);
  }

  async validateServer(uuid: string): Promise<ValidationResponse> {
    return this.request<ValidationResponse>(`/servers/${uuid}/validate`);
  }

  async validateConnection(): Promise<void> {
    try {
      await this.listServers();
    } catch (error) {
      throw new Error(
        `Failed to connect to Coolify server: ${error instanceof Error ? error.message : 'Unknown error'}`,
      );
    }
  }

  async listProjects(): Promise<Project[]> {
    return this.request<Project[]>('/projects');
  }

  async getProject(uuid: string): Promise<Project> {
    return this.request<Project>(`/projects/${uuid}`);
  }

  async createProject(project: CreateProjectRequest): Promise<{ uuid: string }> {
    return this.request<{ uuid: string }>('/projects', {
      method: 'POST',
      body: JSON.stringify(project),
    });
  }

  async updateProject(uuid: string, project: UpdateProjectRequest): Promise<Project> {
    return this.request<Project>(`/projects/${uuid}`, {
      method: 'PATCH',
      body: JSON.stringify(project),
    });
  }

  async deleteProject(uuid: string): Promise<{ message: string }> {
    return this.request<{ message: string }>(`/projects/${uuid}`, {
      method: 'DELETE',
    });
  }

  async getProjectEnvironment(
    projectUuid: string,
    environmentNameOrUuid: string,
  ): Promise<Environment> {
    return this.request<Environment>(`/projects/${projectUuid}/${environmentNameOrUuid}`);
  }

  async deployApplication(uuid: string): Promise<Deployment> {
    const response = await this.request<Deployment>(`/applications/${uuid}/deploy`, {
      method: 'POST',
    });
    return response;
  }

  async listDatabases(): Promise<Database[]> {
    return this.request<Database[]>('/databases');
  }

  async getDatabase(uuid: string): Promise<Database> {
    return this.request<Database>(`/databases/${uuid}`);
  }

  async updateDatabase(uuid: string, data: DatabaseUpdateRequest): Promise<Database> {
    return this.request<Database>(`/databases/${uuid}`, {
      method: 'PATCH',
      body: JSON.stringify(data),
    });
  }

  async deleteDatabase(
    uuid: string,
    options?: {
      deleteConfigurations?: boolean;
      deleteVolumes?: boolean;
      dockerCleanup?: boolean;
      deleteConnectedNetworks?: boolean;
    },
  ): Promise<{ message: string }> {
    const queryParams = new URLSearchParams();
    if (options) {
      if (options.deleteConfigurations !== undefined) {
        queryParams.set('delete_configurations', options.deleteConfigurations.toString());
      }
      if (options.deleteVolumes !== undefined) {
        queryParams.set('delete_volumes', options.deleteVolumes.toString());
      }
      if (options.dockerCleanup !== undefined) {
        queryParams.set('docker_cleanup', options.dockerCleanup.toString());
      }
      if (options.deleteConnectedNetworks !== undefined) {
        queryParams.set('delete_connected_networks', options.deleteConnectedNetworks.toString());
      }
    }

    const queryString = queryParams.toString();
    const url = queryString ? `/databases/${uuid}?${queryString}` : `/databases/${uuid}`;

    return this.request<{ message: string }>(url, {
      method: 'DELETE',
    });
  }

  async listServices(): Promise<Service[]> {
    return this.request<Service[]>('/services');
  }

  async getService(uuid: string): Promise<Service> {
    return this.request<Service>(`/services/${uuid}`);
  }

  async createService(data: CreateServiceRequest): Promise<{ uuid: string; domains: string[] }> {
    return this.request<{ uuid: string; domains: string[] }>('/services', {
      method: 'POST',
      body: JSON.stringify(data),
    });
  }

  async deleteService(uuid: string, options?: DeleteServiceOptions): Promise<{ message: string }> {
    const queryParams = new URLSearchParams();
    if (options) {
      if (options.deleteConfigurations !== undefined) {
        queryParams.set('delete_configurations', options.deleteConfigurations.toString());
      }
      if (options.deleteVolumes !== undefined) {
        queryParams.set('delete_volumes', options.deleteVolumes.toString());
      }
      if (options.dockerCleanup !== undefined) {
        queryParams.set('docker_cleanup', options.dockerCleanup.toString());
      }
      if (options.deleteConnectedNetworks !== undefined) {
        queryParams.set('delete_connected_networks', options.deleteConnectedNetworks.toString());
      }
    }

    const queryString = queryParams.toString();
    const url = queryString ? `/services/${uuid}?${queryString}` : `/services/${uuid}`;

    return this.request<{ message: string }>(url, {
      method: 'DELETE',
    });
  }

  // Add more methods as needed for other endpoints
}

```

--------------------------------------------------------------------------------
/src/__tests__/coolify-client.test.ts:
--------------------------------------------------------------------------------

```typescript
import { jest } from '@jest/globals';
import { CoolifyClient } from '../lib/coolify-client.js';
import { ServiceType, CreateServiceRequest } from '../types/coolify.js';

const mockFetch = jest.fn() as any;

describe('CoolifyClient', () => {
  let client: CoolifyClient;

  const mockServers = [
    {
      id: 1,
      uuid: 'test-uuid',
      name: 'test-server',
      status: 'running',
    },
  ];

  const mockServerInfo = {
    id: 1,
    uuid: 'test-uuid',
    name: 'test-server',
    status: 'running',
  };

  const mockServerResources = {
    resources: [
      {
        name: 'memory',
        value: '2GB',
      },
      {
        name: 'disk',
        value: '20GB',
      },
    ],
  };

  const mockService = {
    id: 1,
    uuid: 'test-uuid',
    name: 'test-service',
    type: 'code-server' as ServiceType,
    status: 'running',
    created_at: '2024-01-01',
    updated_at: '2024-01-01',
  };

  const errorResponse = {
    message: 'Resource not found',
  };

  beforeEach(() => {
    mockFetch.mockClear();
    (global as any).fetch = mockFetch;
    client = new CoolifyClient({
      baseUrl: 'http://localhost:3000',
      accessToken: 'test-api-key',
    });
  });

  describe('listServers', () => {
    it('should return a list of servers', async () => {
      mockFetch.mockImplementationOnce(
        async () =>
          ({
            ok: true,
            json: async () => mockServers,
          }) as Response,
      );

      const servers = await client.listServers();
      expect(servers).toEqual(mockServers);
      expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/servers', {
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'Bearer test-api-key',
        },
      });
    });

    it('should handle errors', async () => {
      mockFetch.mockImplementationOnce(() =>
        Promise.resolve({
          ok: false,
          json: async () => errorResponse,
        } as Response),
      );

      await expect(client.listServers()).rejects.toThrow('Resource not found');
    });
  });

  describe('getServer', () => {
    it('should get server info', async () => {
      mockFetch.mockImplementationOnce(() =>
        Promise.resolve({
          ok: true,
          json: async () => mockServerInfo,
        } as Response),
      );

      const result = await client.getServer('test-uuid');

      expect(result).toEqual(mockServerInfo);
      expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/servers/test-uuid', {
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'Bearer test-api-key',
        },
      });
    });

    it('should handle errors', async () => {
      mockFetch.mockImplementationOnce(() =>
        Promise.resolve({
          ok: false,
          json: async () => errorResponse,
        } as Response),
      );

      await expect(client.getServer('test-uuid')).rejects.toThrow('Resource not found');
    });
  });

  describe('getServerResources', () => {
    it('should get server resources', async () => {
      mockFetch.mockImplementationOnce(() =>
        Promise.resolve({
          ok: true,
          json: async () => mockServerResources,
        } as Response),
      );

      const result = await client.getServerResources('test-uuid');

      expect(result).toEqual(mockServerResources);
      expect(mockFetch).toHaveBeenCalledWith(
        'http://localhost:3000/api/v1/servers/test-uuid/resources',
        {
          headers: {
            'Content-Type': 'application/json',
            Authorization: 'Bearer test-api-key',
          },
        },
      );
    });

    it('should handle errors', async () => {
      mockFetch.mockImplementationOnce(() =>
        Promise.resolve({
          ok: false,
          json: async () => errorResponse,
        } as Response),
      );

      await expect(client.getServerResources('test-uuid')).rejects.toThrow('Resource not found');
    });
  });

  describe('listServices', () => {
    it('should list services', async () => {
      mockFetch.mockImplementationOnce(() =>
        Promise.resolve({
          ok: true,
          json: () => Promise.resolve([mockService]),
        } as Response),
      );

      const result = await client.listServices();

      expect(result).toEqual([mockService]);
      expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/services', {
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'Bearer test-api-key',
        },
      });
    });
  });

  describe('getService', () => {
    it('should get service info', async () => {
      mockFetch.mockImplementationOnce(() =>
        Promise.resolve({
          ok: true,
          json: () => Promise.resolve(mockService),
        } as Response),
      );

      const result = await client.getService('test-uuid');

      expect(result).toEqual(mockService);
      expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/services/test-uuid', {
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'Bearer test-api-key',
        },
      });
    });
  });

  describe('createService', () => {
    it('should create a service', async () => {
      mockFetch.mockImplementationOnce(() =>
        Promise.resolve({
          ok: true,
          json: () =>
            Promise.resolve({
              uuid: 'test-uuid',
              domains: ['test.com'],
            }),
        } as Response),
      );

      const createData: CreateServiceRequest = {
        name: 'test-service',
        type: 'code-server',
        project_uuid: 'project-uuid',
        environment_uuid: 'env-uuid',
        server_uuid: 'server-uuid',
      };

      const result = await client.createService(createData);

      expect(result).toEqual({
        uuid: 'test-uuid',
        domains: ['test.com'],
      });
      expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/services', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'Bearer test-api-key',
        },
        body: JSON.stringify(createData),
      });
    });
  });

  describe('deleteService', () => {
    it('should delete a service', async () => {
      mockFetch.mockImplementationOnce(() =>
        Promise.resolve({
          ok: true,
          json: () => Promise.resolve({ message: 'Service deleted' }),
        } as Response),
      );

      const result = await client.deleteService('test-uuid');

      expect(result).toEqual({ message: 'Service deleted' });
      expect(mockFetch).toHaveBeenCalledWith('http://localhost:3000/api/v1/services/test-uuid', {
        method: 'DELETE',
        headers: {
          'Content-Type': 'application/json',
          Authorization: 'Bearer test-api-key',
        },
      });
    });
  });

  describe('error handling', () => {
    it('should handle network errors', async () => {
      const errorMessage = 'Network error';
      mockFetch.mockImplementationOnce(() => Promise.reject(new Error(errorMessage)));

      await expect(client.listServers()).rejects.toThrow(errorMessage);
    });
  });
});

```

--------------------------------------------------------------------------------
/src/types/coolify.ts:
--------------------------------------------------------------------------------

```typescript
export interface CoolifyConfig {
  baseUrl: string;
  accessToken: string;
}

export interface ServerInfo {
  uuid: string;
  name: string;
  status: 'running' | 'stopped' | 'error';
  version: string;
  resources: {
    cpu: number;
    memory: number;
    disk: number;
  };
}

export interface ResourceStatus {
  id: number;
  uuid: string;
  name: string;
  type: string;
  created_at: string;
  updated_at: string;
  status: string;
}

export type ServerResources = ResourceStatus[];

export interface ErrorResponse {
  error: string;
  status: number;
  message: string;
}

export interface ServerDomain {
  ip: string;
  domains: string[];
}

export interface ValidationResponse {
  message: string;
}

export interface Environment {
  id: number;
  uuid: string;
  name: string;
  project_uuid: string;
  variables?: Record<string, string>;
  created_at: string;
  updated_at: string;
}

export interface Project {
  id: number;
  uuid: string;
  name: string;
  description?: string;
  environments?: Environment[];
}

export interface CreateProjectRequest {
  name: string;
  description?: string;
}

export interface UpdateProjectRequest {
  name?: string;
  description?: string;
}

export interface LogEntry {
  timestamp: string;
  level: string;
  message: string;
}

export interface Deployment {
  id: number;
  uuid: string;
  application_uuid: string;
  status: string;
  created_at: string;
  updated_at: string;
}

export interface DatabaseBase {
  id: number;
  uuid: string;
  name: string;
  description?: string;
  type:
    | 'postgresql'
    | 'mysql'
    | 'mariadb'
    | 'mongodb'
    | 'redis'
    | 'keydb'
    | 'clickhouse'
    | 'dragonfly';
  status: 'running' | 'stopped' | 'error';
  created_at: string;
  updated_at: string;
  is_public: boolean;
  public_port?: number;
  image: string;
  limits?: {
    memory?: string;
    memory_swap?: string;
    memory_swappiness?: number;
    memory_reservation?: string;
    cpus?: string;
    cpuset?: string;
    cpu_shares?: number;
  };
}

export interface PostgresDatabase extends DatabaseBase {
  type: 'postgresql';
  postgres_user: string;
  postgres_password: string;
  postgres_db: string;
  postgres_initdb_args?: string;
  postgres_host_auth_method?: string;
  postgres_conf?: string;
}

export interface MySQLDatabase extends DatabaseBase {
  type: 'mysql';
  mysql_root_password: string;
  mysql_user?: string;
  mysql_password?: string;
  mysql_database?: string;
}

export interface MariaDBDatabase extends DatabaseBase {
  type: 'mariadb';
  mariadb_root_password: string;
  mariadb_user?: string;
  mariadb_password?: string;
  mariadb_database?: string;
  mariadb_conf?: string;
}

export interface MongoDBDatabase extends DatabaseBase {
  type: 'mongodb';
  mongo_initdb_root_username: string;
  mongo_initdb_root_password: string;
  mongo_initdb_database?: string;
  mongo_conf?: string;
}

export interface RedisDatabase extends DatabaseBase {
  type: 'redis';
  redis_password?: string;
  redis_conf?: string;
}

export interface KeyDBDatabase extends DatabaseBase {
  type: 'keydb';
  keydb_password?: string;
  keydb_conf?: string;
}

export interface ClickhouseDatabase extends DatabaseBase {
  type: 'clickhouse';
  clickhouse_admin_user: string;
  clickhouse_admin_password: string;
}

export interface DragonflyDatabase extends DatabaseBase {
  type: 'dragonfly';
  dragonfly_password: string;
}

export type Database =
  | PostgresDatabase
  | MySQLDatabase
  | MariaDBDatabase
  | MongoDBDatabase
  | RedisDatabase
  | KeyDBDatabase
  | ClickhouseDatabase
  | DragonflyDatabase;

export interface DatabaseUpdateRequest {
  name?: string;
  description?: string;
  image?: string;
  is_public?: boolean;
  public_port?: number;
  limits_memory?: string;
  limits_memory_swap?: string;
  limits_memory_swappiness?: number;
  limits_memory_reservation?: string;
  limits_cpus?: string;
  limits_cpuset?: string;
  limits_cpu_shares?: number;
  postgres_user?: string;
  postgres_password?: string;
  postgres_db?: string;
  postgres_initdb_args?: string;
  postgres_host_auth_method?: string;
  postgres_conf?: string;
  clickhouse_admin_user?: string;
  clickhouse_admin_password?: string;
  dragonfly_password?: string;
  redis_password?: string;
  redis_conf?: string;
  keydb_password?: string;
  keydb_conf?: string;
  mariadb_conf?: string;
  mariadb_root_password?: string;
  mariadb_user?: string;
  mariadb_password?: string;
  mariadb_database?: string;
  mongo_conf?: string;
  mongo_initdb_root_username?: string;
  mongo_initdb_root_password?: string;
  mongo_initdb_database?: string;
  mysql_root_password?: string;
  mysql_password?: string;
  mysql_user?: string;
  mysql_database?: string;
}

export type ServiceType =
  | 'activepieces'
  | 'appsmith'
  | 'appwrite'
  | 'authentik'
  | 'babybuddy'
  | 'budge'
  | 'changedetection'
  | 'chatwoot'
  | 'classicpress-with-mariadb'
  | 'classicpress-with-mysql'
  | 'classicpress-without-database'
  | 'cloudflared'
  | 'code-server'
  | 'dashboard'
  | 'directus'
  | 'directus-with-postgresql'
  | 'docker-registry'
  | 'docuseal'
  | 'docuseal-with-postgres'
  | 'dokuwiki'
  | 'duplicati'
  | 'emby'
  | 'embystat'
  | 'fider'
  | 'filebrowser'
  | 'firefly'
  | 'formbricks'
  | 'ghost'
  | 'gitea'
  | 'gitea-with-mariadb'
  | 'gitea-with-mysql'
  | 'gitea-with-postgresql'
  | 'glance'
  | 'glances'
  | 'glitchtip'
  | 'grafana'
  | 'grafana-with-postgresql'
  | 'grocy'
  | 'heimdall'
  | 'homepage'
  | 'jellyfin'
  | 'kuzzle'
  | 'listmonk'
  | 'logto'
  | 'mediawiki'
  | 'meilisearch'
  | 'metabase'
  | 'metube'
  | 'minio'
  | 'moodle'
  | 'n8n'
  | 'n8n-with-postgresql'
  | 'next-image-transformation'
  | 'nextcloud'
  | 'nocodb'
  | 'odoo'
  | 'openblocks'
  | 'pairdrop'
  | 'penpot'
  | 'phpmyadmin'
  | 'pocketbase'
  | 'posthog'
  | 'reactive-resume'
  | 'rocketchat'
  | 'shlink'
  | 'slash'
  | 'snapdrop'
  | 'statusnook'
  | 'stirling-pdf'
  | 'supabase'
  | 'syncthing'
  | 'tolgee'
  | 'trigger'
  | 'trigger-with-external-database'
  | 'twenty'
  | 'umami'
  | 'unleash-with-postgresql'
  | 'unleash-without-database'
  | 'uptime-kuma'
  | 'vaultwarden'
  | 'vikunja'
  | 'weblate'
  | 'whoogle'
  | 'wordpress-with-mariadb'
  | 'wordpress-with-mysql'
  | 'wordpress-without-database';

export interface Service {
  id: number;
  uuid: string;
  name: string;
  description?: string;
  type: ServiceType;
  status: 'running' | 'stopped' | 'error';
  created_at: string;
  updated_at: string;
  project_uuid: string;
  environment_name: string;
  environment_uuid: string;
  server_uuid: string;
  destination_uuid?: string;
  domains?: string[];
}

export interface CreateServiceRequest {
  type: ServiceType;
  name?: string;
  description?: string;
  project_uuid: string;
  environment_name?: string;
  environment_uuid?: string;
  server_uuid: string;
  destination_uuid?: string;
  instant_deploy?: boolean;
}

export interface DeleteServiceOptions {
  deleteConfigurations?: boolean;
  deleteVolumes?: boolean;
  dockerCleanup?: boolean;
  deleteConnectedNetworks?: boolean;
}

export interface Application {
  uuid: string;
  name: string;
  // Add other application properties as needed
}

export interface CreateApplicationRequest {
  name: string;
  // Add other required fields for application creation
}

```

--------------------------------------------------------------------------------
/docs/openapi-chunks/servers-api.yaml:
--------------------------------------------------------------------------------

```yaml
openapi: 3.1.0
info:
  title: Coolify
  version: '0.1'
paths:
  /servers:
    get:
      tags:
        - Servers
      summary: List
      description: List all servers.
      operationId: list-servers
      responses:
        '200':
          description: Get all servers.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Server'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
    post:
      tags:
        - Servers
      summary: Create
      description: Create Server.
      operationId: create-server
      requestBody:
        description: Server created.
        required: true
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  example: My Server
                  description: The name of the server.
                description:
                  type: string
                  example: My Server Description
                  description: The description of the server.
                ip:
                  type: string
                  example: 127.0.0.1
                  description: The IP of the server.
                port:
                  type: integer
                  example: 22
                  description: The port of the server.
                user:
                  type: string
                  example: root
                  description: The user of the server.
                private_key_uuid:
                  type: string
                  example: og888os
                  description: The UUID of the private key.
                is_build_server:
                  type: boolean
                  example: false
                  description: Is build server.
                instant_validate:
                  type: boolean
                  example: false
                  description: Instant validate.
                proxy_type:
                  type: string
                  enum:
                    - traefik
                    - caddy
                    - none
                  example: traefik
                  description: The proxy type.
              type: object
      responses:
        '201':
          description: Server created.
          content:
            application/json:
              schema:
                properties:
                  uuid:
                    type: string
                    example: og888os
                    description: The UUID of the server.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /servers/{uuid}:
    get:
      tags:
        - Servers
      summary: Get
      description: Get server by UUID.
      operationId: get-server-by-uuid
      parameters:
        - name: uuid
          in: path
          description: Server's UUID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Get server by UUID
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Server'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
    delete:
      tags:
        - Servers
      summary: Delete
      description: Delete server by UUID.
      operationId: delete-server-by-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the server.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Server deleted.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Server deleted.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
    patch:
      tags:
        - Servers
      summary: Update
      description: Update Server.
      operationId: update-server-by-uuid
      parameters:
        - name: uuid
          in: path
          description: Server UUID
          required: true
          schema:
            type: string
      requestBody:
        description: Server updated.
        required: true
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: The name of the server.
                description:
                  type: string
                  description: The description of the server.
                ip:
                  type: string
                  description: The IP of the server.
                port:
                  type: integer
                  description: The port of the server.
                user:
                  type: string
                  description: The user of the server.
                private_key_uuid:
                  type: string
                  description: The UUID of the private key.
                is_build_server:
                  type: boolean
                  description: Is build server.
                instant_validate:
                  type: boolean
                  description: Instant validate.
                proxy_type:
                  type: string
                  enum:
                    - traefik
                    - caddy
                    - none
                  description: The proxy type.
              type: object
      responses:
        '201':
          description: Server updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Server'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /servers/{uuid}/resources:
    get:
      tags:
        - Servers
      summary: Resources
      description: Get resources by server.
      operationId: get-resources-by-server-uuid
      parameters:
        - name: uuid
          in: path
          description: Server's UUID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Get resources by server
          content:
            application/json:
              schema:
                type: array
                items:
                  properties:
                    id:
                      type: integer
                    uuid:
                      type: string
                    name:
                      type: string
                    type:
                      type: string
                    created_at:
                      type: string
                    updated_at:
                      type: string
                    status:
                      type: string
                  type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /servers/{uuid}/domains:
    get:
      tags:
        - Servers
      summary: Domains
      description: Get domains by server.
      operationId: get-domains-by-server-uuid
      parameters:
        - name: uuid
          in: path
          description: Server's UUID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Get domains by server
          content:
            application/json:
              schema:
                type: array
                items:
                  properties:
                    ip:
                      type: string
                    domains:
                      type: array
                      items:
                        type: string
                  type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /servers/{uuid}/validate:
    get:
      tags:
        - Servers
      summary: Validate
      description: Validate server by UUID.
      operationId: validate-server-by-uuid
      parameters:
        - name: uuid
          in: path
          description: Server UUID
          required: true
          schema:
            type: string
      responses:
        '201':
          description: Server validation started.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Validation started.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []

```

--------------------------------------------------------------------------------
/docs/features/013-npx-config-fix.md:
--------------------------------------------------------------------------------

```markdown
# npx config fix

I want to be able to have the following config:

```json
{
  "mcpServers": {
    "coolify": {
      "command": "npx",
      "args": ["-y", "@masonator/coolify-mcp"],
      "env": {
        "COOLIFY_ACCESS_TOKEN": "token",
        "COOLIFY_BASE_URL": "https://url"
      }
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "pat"
      }
    }
  }
}
```

The github config is correct, but the coolify config currently does not work.

I get the following error:

```
2025-03-07T09:43:34.691Z [coolify] [info] Initializing server...
2025-03-07T09:43:34.783Z [coolify] [info] Server started and connected successfully
2025-03-07T09:43:35.882Z [coolify] [info] Message from client: {"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"claude-ai","version":"0.1.0"}},"jsonrpc":"2.0","id":0}
node:internal/modules/cjs/loader:603
      throw e;
      ^

Error: Cannot find module '/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp'
    at createEsmNotFoundErr (node:internal/modules/cjs/loader:1186:15)
    at finalizeEsmResolution (node:internal/modules/cjs/loader:1174:15)
    at resolveExports (node:internal/modules/cjs/loader:596:14)
    at Module._findPath (node:internal/modules/cjs/loader:673:31)
    at Module._resolveFilename (node:internal/modules/cjs/loader:1135:27)
    at Module._load (node:internal/modules/cjs/loader:990:27)
    at Module.require (node:internal/modules/cjs/loader:1237:19)
    at require (node:internal/modules/helpers:176:18)
    at Object.<anonymous> (/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@masonator/coolify-mcp/dist/lib/mcp-server.js:4:15)
    at Module._compile (node:internal/modules/cjs/loader:1378:14) {
  code: 'MODULE_NOT_FOUND',
  path: '/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@modelcontextprotocol/sdk/package.json'
}
node:internal/modules/cjs/loader:603
      throw e;
      ^

Error: Cannot find module '/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp'
    at createEsmNotFoundErr (node:internal/modules/cjs/loader:1186:15)
    at finalizeEsmResolution (node:internal/modules/cjs/loader:1174:15)
    at resolveExports (node:internal/modules/cjs/loader:596:14)
    at Module._findPath (node:internal/modules/cjs/loader:673:31)
    at Module._resolveFilename (node:internal/modules/cjs/loader:1135:27)
    at Module._load (node:internal/modules/cjs/loader:990:27)
    at Module.require (node:internal/modules/cjs/loader:1237:19)
    at require (node:internal/modules/helpers:176:18)
    at Object.<anonymous> (/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@masonator/coolify-mcp/dist/lib/mcp-server.js:4:15)
    at Module._compile (node:internal/modules/cjs/loader:1378:14) {
  code: 'MODULE_NOT_FOUND',
  path: '/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@modelcontextprotocol/sdk/package.json'
}

Node.js v21.6.0

Node.js v21.6.0
2025-03-07T09:43:36.909Z [coolify] [info] Server transport closed
2025-03-07T09:43:36.910Z [coolify] [info] Client transport closed
2025-03-07T09:43:36.910Z [coolify] [info] Server transport closed unexpectedly, this is likely due to the process exiting early. If you are developing this MCP server you can add output to stderr (i.e. `console.error('...')` in JavaScript, `print('...', file=sys.stderr)` in python) and it will appear in this log.
2025-03-07T09:43:36.910Z [coolify] [error] Server disconnected. For troubleshooting guidance, please visit our [debugging documentation](https://modelcontextprotocol.io/docs/tools/debugging) {"context":"connection"}
2025-03-07T09:43:36.911Z [coolify] [info] Client transport closed
2025-03-07T09:43:36.912Z [coolify] [info] Server transport closed
2025-03-07T09:43:36.912Z [coolify] [info] Client transport closed
2025-03-07T09:43:36.912Z [coolify] [info] Server transport closed unexpectedly, this is likely due to the process exiting early. If you are developing this MCP server you can add output to stderr (i.e. `console.error('...')` in JavaScript, `print('...', file=sys.stderr)` in python) and it will appear in this log.
2025-03-07T09:43:36.912Z [coolify] [error] Server disconnected. For troubleshooting guidance, please visit our [debugging documentation](https://modelcontextprotocol.io/docs/tools/debugging) {"context":"connection"}
2025-03-07T09:43:36.913Z [coolify] [info] Client transport closed
2025-03-07T09:51:22.595Z [coolify] [info] Initializing server...
2025-03-07T09:51:22.618Z [coolify] [info] Server started and connected successfully
2025-03-07T09:51:22.621Z [coolify] [info] Message from client: {"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"claude-ai","version":"0.1.0"}},"jsonrpc":"2.0","id":0}
2025-03-07T09:51:23.837Z [coolify] [info] Initializing server...
2025-03-07T09:51:23.853Z [coolify] [info] Server started and connected successfully
2025-03-07T09:51:23.948Z [coolify] [info] Message from client: {"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"claude-ai","version":"0.1.0"}},"jsonrpc":"2.0","id":0}
node:internal/modules/cjs/loader:603
      throw e;
      ^

Error: Cannot find module '/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp'
    at createEsmNotFoundErr (node:internal/modules/cjs/loader:1186:15)
    at finalizeEsmResolution (node:internal/modules/cjs/loader:1174:15)
    at resolveExports (node:internal/modules/cjs/loader:596:14)
    at Module._findPath (node:internal/modules/cjs/loader:673:31)
    at Module._resolveFilename (node:internal/modules/cjs/loader:1135:27)
    at Module._load (node:internal/modules/cjs/loader:990:27)
    at Module.require (node:internal/modules/cjs/loader:1237:19)
    at require (node:internal/modules/helpers:176:18)
    at Object.<anonymous> (/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@masonator/coolify-mcp/dist/lib/mcp-server.js:4:15)
    at Module._compile (node:internal/modules/cjs/loader:1378:14) {
  code: 'MODULE_NOT_FOUND',
  path: '/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@modelcontextprotocol/sdk/package.json'
}

Node.js v21.6.0
2025-03-07T09:51:25.767Z [coolify] [info] Server transport closed
2025-03-07T09:51:25.768Z [coolify] [info] Client transport closed
2025-03-07T09:51:25.768Z [coolify] [info] Server transport closed unexpectedly, this is likely due to the process exiting early. If you are developing this MCP server you can add output to stderr (i.e. `console.error('...')` in JavaScript, `print('...', file=sys.stderr)` in python) and it will appear in this log.
2025-03-07T09:51:25.768Z [coolify] [error] Server disconnected. For troubleshooting guidance, please visit our [debugging documentation](https://modelcontextprotocol.io/docs/tools/debugging) {"context":"connection"}
2025-03-07T09:51:25.769Z [coolify] [info] Client transport closed
node:internal/modules/cjs/loader:603
      throw e;
      ^

Error: Cannot find module '/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp'
    at createEsmNotFoundErr (node:internal/modules/cjs/loader:1186:15)
    at finalizeEsmResolution (node:internal/modules/cjs/loader:1174:15)
    at resolveExports (node:internal/modules/cjs/loader:596:14)
    at Module._findPath (node:internal/modules/cjs/loader:673:31)
    at Module._resolveFilename (node:internal/modules/cjs/loader:1135:27)
    at Module._load (node:internal/modules/cjs/loader:990:27)
    at Module.require (node:internal/modules/cjs/loader:1237:19)
    at require (node:internal/modules/helpers:176:18)
    at Object.<anonymous> (/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@masonator/coolify-mcp/dist/lib/mcp-server.js:4:15)
    at Module._compile (node:internal/modules/cjs/loader:1378:14) {
  code: 'MODULE_NOT_FOUND',
  path: '/Users/stumason/.npm/_npx/4e3adc8df0812880/node_modules/@modelcontextprotocol/sdk/package.json'
}

Node.js v21.6.0
2025-03-07T09:51:25.851Z [coolify] [info] Server transport closed
2025-03-07T09:51:25.851Z [coolify] [info] Client transport closed
2025-03-07T09:51:25.852Z [coolify] [info] Server transport closed unexpectedly, this is likely due to the process exiting early. If you are developing this MCP server you can add output to stderr (i.e. `console.error('...')` in JavaScript, `print('...', file=sys.stderr)` in python) and it will appear in this log.
2025-03-07T09:51:25.852Z [coolify] [error] Server disconnected. For troubleshooting guidance, please visit our [debugging documentation](https://modelcontextprotocol.io/docs/tools/debugging) {"context":"connection"}
2025-03-07T09:51:25.852Z [coolify] [info] Client transport closed
```

For reference, the github package.json looks like this:

```json
{
  "name": "@modelcontextprotocol/server-github",
  "version": "0.6.2",
  "description": "MCP server for using the GitHub API",
  "license": "MIT",
  "author": "Anthropic, PBC (https://anthropic.com)",
  "homepage": "https://modelcontextprotocol.io",
  "bugs": "https://github.com/modelcontextprotocol/servers/issues",
  "type": "module",
  "bin": {
    "mcp-server-github": "dist/index.js"
  },
  "files": ["dist"],
  "scripts": {
    "build": "tsc && shx chmod +x dist/*.js",
    "prepare": "npm run build",
    "watch": "tsc --watch"
  },
  "dependencies": {
    "@modelcontextprotocol/sdk": "1.0.1",
    "@types/node": "^22",
    "@types/node-fetch": "^2.6.12",
    "node-fetch": "^3.3.2",
    "universal-user-agent": "^7.0.2",
    "zod": "^3.22.4",
    "zod-to-json-schema": "^3.23.5"
  },
  "devDependencies": {
    "shx": "^0.3.4",
    "typescript": "^5.6.2"
  }
}
```

```

--------------------------------------------------------------------------------
/docs/mcp-js-readme.md:
--------------------------------------------------------------------------------

```markdown
# MCP TypeScript SDK ![NPM Version](https://img.shields.io/npm/v/%40modelcontextprotocol%2Fsdk) ![MIT licensed](https://img.shields.io/npm/l/%40modelcontextprotocol%2Fsdk)

## Table of Contents

- [Overview](#overview)
- [Installation](#installation)
- [Quickstart](#quickstart)
- [What is MCP?](#what-is-mcp)
- [Core Concepts](#core-concepts)
  - [Server](#server)
  - [Resources](#resources)
  - [Tools](#tools)
  - [Prompts](#prompts)
- [Running Your Server](#running-your-server)
  - [stdio](#stdio)
  - [HTTP with SSE](#http-with-sse)
  - [Testing and Debugging](#testing-and-debugging)
- [Examples](#examples)
  - [Echo Server](#echo-server)
  - [SQLite Explorer](#sqlite-explorer)
- [Advanced Usage](#advanced-usage)
  - [Low-Level Server](#low-level-server)
  - [Writing MCP Clients](#writing-mcp-clients)
  - [Server Capabilities](#server-capabilities)

## Overview

The Model Context Protocol allows applications to provide context for LLMs in a standardized way, separating the concerns of providing context from the actual LLM interaction. This TypeScript SDK implements the full MCP specification, making it easy to:

- Build MCP clients that can connect to any MCP server
- Create MCP servers that expose resources, prompts and tools
- Use standard transports like stdio and SSE
- Handle all MCP protocol messages and lifecycle events

## Installation

```bash
npm install @modelcontextprotocol/sdk
```

## Quick Start

Let's create a simple MCP server that exposes a calculator tool and some data:

```typescript
import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';

// Create an MCP server
const server = new McpServer({
  name: 'Demo',
  version: '1.0.0',
});

// Add an addition tool
server.tool('add', { a: z.number(), b: z.number() }, async ({ a, b }) => ({
  content: [{ type: 'text', text: String(a + b) }],
}));

// Add a dynamic greeting resource
server.resource(
  'greeting',
  new ResourceTemplate('greeting://{name}', { list: undefined }),
  async (uri, { name }) => ({
    contents: [
      {
        uri: uri.href,
        text: `Hello, ${name}!`,
      },
    ],
  }),
);

// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
await server.connect(transport);
```

## What is MCP?

The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) lets you build servers that expose data and functionality to LLM applications in a secure, standardized way. Think of it like a web API, but specifically designed for LLM interactions. MCP servers can:

- Expose data through **Resources** (think of these sort of like GET endpoints; they are used to load information into the LLM's context)
- Provide functionality through **Tools** (sort of like POST endpoints; they are used to execute code or otherwise produce a side effect)
- Define interaction patterns through **Prompts** (reusable templates for LLM interactions)
- And more!

## Core Concepts

### Server

The McpServer is your core interface to the MCP protocol. It handles connection management, protocol compliance, and message routing:

```typescript
const server = new McpServer({
  name: 'My App',
  version: '1.0.0',
});
```

### Resources

Resources are how you expose data to LLMs. They're similar to GET endpoints in a REST API - they provide data but shouldn't perform significant computation or have side effects:

```typescript
// Static resource
server.resource('config', 'config://app', async (uri) => ({
  contents: [
    {
      uri: uri.href,
      text: 'App configuration here',
    },
  ],
}));

// Dynamic resource with parameters
server.resource(
  'user-profile',
  new ResourceTemplate('users://{userId}/profile', { list: undefined }),
  async (uri, { userId }) => ({
    contents: [
      {
        uri: uri.href,
        text: `Profile data for user ${userId}`,
      },
    ],
  }),
);
```

### Tools

Tools let LLMs take actions through your server. Unlike resources, tools are expected to perform computation and have side effects:

```typescript
// Simple tool with parameters
server.tool(
  'calculate-bmi',
  {
    weightKg: z.number(),
    heightM: z.number(),
  },
  async ({ weightKg, heightM }) => ({
    content: [
      {
        type: 'text',
        text: String(weightKg / (heightM * heightM)),
      },
    ],
  }),
);

// Async tool with external API call
server.tool('fetch-weather', { city: z.string() }, async ({ city }) => {
  const response = await fetch(`https://api.weather.com/${city}`);
  const data = await response.text();
  return {
    content: [{ type: 'text', text: data }],
  };
});
```

### Prompts

Prompts are reusable templates that help LLMs interact with your server effectively:

```typescript
server.prompt('review-code', { code: z.string() }, ({ code }) => ({
  messages: [
    {
      role: 'user',
      content: {
        type: 'text',
        text: `Please review this code:\n\n${code}`,
      },
    },
  ],
}));
```

## Running Your Server

MCP servers in TypeScript need to be connected to a transport to communicate with clients. How you start the server depends on the choice of transport:

### stdio

For command-line tools and direct integrations:

```typescript
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';

const server = new McpServer({
  name: 'example-server',
  version: '1.0.0',
});

// ... set up server resources, tools, and prompts ...

const transport = new StdioServerTransport();
await server.connect(transport);
```

### HTTP with SSE

For remote servers, start a web server with a Server-Sent Events (SSE) endpoint, and a separate endpoint for the client to send its messages to:

```typescript
import express from 'express';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';

const server = new McpServer({
  name: 'example-server',
  version: '1.0.0',
});

// ... set up server resources, tools, and prompts ...

const app = express();

app.get('/sse', async (req, res) => {
  const transport = new SSEServerTransport('/messages', res);
  await server.connect(transport);
});

app.post('/messages', async (req, res) => {
  // Note: to support multiple simultaneous connections, these messages will
  // need to be routed to a specific matching transport. (This logic isn't
  // implemented here, for simplicity.)
  await transport.handlePostMessage(req, res);
});

app.listen(3001);
```

### Testing and Debugging

To test your server, you can use the [MCP Inspector](https://github.com/modelcontextprotocol/inspector). See its README for more information.

## Examples

### Echo Server

A simple server demonstrating resources, tools, and prompts:

```typescript
import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
import { z } from 'zod';

const server = new McpServer({
  name: 'Echo',
  version: '1.0.0',
});

server.resource(
  'echo',
  new ResourceTemplate('echo://{message}', { list: undefined }),
  async (uri, { message }) => ({
    contents: [
      {
        uri: uri.href,
        text: `Resource echo: ${message}`,
      },
    ],
  }),
);

server.tool('echo', { message: z.string() }, async ({ message }) => ({
  content: [{ type: 'text', text: `Tool echo: ${message}` }],
}));

server.prompt('echo', { message: z.string() }, ({ message }) => ({
  messages: [
    {
      role: 'user',
      content: {
        type: 'text',
        text: `Please process this message: ${message}`,
      },
    },
  ],
}));
```

### SQLite Explorer

A more complex example showing database integration:

```typescript
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import sqlite3 from 'sqlite3';
import { promisify } from 'util';
import { z } from 'zod';

const server = new McpServer({
  name: 'SQLite Explorer',
  version: '1.0.0',
});

// Helper to create DB connection
const getDb = () => {
  const db = new sqlite3.Database('database.db');
  return {
    all: promisify<string, any[]>(db.all.bind(db)),
    close: promisify(db.close.bind(db)),
  };
};

server.resource('schema', 'schema://main', async (uri) => {
  const db = getDb();
  try {
    const tables = await db.all("SELECT sql FROM sqlite_master WHERE type='table'");
    return {
      contents: [
        {
          uri: uri.href,
          text: tables.map((t: { sql: string }) => t.sql).join('\n'),
        },
      ],
    };
  } finally {
    await db.close();
  }
});

server.tool('query', { sql: z.string() }, async ({ sql }) => {
  const db = getDb();
  try {
    const results = await db.all(sql);
    return {
      content: [
        {
          type: 'text',
          text: JSON.stringify(results, null, 2),
        },
      ],
    };
  } catch (err: unknown) {
    const error = err as Error;
    return {
      content: [
        {
          type: 'text',
          text: `Error: ${error.message}`,
        },
      ],
      isError: true,
    };
  } finally {
    await db.close();
  }
});
```

## Advanced Usage

### Low-Level Server

For more control, you can use the low-level Server class directly:

```typescript
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  ListPromptsRequestSchema,
  GetPromptRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';

const server = new Server(
  {
    name: 'example-server',
    version: '1.0.0',
  },
  {
    capabilities: {
      prompts: {},
    },
  },
);

server.setRequestHandler(ListPromptsRequestSchema, async () => {
  return {
    prompts: [
      {
        name: 'example-prompt',
        description: 'An example prompt template',
        arguments: [
          {
            name: 'arg1',
            description: 'Example argument',
            required: true,
          },
        ],
      },
    ],
  };
});

server.setRequestHandler(GetPromptRequestSchema, async (request) => {
  if (request.params.name !== 'example-prompt') {
    throw new Error('Unknown prompt');
  }
  return {
    description: 'Example prompt',
    messages: [
      {
        role: 'user',
        content: {
          type: 'text',
          text: 'Example prompt text',
        },
      },
    ],
  };
});

const transport = new StdioServerTransport();
await server.connect(transport);
```

### Writing MCP Clients

The SDK provides a high-level client interface:

```typescript
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';

const transport = new StdioClientTransport({
  command: 'node',
  args: ['server.js'],
});

const client = new Client(
  {
    name: 'example-client',
    version: '1.0.0',
  },
  {
    capabilities: {
      prompts: {},
      resources: {},
      tools: {},
    },
  },
);

await client.connect(transport);

// List prompts
const prompts = await client.listPrompts();

// Get a prompt
const prompt = await client.getPrompt('example-prompt', {
  arg1: 'value',
});

// List resources
const resources = await client.listResources();

// Read a resource
const resource = await client.readResource('file:///example.txt');

// Call a tool
const result = await client.callTool({
  name: 'example-tool',
  arguments: {
    arg1: 'value',
  },
});
```

## Documentation

- [Model Context Protocol documentation](https://modelcontextprotocol.io)
- [MCP Specification](https://spec.modelcontextprotocol.io)
- [Example Servers](https://github.com/modelcontextprotocol/servers)

## Contributing

Issues and pull requests are welcome on GitHub at https://github.com/modelcontextprotocol/typescript-sdk.

## License

This project is licensed under the MIT License—see the [LICENSE](LICENSE) file for details.

```

--------------------------------------------------------------------------------
/src/lib/mcp-server.ts:
--------------------------------------------------------------------------------

```typescript
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
import { CoolifyClient } from './coolify-client.js';
import debug from 'debug';
import { z } from 'zod';
import type {
  ServerInfo,
  ServerResources,
  ServerDomain,
  ValidationResponse,
  Project,
  CreateProjectRequest,
  UpdateProjectRequest,
  Environment,
  Deployment,
  Database,
  DatabaseUpdateRequest,
  Service,
  CreateServiceRequest,
  DeleteServiceOptions,
} from '../types/coolify.js';

const log = debug('coolify:mcp');

// Define valid service types
const serviceTypes = [
  'activepieces',
  'appsmith',
  'appwrite',
  'authentik',
  'babybuddy',
  'budge',
  'changedetection',
  'chatwoot',
  'classicpress-with-mariadb',
  'classicpress-with-mysql',
  'classicpress-without-database',
  'cloudflared',
  'code-server',
  'dashboard',
  'directus',
  'directus-with-postgresql',
  'docker-registry',
  'docuseal',
  'docuseal-with-postgres',
  'dokuwiki',
  'duplicati',
  'emby',
  'embystat',
  'fider',
  'filebrowser',
  'firefly',
  'formbricks',
  'ghost',
  'gitea',
  'gitea-with-mariadb',
  'gitea-with-mysql',
  'gitea-with-postgresql',
  'glance',
  'glances',
  'glitchtip',
  'grafana',
  'grafana-with-postgresql',
  'grocy',
  'heimdall',
  'homepage',
  'jellyfin',
  'kuzzle',
  'listmonk',
  'logto',
  'mediawiki',
  'meilisearch',
  'metabase',
  'metube',
  'minio',
  'moodle',
  'n8n',
  'n8n-with-postgresql',
  'next-image-transformation',
  'nextcloud',
  'nocodb',
  'odoo',
  'openblocks',
  'pairdrop',
  'penpot',
  'phpmyadmin',
  'pocketbase',
  'posthog',
  'reactive-resume',
  'rocketchat',
  'shlink',
  'slash',
  'snapdrop',
  'statusnook',
  'stirling-pdf',
  'supabase',
  'syncthing',
  'tolgee',
  'trigger',
  'trigger-with-external-database',
  'twenty',
  'umami',
  'unleash-with-postgresql',
  'unleash-without-database',
  'uptime-kuma',
  'vaultwarden',
  'vikunja',
  'weblate',
  'whoogle',
  'wordpress-with-mariadb',
  'wordpress-with-mysql',
  'wordpress-without-database'
] as const;

export class CoolifyMcpServer extends McpServer {
  private client: CoolifyClient;

  constructor(config: { baseUrl: string; accessToken: string }) {
    super({
      name: 'coolify',
      version: '0.1.18'
    });
    
    log('Initializing server with config: %o', config);
    this.client = new CoolifyClient(config);
  }

  async initialize(): Promise<void> {
    // Register capabilities first
    await this.server.registerCapabilities({
      tools: {}
    });

    // Then register all tools
    this.tool('list_servers', 'List all Coolify servers', {}, async () => {
      const servers = await this.client.listServers();
      return {
        content: [{ type: 'text', text: JSON.stringify(servers, null, 2) }]
      };
    });

    this.tool('get_server', 'Get details about a specific Coolify server', {
      uuid: z.string().describe('UUID of the server to get details for')
    }, async (args) => {
      const server = await this.client.getServer(args.uuid);
      return {
        content: [{ type: 'text', text: JSON.stringify(server, null, 2) }]
      };
    });

    this.tool('get_server_resources', 'Get the current resources running on a specific Coolify server', {
      uuid: z.string()
    }, async (args, _extra) => {
      const resources = await this.client.getServerResources(args.uuid);
      return {
        content: [{ type: 'text', text: JSON.stringify(resources, null, 2) }]
      };
    });

    this.tool('get_server_domains', 'Get domains for a specific Coolify server', {
      uuid: z.string()
    }, async (args, _extra) => {
      const domains = await this.client.getServerDomains(args.uuid);
      return {
        content: [{ type: 'text', text: JSON.stringify(domains, null, 2) }]
      };
    });

    this.tool('validate_server', 'Validate a specific Coolify server', {
      uuid: z.string()
    }, async (args, _extra) => {
      const validation = await this.client.validateServer(args.uuid);
      return {
        content: [{ type: 'text', text: JSON.stringify(validation, null, 2) }]
      };
    });

    this.tool('list_projects', 'List all Coolify projects', {}, async (_args, _extra) => {
      const projects = await this.client.listProjects();
      return {
        content: [{ type: 'text', text: JSON.stringify(projects, null, 2) }]
      };
    });

    this.tool('get_project', 'Get details about a specific Coolify project', {
      uuid: z.string()
    }, async (args, _extra) => {
      const project = await this.client.getProject(args.uuid);
      return {
        content: [{ type: 'text', text: JSON.stringify(project, null, 2) }]
      };
    });

    this.tool('create_project', 'Create a new Coolify project', {
      name: z.string(),
      description: z.string().optional()
    }, async (args, _extra) => {
      const result = await this.client.createProject({
        name: args.name,
        description: args.description
      });
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
      };
    });

    this.tool('update_project', 'Update an existing Coolify project', {
      uuid: z.string(),
      name: z.string(),
      description: z.string().optional()
    }, async (args, _extra) => {
      const { uuid, ...updateData } = args;
      const result = await this.client.updateProject(uuid, updateData);
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
      };
    });

    this.tool('delete_project', 'Delete a Coolify project', {
      uuid: z.string()
    }, async (args, _extra) => {
      const result = await this.client.deleteProject(args.uuid);
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
      };
    });

    this.tool('get_project_environment', 'Get environment details for a Coolify project', {
      project_uuid: z.string(),
      environment_name_or_uuid: z.string()
    }, async (args, _extra) => {
      const environment = await this.client.getProjectEnvironment(args.project_uuid, args.environment_name_or_uuid);
      return {
        content: [{ type: 'text', text: JSON.stringify(environment, null, 2) }]
      };
    });

    this.tool('list_databases', 'List all Coolify databases', {}, async (_args, _extra) => {
      const databases = await this.client.listDatabases();
      return {
        content: [{ type: 'text', text: JSON.stringify(databases, null, 2) }]
      };
    });

    this.tool('get_database', 'Get details about a specific Coolify database', {
      uuid: z.string()
    }, async (args, _extra) => {
      const database = await this.client.getDatabase(args.uuid);
      return {
        content: [{ type: 'text', text: JSON.stringify(database, null, 2) }]
      };
    });

    this.tool('update_database', 'Update a Coolify database', {
      uuid: z.string(),
      data: z.record(z.unknown())
    }, async (args, _extra) => {
      const result = await this.client.updateDatabase(args.uuid, args.data);
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
      };
    });

    const deleteOptionsSchema = {
      deleteConfigurations: z.boolean().optional(),
      deleteVolumes: z.boolean().optional(),
      dockerCleanup: z.boolean().optional(),
      deleteConnectedNetworks: z.boolean().optional()
    };

    this.tool('delete_database', 'Delete a Coolify database', {
      uuid: z.string(),
      options: z.object(deleteOptionsSchema).optional()
    }, async (args, _extra) => {
      const result = await this.client.deleteDatabase(args.uuid, args.options);
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
      };
    });

    this.tool('deploy_application', 'Deploy a Coolify application', {
      uuid: z.string()
    }, async (args, _extra) => {
      const result = await this.client.deployApplication(args.uuid);
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
      };
    });

    this.tool('list_services', 'List all Coolify services', {}, async (_args, _extra) => {
      const services = await this.client.listServices();
      return {
        content: [{ type: 'text', text: JSON.stringify(services, null, 2) }]
      };
    });

    this.tool('get_service', 'Get details about a specific Coolify service', {
      uuid: z.string()
    }, async (args, _extra) => {
      const service = await this.client.getService(args.uuid);
      return {
        content: [{ type: 'text', text: JSON.stringify(service, null, 2) }]
      };
    });

    this.tool('create_service', 'Create a new Coolify service', {
      type: z.enum(serviceTypes),
      project_uuid: z.string(),
      server_uuid: z.string(),
      name: z.string().optional(),
      description: z.string().optional(),
      environment_name: z.string().optional(),
      environment_uuid: z.string().optional(),
      destination_uuid: z.string().optional(),
      instant_deploy: z.boolean().optional()
    }, async (args, _extra) => {
      const result = await this.client.createService(args);
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
      };
    });

    this.tool('delete_service', 'Delete a Coolify service', {
      uuid: z.string(),
      options: z.object(deleteOptionsSchema).optional()
    }, async (args, _extra) => {
      const result = await this.client.deleteService(args.uuid, args.options);
      return {
        content: [{ type: 'text', text: JSON.stringify(result, null, 2) }]
      };
    });
  }

  async connect(transport: Transport): Promise<void> {
    log('Starting server...');
    log('Validating connection...');
    await this.client.validateConnection();
    await this.initialize();
    await super.connect(transport);
    log('Server started successfully');
  }

  async list_servers(): Promise<ServerInfo[]> {
    return this.client.listServers();
  }

  async get_server(uuid: string): Promise<ServerInfo> {
    return this.client.getServer(uuid);
  }

  async get_server_resources(uuid: string): Promise<ServerResources> {
    return this.client.getServerResources(uuid);
  }

  async get_server_domains(uuid: string): Promise<ServerDomain[]> {
    return this.client.getServerDomains(uuid);
  }

  async validate_server(uuid: string): Promise<ValidationResponse> {
    return this.client.validateServer(uuid);
  }

  async list_projects(): Promise<Project[]> {
    return this.client.listProjects();
  }

  async get_project(uuid: string): Promise<Project> {
    return this.client.getProject(uuid);
  }

  async create_project(project: CreateProjectRequest): Promise<{ uuid: string }> {
    return this.client.createProject(project);
  }

  async update_project(uuid: string, project: UpdateProjectRequest): Promise<Project> {
    return this.client.updateProject(uuid, project);
  }

  async delete_project(uuid: string): Promise<{ message: string }> {
    return this.client.deleteProject(uuid);
  }

  async get_project_environment(
    projectUuid: string,
    environmentNameOrUuid: string,
  ): Promise<Environment> {
    return this.client.getProjectEnvironment(projectUuid, environmentNameOrUuid);
  }

  async deploy_application(params: { uuid: string }): Promise<Deployment> {
    return this.client.deployApplication(params.uuid);
  }

  async list_databases(): Promise<Database[]> {
    return this.client.listDatabases();
  }

  async get_database(uuid: string): Promise<Database> {
    return this.client.getDatabase(uuid);
  }

  async update_database(uuid: string, data: DatabaseUpdateRequest): Promise<Database> {
    return this.client.updateDatabase(uuid, data);
  }

  async delete_database(
    uuid: string,
    options?: {
      deleteConfigurations?: boolean;
      deleteVolumes?: boolean;
      dockerCleanup?: boolean;
      deleteConnectedNetworks?: boolean;
    },
  ): Promise<{ message: string }> {
    return this.client.deleteDatabase(uuid, options);
  }

  async list_services(): Promise<Service[]> {
    return this.client.listServices();
  }

  async get_service(uuid: string): Promise<Service> {
    return this.client.getService(uuid);
  }

  async create_service(data: CreateServiceRequest): Promise<{ uuid: string; domains: string[] }> {
    return this.client.createService(data);
  }

  async delete_service(uuid: string, options?: DeleteServiceOptions): Promise<{ message: string }> {
    return this.client.deleteService(uuid, options);
  }
}

```

--------------------------------------------------------------------------------
/docs/openapi-chunks/services-api.yaml:
--------------------------------------------------------------------------------

```yaml
openapi: 3.1.0
info:
  title: Coolify
  version: '0.1'
paths:
  /services:
    get:
      tags:
        - Services
      summary: List
      description: List all services.
      operationId: list-services
      responses:
        '200':
          description: Get all services
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Service'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
    post:
      tags:
        - Services
      summary: Create
      description: Create a one-click service
      operationId: create-service
      requestBody:
        required: true
        content:
          application/json:
            schema:
              required:
                - server_uuid
                - project_uuid
                - environment_name
                - environment_uuid
                - type
              properties:
                type:
                  description: The one-click service type
                  type: string
                  enum:
                    - activepieces
                    - appsmith
                    - appwrite
                    - authentik
                    - babybuddy
                    - budge
                    - changedetection
                    - chatwoot
                    - classicpress-with-mariadb
                    - classicpress-with-mysql
                    - classicpress-without-database
                    - cloudflared
                    - code-server
                    - dashboard
                    - directus
                    - directus-with-postgresql
                    - docker-registry
                    - docuseal
                    - docuseal-with-postgres
                    - dokuwiki
                    - duplicati
                    - emby
                    - embystat
                    - fider
                    - filebrowser
                    - firefly
                    - formbricks
                    - ghost
                    - gitea
                    - gitea-with-mariadb
                    - gitea-with-mysql
                    - gitea-with-postgresql
                    - glance
                    - glances
                    - glitchtip
                    - grafana
                    - grafana-with-postgresql
                    - grocy
                    - heimdall
                    - homepage
                    - jellyfin
                    - kuzzle
                    - listmonk
                    - logto
                    - mediawiki
                    - meilisearch
                    - metabase
                    - metube
                    - minio
                    - moodle
                    - n8n
                    - n8n-with-postgresql
                    - next-image-transformation
                    - nextcloud
                    - nocodb
                    - odoo
                    - openblocks
                    - pairdrop
                    - penpot
                    - phpmyadmin
                    - pocketbase
                    - posthog
                    - reactive-resume
                    - rocketchat
                    - shlink
                    - slash
                    - snapdrop
                    - statusnook
                    - stirling-pdf
                    - supabase
                    - syncthing
                    - tolgee
                    - trigger
                    - trigger-with-external-database
                    - twenty
                    - umami
                    - unleash-with-postgresql
                    - unleash-without-database
                    - uptime-kuma
                    - vaultwarden
                    - vikunja
                    - weblate
                    - whoogle
                    - wordpress-with-mariadb
                    - wordpress-with-mysql
                    - wordpress-without-database
                name:
                  type: string
                  maxLength: 255
                  description: Name of the service.
                description:
                  type: string
                  nullable: true
                  description: Description of the service.
                project_uuid:
                  type: string
                  description: Project UUID.
                environment_name:
                  type: string
                  description: Environment name. You need to provide at least one of environment_name or environment_uuid.
                environment_uuid:
                  type: string
                  description: Environment UUID. You need to provide at least one of environment_name or environment_uuid.
                server_uuid:
                  type: string
                  description: Server UUID.
                destination_uuid:
                  type: string
                  description: Destination UUID. Required if server has multiple destinations.
                instant_deploy:
                  type: boolean
                  default: false
                  description: Start the service immediately after creation.
              type: object
      responses:
        '201':
          description: Create a service.
          content:
            application/json:
              schema:
                properties:
                  uuid:
                    type: string
                    description: Service UUID.
                  domains:
                    type: array
                    items:
                      type: string
                    description: Service domains.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /services/{uuid}:
    get:
      tags:
        - Services
      summary: Get
      description: Get service by UUID.
      operationId: get-service-by-uuid
      parameters:
        - name: uuid
          in: path
          description: Service UUID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Get a service by UUID.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Service'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
    delete:
      tags:
        - Services
      summary: Delete
      description: Delete service by UUID.
      operationId: delete-service-by-uuid
      parameters:
        - name: uuid
          in: path
          description: Service UUID
          required: true
          schema:
            type: string
        - name: delete_configurations
          in: query
          description: Delete configurations.
          required: false
          schema:
            type: boolean
            default: true
        - name: delete_volumes
          in: query
          description: Delete volumes.
          required: false
          schema:
            type: boolean
            default: true
        - name: docker_cleanup
          in: query
          description: Run docker cleanup.
          required: false
          schema:
            type: boolean
            default: true
        - name: delete_connected_networks
          in: query
          description: Delete connected networks.
          required: false
          schema:
            type: boolean
            default: true
      responses:
        '200':
          description: Delete a service by UUID
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Service deletion request queued.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /services/{uuid}/envs:
    get:
      tags:
        - Services
      summary: List Envs
      description: List all envs by service UUID.
      operationId: list-envs-by-service-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the service.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: All environment variables by service UUID.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/EnvironmentVariable'
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
    post:
      tags:
        - Services
      summary: Create Env
      description: Create env by service UUID.
      operationId: create-env-by-service-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the service.
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        description: Env created.
        required: true
        content:
          application/json:
            schema:
              properties:
                key:
                  type: string
                  description: The key of the environment variable.
                value:
                  type: string
                  description: The value of the environment variable.
                is_preview:
                  type: boolean
                  description: The flag to indicate if the environment variable is used in preview deployments.
                is_build_time:
                  type: boolean
                  description: The flag to indicate if the environment variable is used in build time.
                is_literal:
                  type: boolean
                  description: The flag to indicate if the environment variable is a literal, nothing espaced.
                is_multiline:
                  type: boolean
                  description: The flag to indicate if the environment variable is multiline.
                is_shown_once:
                  type: boolean
                  description: The flag to indicate if the environment variable's value is shown on the UI.
              type: object
      responses:
        '201':
          description: Environment variable created.
          content:
            application/json:
              schema:
                properties:
                  uuid:
                    type: string
                    example: nc0k04gk8g0cgsk440g0koko
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
    patch:
      tags:
        - Services
      summary: Update Env
      description: Update env by service UUID.
      operationId: update-env-by-service-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the service.
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        description: Env updated.
        required: true
        content:
          application/json:
            schema:
              required:
                - key
                - value
              properties:
                key:
                  type: string
                  description: The key of the environment variable.
                value:
                  type: string
                  description: The value of the environment variable.
                is_preview:
                  type: boolean
                  description: The flag to indicate if the environment variable is used in preview deployments.
                is_build_time:
                  type: boolean
                  description: The flag to indicate if the environment variable is used in build time.
                is_literal:
                  type: boolean
                  description: The flag to indicate if the environment variable is a literal, nothing espaced.
                is_multiline:
                  type: boolean
                  description: The flag to indicate if the environment variable is multiline.
                is_shown_once:
                  type: boolean
                  description: The flag to indicate if the environment variable's value is shown on the UI.
              type: object
      responses:
        '201':
          description: Environment variable updated.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Environment variable updated.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /services/{uuid}/envs/bulk:
    patch:
      tags:
        - Services
      summary: Update Envs (Bulk)
      description: Update multiple envs by service UUID.
      operationId: update-envs-by-service-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the service.
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        description: Bulk envs updated.
        required: true
        content:
          application/json:
            schema:
              required:
                - data
              properties:
                data:
                  type: array
                  items:
                    properties:
                      key:
                        type: string
                        description: The key of the environment variable.
                      value:
                        type: string
                        description: The value of the environment variable.
                      is_preview:
                        type: boolean
                        description: The flag to indicate if the environment variable is used in preview deployments.
                      is_build_time:
                        type: boolean
                        description: The flag to indicate if the environment variable is used in build time.
                      is_literal:
                        type: boolean
                        description: The flag to indicate if the environment variable is a literal, nothing espaced.
                      is_multiline:
                        type: boolean
                        description: The flag to indicate if the environment variable is multiline.
                      is_shown_once:
                        type: boolean
                        description: The flag to indicate if the environment variable's value is shown on the UI.
                    type: object
              type: object
      responses:
        '201':
          description: Environment variables updated.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Environment variables updated.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /services/{uuid}/envs/{env_uuid}:
    delete:
      tags:
        - Services
      summary: Delete Env
      description: Delete env by UUID.
      operationId: delete-env-by-service-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the service.
          required: true
          schema:
            type: string
            format: uuid
        - name: env_uuid
          in: path
          description: UUID of the environment variable.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Environment variable deleted.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Environment variable deleted.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /services/{uuid}/start:
    get:
      tags:
        - Services
      summary: Start
      description: Start service. `Post` request is also accepted.
      operationId: start-service-by-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the service.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Start service.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Service starting request queued.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /services/{uuid}/stop:
    get:
      tags:
        - Services
      summary: Stop
      description: Stop service. `Post` request is also accepted.
      operationId: stop-service-by-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the service.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Stop service.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Service stopping request queued.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /services/{uuid}/restart:
    get:
      tags:
        - Services
      summary: Restart
      description: Restart service. `Post` request is also accepted.
      operationId: restart-service-by-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the service.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Restart service.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Service restaring request queued.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []

```

--------------------------------------------------------------------------------
/docs/openapi-chunks/schemas.yaml:
--------------------------------------------------------------------------------

```yaml
openapi: 3.1.0
info:
  title: Coolify
  version: '0.1'
paths: {}
components:
  schemas:
    Application:
      description: Application model
      properties:
        id:
          type: integer
          description: The application identifier in the database.
        description:
          type: string
          nullable: true
          description: The application description.
        repository_project_id:
          type: integer
          nullable: true
          description: The repository project identifier.
        uuid:
          type: string
          description: The application UUID.
        name:
          type: string
          description: The application name.
        fqdn:
          type: string
          nullable: true
          description: The application domains.
        config_hash:
          type: string
          description: Configuration hash.
        git_repository:
          type: string
          description: Git repository URL.
        git_branch:
          type: string
          description: Git branch.
        git_commit_sha:
          type: string
          description: Git commit SHA.
        git_full_url:
          type: string
          nullable: true
          description: Git full URL.
        docker_registry_image_name:
          type: string
          nullable: true
          description: Docker registry image name.
        docker_registry_image_tag:
          type: string
          nullable: true
          description: Docker registry image tag.
        build_pack:
          type: string
          description: Build pack.
          enum:
            - nixpacks
            - static
            - dockerfile
            - dockercompose
        static_image:
          type: string
          description: Static image used when static site is deployed.
        install_command:
          type: string
          description: Install command.
        build_command:
          type: string
          description: Build command.
        start_command:
          type: string
          description: Start command.
        ports_exposes:
          type: string
          description: Ports exposes.
        ports_mappings:
          type: string
          nullable: true
          description: Ports mappings.
        base_directory:
          type: string
          description: Base directory for all commands.
        publish_directory:
          type: string
          description: Publish directory.
        health_check_enabled:
          type: boolean
          description: Health check enabled.
        health_check_path:
          type: string
          description: Health check path.
        health_check_port:
          type: string
          nullable: true
          description: Health check port.
        health_check_host:
          type: string
          nullable: true
          description: Health check host.
        health_check_method:
          type: string
          description: Health check method.
        health_check_return_code:
          type: integer
          description: Health check return code.
        health_check_scheme:
          type: string
          description: Health check scheme.
        health_check_response_text:
          type: string
          nullable: true
          description: Health check response text.
        health_check_interval:
          type: integer
          description: Health check interval in seconds.
        health_check_timeout:
          type: integer
          description: Health check timeout in seconds.
        health_check_retries:
          type: integer
          description: Health check retries count.
        health_check_start_period:
          type: integer
          description: Health check start period in seconds.
        limits_memory:
          type: string
          description: Memory limit.
        limits_memory_swap:
          type: string
          description: Memory swap limit.
        limits_memory_swappiness:
          type: integer
          description: Memory swappiness.
        limits_memory_reservation:
          type: string
          description: Memory reservation.
        limits_cpus:
          type: string
          description: CPU limit.
        limits_cpuset:
          type: string
          nullable: true
          description: CPU set.
        limits_cpu_shares:
          type: integer
          description: CPU shares.
        status:
          type: string
          description: Application status.
        preview_url_template:
          type: string
          description: Preview URL template.
        destination_type:
          type: string
          description: Destination type.
        destination_id:
          type: integer
          description: Destination identifier.
        source_id:
          type: integer
          nullable: true
          description: Source identifier.
        private_key_id:
          type: integer
          nullable: true
          description: Private key identifier.
        environment_id:
          type: integer
          description: Environment identifier.
        dockerfile:
          type: string
          nullable: true
          description: Dockerfile content. Used for dockerfile build pack.
        dockerfile_location:
          type: string
          description: Dockerfile location.
        custom_labels:
          type: string
          nullable: true
          description: Custom labels.
        dockerfile_target_build:
          type: string
          nullable: true
          description: Dockerfile target build.
        manual_webhook_secret_github:
          type: string
          nullable: true
          description: Manual webhook secret for GitHub.
        manual_webhook_secret_gitlab:
          type: string
          nullable: true
          description: Manual webhook secret for GitLab.
        manual_webhook_secret_bitbucket:
          type: string
          nullable: true
          description: Manual webhook secret for Bitbucket.
        manual_webhook_secret_gitea:
          type: string
          nullable: true
          description: Manual webhook secret for Gitea.
        docker_compose_location:
          type: string
          description: Docker compose location.
        docker_compose:
          type: string
          nullable: true
          description: Docker compose content. Used for docker compose build pack.
        docker_compose_raw:
          type: string
          nullable: true
          description: Docker compose raw content.
        docker_compose_domains:
          type: string
          nullable: true
          description: Docker compose domains.
        docker_compose_custom_start_command:
          type: string
          nullable: true
          description: Docker compose custom start command.
        docker_compose_custom_build_command:
          type: string
          nullable: true
          description: Docker compose custom build command.
        swarm_replicas:
          type: integer
          nullable: true
          description: Swarm replicas. Only used for swarm deployments.
        swarm_placement_constraints:
          type: string
          nullable: true
          description: Swarm placement constraints. Only used for swarm deployments.
        custom_docker_run_options:
          type: string
          nullable: true
          description: Custom docker run options.
        post_deployment_command:
          type: string
          nullable: true
          description: Post deployment command.
        post_deployment_command_container:
          type: string
          nullable: true
          description: Post deployment command container.
        pre_deployment_command:
          type: string
          nullable: true
          description: Pre deployment command.
        pre_deployment_command_container:
          type: string
          nullable: true
          description: Pre deployment command container.
        watch_paths:
          type: string
          nullable: true
          description: Watch paths.
        custom_healthcheck_found:
          type: boolean
          description: Custom healthcheck found.
        redirect:
          type: string
          nullable: true
          description: How to set redirect with Traefik / Caddy. www<->non-www.
          enum:
            - www
            - non-www
            - both
        created_at:
          type: string
          format: date-time
          description: The date and time when the application was created.
        updated_at:
          type: string
          format: date-time
          description: The date and time when the application was last updated.
        deleted_at:
          type: string
          format: date-time
          nullable: true
          description: The date and time when the application was deleted.
        compose_parsing_version:
          type: string
          description: How Coolify parse the compose file.
        custom_nginx_configuration:
          type: string
          nullable: true
          description: Custom Nginx configuration base64 encoded.
      type: object
    ApplicationDeploymentQueue:
      description: Project model
      properties:
        id:
          type: integer
        application_id:
          type: string
        deployment_uuid:
          type: string
        pull_request_id:
          type: integer
        force_rebuild:
          type: boolean
        commit:
          type: string
        status:
          type: string
        is_webhook:
          type: boolean
        is_api:
          type: boolean
        created_at:
          type: string
        updated_at:
          type: string
        logs:
          type: string
        current_process_id:
          type: string
        restart_only:
          type: boolean
        git_type:
          type: string
        server_id:
          type: integer
        application_name:
          type: string
        server_name:
          type: string
        deployment_url:
          type: string
        destination_id:
          type: string
        only_this_server:
          type: boolean
        rollback:
          type: boolean
        commit_message:
          type: string
      type: object
    Environment:
      description: Environment model
      properties:
        id:
          type: integer
        name:
          type: string
        project_id:
          type: integer
        created_at:
          type: string
        updated_at:
          type: string
        description:
          type: string
      type: object
    EnvironmentVariable:
      description: Environment Variable model
      properties:
        id:
          type: integer
        uuid:
          type: string
        resourceable_type:
          type: string
        resourceable_id:
          type: integer
        is_build_time:
          type: boolean
        is_literal:
          type: boolean
        is_multiline:
          type: boolean
        is_preview:
          type: boolean
        is_shared:
          type: boolean
        is_shown_once:
          type: boolean
        key:
          type: string
        value:
          type: string
        real_value:
          type: string
        version:
          type: string
        created_at:
          type: string
        updated_at:
          type: string
      type: object
    PrivateKey:
      description: Private Key model
      properties:
        id:
          type: integer
        uuid:
          type: string
        name:
          type: string
        description:
          type: string
        private_key:
          type: string
          format: private-key
        is_git_related:
          type: boolean
        team_id:
          type: integer
        created_at:
          type: string
        updated_at:
          type: string
      type: object
    Project:
      description: Project model
      properties:
        id:
          type: integer
        uuid:
          type: string
        name:
          type: string
        description:
          type: string
        environments:
          description: The environments of the project.
          type: array
          items:
            $ref: '#/components/schemas/Environment'
      type: object
    Server:
      description: Server model
      properties:
        id:
          type: integer
          description: The server ID.
        uuid:
          type: string
          description: The server UUID.
        name:
          type: string
          description: The server name.
        description:
          type: string
          description: The server description.
        ip:
          type: string
          description: The IP address.
        user:
          type: string
          description: The user.
        port:
          type: integer
          description: The port number.
        proxy:
          type: object
          description: The proxy configuration.
        proxy_type:
          type: string
          enum:
            - traefik
            - caddy
            - none
          description: The proxy type.
        high_disk_usage_notification_sent:
          type: boolean
          description: The flag to indicate if the high disk usage notification has been sent.
        unreachable_notification_sent:
          type: boolean
          description: The flag to indicate if the unreachable notification has been sent.
        unreachable_count:
          type: integer
          description: The unreachable count for your server.
        validation_logs:
          type: string
          description: The validation logs.
        log_drain_notification_sent:
          type: boolean
          description: The flag to indicate if the log drain notification has been sent.
        swarm_cluster:
          type: string
          description: The swarm cluster configuration.
        settings:
          $ref: '#/components/schemas/ServerSetting'
      type: object
    ServerSetting:
      description: Server Settings model
      properties:
        id:
          type: integer
        concurrent_builds:
          type: integer
        dynamic_timeout:
          type: integer
        force_disabled:
          type: boolean
        force_server_cleanup:
          type: boolean
        is_build_server:
          type: boolean
        is_cloudflare_tunnel:
          type: boolean
        is_jump_server:
          type: boolean
        is_logdrain_axiom_enabled:
          type: boolean
        is_logdrain_custom_enabled:
          type: boolean
        is_logdrain_highlight_enabled:
          type: boolean
        is_logdrain_newrelic_enabled:
          type: boolean
        is_metrics_enabled:
          type: boolean
        is_reachable:
          type: boolean
        is_sentinel_enabled:
          type: boolean
        is_swarm_manager:
          type: boolean
        is_swarm_worker:
          type: boolean
        is_usable:
          type: boolean
        logdrain_axiom_api_key:
          type: string
        logdrain_axiom_dataset_name:
          type: string
        logdrain_custom_config:
          type: string
        logdrain_custom_config_parser:
          type: string
        logdrain_highlight_project_id:
          type: string
        logdrain_newrelic_base_uri:
          type: string
        logdrain_newrelic_license_key:
          type: string
        sentinel_metrics_history_days:
          type: integer
        sentinel_metrics_refresh_rate_seconds:
          type: integer
        sentinel_token:
          type: string
        docker_cleanup_frequency:
          type: string
        docker_cleanup_threshold:
          type: integer
        server_id:
          type: integer
        wildcard_domain:
          type: string
        created_at:
          type: string
        updated_at:
          type: string
        delete_unused_volumes:
          type: boolean
          description: The flag to indicate if the unused volumes should be deleted.
        delete_unused_networks:
          type: boolean
          description: The flag to indicate if the unused networks should be deleted.
      type: object
    Service:
      description: Service model
      properties:
        id:
          type: integer
          description: The unique identifier of the service. Only used for database identification.
        uuid:
          type: string
          description: The unique identifier of the service.
        name:
          type: string
          description: The name of the service.
        environment_id:
          type: integer
          description: The unique identifier of the environment where the service is attached to.
        server_id:
          type: integer
          description: The unique identifier of the server where the service is running.
        description:
          type: string
          description: The description of the service.
        docker_compose_raw:
          type: string
          description: The raw docker-compose.yml file of the service.
        docker_compose:
          type: string
          description: The docker-compose.yml file that is parsed and modified by Coolify.
        destination_type:
          type: string
          description: Destination type.
        destination_id:
          type: integer
          description: The unique identifier of the destination where the service is running.
        connect_to_docker_network:
          type: boolean
          description: The flag to connect the service to the predefined Docker network.
        is_container_label_escape_enabled:
          type: boolean
          description: The flag to enable the container label escape.
        is_container_label_readonly_enabled:
          type: boolean
          description: The flag to enable the container label readonly.
        config_hash:
          type: string
          description: The hash of the service configuration.
        service_type:
          type: string
          description: The type of the service.
        created_at:
          type: string
          description: The date and time when the service was created.
        updated_at:
          type: string
          description: The date and time when the service was last updated.
        deleted_at:
          type: string
          description: The date and time when the service was deleted.
      type: object
    Team:
      description: Team model
      properties:
        id:
          type: integer
          description: The unique identifier of the team.
        name:
          type: string
          description: The name of the team.
        description:
          type: string
          description: The description of the team.
        personal_team:
          type: boolean
          description: Whether the team is personal or not.
        created_at:
          type: string
          description: The date and time the team was created.
        updated_at:
          type: string
          description: The date and time the team was last updated.
        show_boarding:
          type: boolean
          description: Whether to show the boarding screen or not.
        custom_server_limit:
          type: string
          description: The custom server limit.
        members:
          description: The members of the team.
          type: array
          items:
            $ref: '#/components/schemas/User'
      type: object
    User:
      description: User model
      properties:
        id:
          type: integer
          description: The user identifier in the database.
        name:
          type: string
          description: The user name.
        email:
          type: string
          description: The user email.
        email_verified_at:
          type: string
          description: The date when the user email was verified.
        created_at:
          type: string
          description: The date when the user was created.
        updated_at:
          type: string
          description: The date when the user was updated.
        two_factor_confirmed_at:
          type: string
          description: The date when the user two factor was confirmed.
        force_password_reset:
          type: boolean
          description: The flag to force the user to reset the password.
        marketing_emails:
          type: boolean
          description: The flag to receive marketing emails.
      type: object

```

--------------------------------------------------------------------------------
/docs/openapi-chunks/databases-api.yaml:
--------------------------------------------------------------------------------

```yaml
openapi: 3.1.0
info:
  title: Coolify
  version: '0.1'
paths:
  /databases:
    get:
      tags:
        - Databases
      summary: List
      description: List all databases.
      operationId: list-databases
      responses:
        '200':
          description: Get all databases
          content:
            application/json:
              schema:
                type: string
              example: Content is very complex. Will be implemented later.
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /databases/{uuid}:
    get:
      tags:
        - Databases
      summary: Get
      description: Get database by UUID.
      operationId: get-database-by-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the database.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Get all databases
          content:
            application/json:
              schema:
                type: string
              example: Content is very complex. Will be implemented later.
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
    delete:
      tags:
        - Databases
      summary: Delete
      description: Delete database by UUID.
      operationId: delete-database-by-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the database.
          required: true
          schema:
            type: string
            format: uuid
        - name: delete_configurations
          in: query
          description: Delete configurations.
          required: false
          schema:
            type: boolean
            default: true
        - name: delete_volumes
          in: query
          description: Delete volumes.
          required: false
          schema:
            type: boolean
            default: true
        - name: docker_cleanup
          in: query
          description: Run docker cleanup.
          required: false
          schema:
            type: boolean
            default: true
        - name: delete_connected_networks
          in: query
          description: Delete connected networks.
          required: false
          schema:
            type: boolean
            default: true
      responses:
        '200':
          description: Database deleted.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Database deleted.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
    patch:
      tags:
        - Databases
      summary: Update
      description: Update database by UUID.
      operationId: update-database-by-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the database.
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        description: Database data
        required: true
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Name of the database
                description:
                  type: string
                  description: Description of the database
                image:
                  type: string
                  description: Docker Image of the database
                is_public:
                  type: boolean
                  description: Is the database public?
                public_port:
                  type: integer
                  description: Public port of the database
                limits_memory:
                  type: string
                  description: Memory limit of the database
                limits_memory_swap:
                  type: string
                  description: Memory swap limit of the database
                limits_memory_swappiness:
                  type: integer
                  description: Memory swappiness of the database
                limits_memory_reservation:
                  type: string
                  description: Memory reservation of the database
                limits_cpus:
                  type: string
                  description: CPU limit of the database
                limits_cpuset:
                  type: string
                  description: CPU set of the database
                limits_cpu_shares:
                  type: integer
                  description: CPU shares of the database
                postgres_user:
                  type: string
                  description: PostgreSQL user
                postgres_password:
                  type: string
                  description: PostgreSQL password
                postgres_db:
                  type: string
                  description: PostgreSQL database
                postgres_initdb_args:
                  type: string
                  description: PostgreSQL initdb args
                postgres_host_auth_method:
                  type: string
                  description: PostgreSQL host auth method
                postgres_conf:
                  type: string
                  description: PostgreSQL conf
                clickhouse_admin_user:
                  type: string
                  description: Clickhouse admin user
                clickhouse_admin_password:
                  type: string
                  description: Clickhouse admin password
                dragonfly_password:
                  type: string
                  description: DragonFly password
                redis_password:
                  type: string
                  description: Redis password
                redis_conf:
                  type: string
                  description: Redis conf
                keydb_password:
                  type: string
                  description: KeyDB password
                keydb_conf:
                  type: string
                  description: KeyDB conf
                mariadb_conf:
                  type: string
                  description: MariaDB conf
                mariadb_root_password:
                  type: string
                  description: MariaDB root password
                mariadb_user:
                  type: string
                  description: MariaDB user
                mariadb_password:
                  type: string
                  description: MariaDB password
                mariadb_database:
                  type: string
                  description: MariaDB database
                mongo_conf:
                  type: string
                  description: Mongo conf
                mongo_initdb_root_username:
                  type: string
                  description: Mongo initdb root username
                mongo_initdb_root_password:
                  type: string
                  description: Mongo initdb root password
                mongo_initdb_database:
                  type: string
                  description: Mongo initdb init database
                mysql_root_password:
                  type: string
                  description: MySQL root password
                mysql_password:
                  type: string
                  description: MySQL password
                mysql_user:
                  type: string
                  description: MySQL user
                mysql_database:
                  type: string
                  description: MySQL database
                mysql_conf:
                  type: string
                  description: MySQL conf
              type: object
      responses:
        '200':
          description: Database updated
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /databases/postgresql:
    post:
      tags:
        - Databases
      summary: Create (PostgreSQL)
      description: Create a new PostgreSQL database.
      operationId: create-database-postgresql
      requestBody:
        description: Database data
        required: true
        content:
          application/json:
            schema:
              required:
                - server_uuid
                - project_uuid
                - environment_name
                - environment_uuid
              properties:
                server_uuid:
                  type: string
                  description: UUID of the server
                project_uuid:
                  type: string
                  description: UUID of the project
                environment_name:
                  type: string
                  description: Name of the environment. You need to provide at least one of environment_name or environment_uuid.
                environment_uuid:
                  type: string
                  description: UUID of the environment. You need to provide at least one of environment_name or environment_uuid.
                postgres_user:
                  type: string
                  description: PostgreSQL user
                postgres_password:
                  type: string
                  description: PostgreSQL password
                postgres_db:
                  type: string
                  description: PostgreSQL database
                postgres_initdb_args:
                  type: string
                  description: PostgreSQL initdb args
                postgres_host_auth_method:
                  type: string
                  description: PostgreSQL host auth method
                postgres_conf:
                  type: string
                  description: PostgreSQL conf
                destination_uuid:
                  type: string
                  description: UUID of the destination if the server has multiple destinations
                name:
                  type: string
                  description: Name of the database
                description:
                  type: string
                  description: Description of the database
                image:
                  type: string
                  description: Docker Image of the database
                is_public:
                  type: boolean
                  description: Is the database public?
                public_port:
                  type: integer
                  description: Public port of the database
                limits_memory:
                  type: string
                  description: Memory limit of the database
                limits_memory_swap:
                  type: string
                  description: Memory swap limit of the database
                limits_memory_swappiness:
                  type: integer
                  description: Memory swappiness of the database
                limits_memory_reservation:
                  type: string
                  description: Memory reservation of the database
                limits_cpus:
                  type: string
                  description: CPU limit of the database
                limits_cpuset:
                  type: string
                  description: CPU set of the database
                limits_cpu_shares:
                  type: integer
                  description: CPU shares of the database
                instant_deploy:
                  type: boolean
                  description: Instant deploy the database
              type: object
      responses:
        '200':
          description: Database updated
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /databases/clickhouse:
    post:
      tags:
        - Databases
      summary: Create (Clickhouse)
      description: Create a new Clickhouse database.
      operationId: create-database-clickhouse
      requestBody:
        description: Database data
        required: true
        content:
          application/json:
            schema:
              required:
                - server_uuid
                - project_uuid
                - environment_name
                - environment_uuid
              properties:
                server_uuid:
                  type: string
                  description: UUID of the server
                project_uuid:
                  type: string
                  description: UUID of the project
                environment_name:
                  type: string
                  description: Name of the environment. You need to provide at least one of environment_name or environment_uuid.
                environment_uuid:
                  type: string
                  description: UUID of the environment. You need to provide at least one of environment_name or environment_uuid.
                destination_uuid:
                  type: string
                  description: UUID of the destination if the server has multiple destinations
                clickhouse_admin_user:
                  type: string
                  description: Clickhouse admin user
                clickhouse_admin_password:
                  type: string
                  description: Clickhouse admin password
                name:
                  type: string
                  description: Name of the database
                description:
                  type: string
                  description: Description of the database
                image:
                  type: string
                  description: Docker Image of the database
                is_public:
                  type: boolean
                  description: Is the database public?
                public_port:
                  type: integer
                  description: Public port of the database
                limits_memory:
                  type: string
                  description: Memory limit of the database
                limits_memory_swap:
                  type: string
                  description: Memory swap limit of the database
                limits_memory_swappiness:
                  type: integer
                  description: Memory swappiness of the database
                limits_memory_reservation:
                  type: string
                  description: Memory reservation of the database
                limits_cpus:
                  type: string
                  description: CPU limit of the database
                limits_cpuset:
                  type: string
                  description: CPU set of the database
                limits_cpu_shares:
                  type: integer
                  description: CPU shares of the database
                instant_deploy:
                  type: boolean
                  description: Instant deploy the database
              type: object
      responses:
        '200':
          description: Database updated
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /databases/dragonfly:
    post:
      tags:
        - Databases
      summary: Create (DragonFly)
      description: Create a new DragonFly database.
      operationId: create-database-dragonfly
      requestBody:
        description: Database data
        required: true
        content:
          application/json:
            schema:
              required:
                - server_uuid
                - project_uuid
                - environment_name
                - environment_uuid
              properties:
                server_uuid:
                  type: string
                  description: UUID of the server
                project_uuid:
                  type: string
                  description: UUID of the project
                environment_name:
                  type: string
                  description: Name of the environment. You need to provide at least one of environment_name or environment_uuid.
                environment_uuid:
                  type: string
                  description: UUID of the environment. You need to provide at least one of environment_name or environment_uuid.
                destination_uuid:
                  type: string
                  description: UUID of the destination if the server has multiple destinations
                dragonfly_password:
                  type: string
                  description: DragonFly password
                name:
                  type: string
                  description: Name of the database
                description:
                  type: string
                  description: Description of the database
                image:
                  type: string
                  description: Docker Image of the database
                is_public:
                  type: boolean
                  description: Is the database public?
                public_port:
                  type: integer
                  description: Public port of the database
                limits_memory:
                  type: string
                  description: Memory limit of the database
                limits_memory_swap:
                  type: string
                  description: Memory swap limit of the database
                limits_memory_swappiness:
                  type: integer
                  description: Memory swappiness of the database
                limits_memory_reservation:
                  type: string
                  description: Memory reservation of the database
                limits_cpus:
                  type: string
                  description: CPU limit of the database
                limits_cpuset:
                  type: string
                  description: CPU set of the database
                limits_cpu_shares:
                  type: integer
                  description: CPU shares of the database
                instant_deploy:
                  type: boolean
                  description: Instant deploy the database
              type: object
      responses:
        '200':
          description: Database updated
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /databases/redis:
    post:
      tags:
        - Databases
      summary: Create (Redis)
      description: Create a new Redis database.
      operationId: create-database-redis
      requestBody:
        description: Database data
        required: true
        content:
          application/json:
            schema:
              required:
                - server_uuid
                - project_uuid
                - environment_name
                - environment_uuid
              properties:
                server_uuid:
                  type: string
                  description: UUID of the server
                project_uuid:
                  type: string
                  description: UUID of the project
                environment_name:
                  type: string
                  description: Name of the environment. You need to provide at least one of environment_name or environment_uuid.
                environment_uuid:
                  type: string
                  description: UUID of the environment. You need to provide at least one of environment_name or environment_uuid.
                destination_uuid:
                  type: string
                  description: UUID of the destination if the server has multiple destinations
                redis_password:
                  type: string
                  description: Redis password
                redis_conf:
                  type: string
                  description: Redis conf
                name:
                  type: string
                  description: Name of the database
                description:
                  type: string
                  description: Description of the database
                image:
                  type: string
                  description: Docker Image of the database
                is_public:
                  type: boolean
                  description: Is the database public?
                public_port:
                  type: integer
                  description: Public port of the database
                limits_memory:
                  type: string
                  description: Memory limit of the database
                limits_memory_swap:
                  type: string
                  description: Memory swap limit of the database
                limits_memory_swappiness:
                  type: integer
                  description: Memory swappiness of the database
                limits_memory_reservation:
                  type: string
                  description: Memory reservation of the database
                limits_cpus:
                  type: string
                  description: CPU limit of the database
                limits_cpuset:
                  type: string
                  description: CPU set of the database
                limits_cpu_shares:
                  type: integer
                  description: CPU shares of the database
                instant_deploy:
                  type: boolean
                  description: Instant deploy the database
              type: object
      responses:
        '200':
          description: Database updated
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /databases/keydb:
    post:
      tags:
        - Databases
      summary: Create (KeyDB)
      description: Create a new KeyDB database.
      operationId: create-database-keydb
      requestBody:
        description: Database data
        required: true
        content:
          application/json:
            schema:
              required:
                - server_uuid
                - project_uuid
                - environment_name
                - environment_uuid
              properties:
                server_uuid:
                  type: string
                  description: UUID of the server
                project_uuid:
                  type: string
                  description: UUID of the project
                environment_name:
                  type: string
                  description: Name of the environment. You need to provide at least one of environment_name or environment_uuid.
                environment_uuid:
                  type: string
                  description: UUID of the environment. You need to provide at least one of environment_name or environment_uuid.
                destination_uuid:
                  type: string
                  description: UUID of the destination if the server has multiple destinations
                keydb_password:
                  type: string
                  description: KeyDB password
                keydb_conf:
                  type: string
                  description: KeyDB conf
                name:
                  type: string
                  description: Name of the database
                description:
                  type: string
                  description: Description of the database
                image:
                  type: string
                  description: Docker Image of the database
                is_public:
                  type: boolean
                  description: Is the database public?
                public_port:
                  type: integer
                  description: Public port of the database
                limits_memory:
                  type: string
                  description: Memory limit of the database
                limits_memory_swap:
                  type: string
                  description: Memory swap limit of the database
                limits_memory_swappiness:
                  type: integer
                  description: Memory swappiness of the database
                limits_memory_reservation:
                  type: string
                  description: Memory reservation of the database
                limits_cpus:
                  type: string
                  description: CPU limit of the database
                limits_cpuset:
                  type: string
                  description: CPU set of the database
                limits_cpu_shares:
                  type: integer
                  description: CPU shares of the database
                instant_deploy:
                  type: boolean
                  description: Instant deploy the database
              type: object
      responses:
        '200':
          description: Database updated
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /databases/mariadb:
    post:
      tags:
        - Databases
      summary: Create (MariaDB)
      description: Create a new MariaDB database.
      operationId: create-database-mariadb
      requestBody:
        description: Database data
        required: true
        content:
          application/json:
            schema:
              required:
                - server_uuid
                - project_uuid
                - environment_name
                - environment_uuid
              properties:
                server_uuid:
                  type: string
                  description: UUID of the server
                project_uuid:
                  type: string
                  description: UUID of the project
                environment_name:
                  type: string
                  description: Name of the environment. You need to provide at least one of environment_name or environment_uuid.
                environment_uuid:
                  type: string
                  description: UUID of the environment. You need to provide at least one of environment_name or environment_uuid.
                destination_uuid:
                  type: string
                  description: UUID of the destination if the server has multiple destinations
                mariadb_conf:
                  type: string
                  description: MariaDB conf
                mariadb_root_password:
                  type: string
                  description: MariaDB root password
                mariadb_user:
                  type: string
                  description: MariaDB user
                mariadb_password:
                  type: string
                  description: MariaDB password
                mariadb_database:
                  type: string
                  description: MariaDB database
                name:
                  type: string
                  description: Name of the database
                description:
                  type: string
                  description: Description of the database
                image:
                  type: string
                  description: Docker Image of the database
                is_public:
                  type: boolean
                  description: Is the database public?
                public_port:
                  type: integer
                  description: Public port of the database
                limits_memory:
                  type: string
                  description: Memory limit of the database
                limits_memory_swap:
                  type: string
                  description: Memory swap limit of the database
                limits_memory_swappiness:
                  type: integer
                  description: Memory swappiness of the database
                limits_memory_reservation:
                  type: string
                  description: Memory reservation of the database
                limits_cpus:
                  type: string
                  description: CPU limit of the database
                limits_cpuset:
                  type: string
                  description: CPU set of the database
                limits_cpu_shares:
                  type: integer
                  description: CPU shares of the database
                instant_deploy:
                  type: boolean
                  description: Instant deploy the database
              type: object
      responses:
        '200':
          description: Database updated
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /databases/mysql:
    post:
      tags:
        - Databases
      summary: Create (MySQL)
      description: Create a new MySQL database.
      operationId: create-database-mysql
      requestBody:
        description: Database data
        required: true
        content:
          application/json:
            schema:
              required:
                - server_uuid
                - project_uuid
                - environment_name
                - environment_uuid
              properties:
                server_uuid:
                  type: string
                  description: UUID of the server
                project_uuid:
                  type: string
                  description: UUID of the project
                environment_name:
                  type: string
                  description: Name of the environment. You need to provide at least one of environment_name or environment_uuid.
                environment_uuid:
                  type: string
                  description: UUID of the environment. You need to provide at least one of environment_name or environment_uuid.
                destination_uuid:
                  type: string
                  description: UUID of the destination if the server has multiple destinations
                mysql_root_password:
                  type: string
                  description: MySQL root password
                mysql_password:
                  type: string
                  description: MySQL password
                mysql_user:
                  type: string
                  description: MySQL user
                mysql_database:
                  type: string
                  description: MySQL database
                mysql_conf:
                  type: string
                  description: MySQL conf
                name:
                  type: string
                  description: Name of the database
                description:
                  type: string
                  description: Description of the database
                image:
                  type: string
                  description: Docker Image of the database
                is_public:
                  type: boolean
                  description: Is the database public?
                public_port:
                  type: integer
                  description: Public port of the database
                limits_memory:
                  type: string
                  description: Memory limit of the database
                limits_memory_swap:
                  type: string
                  description: Memory swap limit of the database
                limits_memory_swappiness:
                  type: integer
                  description: Memory swappiness of the database
                limits_memory_reservation:
                  type: string
                  description: Memory reservation of the database
                limits_cpus:
                  type: string
                  description: CPU limit of the database
                limits_cpuset:
                  type: string
                  description: CPU set of the database
                limits_cpu_shares:
                  type: integer
                  description: CPU shares of the database
                instant_deploy:
                  type: boolean
                  description: Instant deploy the database
              type: object
      responses:
        '200':
          description: Database updated
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /databases/mongodb:
    post:
      tags:
        - Databases
      summary: Create (MongoDB)
      description: Create a new MongoDB database.
      operationId: create-database-mongodb
      requestBody:
        description: Database data
        required: true
        content:
          application/json:
            schema:
              required:
                - server_uuid
                - project_uuid
                - environment_name
                - environment_uuid
              properties:
                server_uuid:
                  type: string
                  description: UUID of the server
                project_uuid:
                  type: string
                  description: UUID of the project
                environment_name:
                  type: string
                  description: Name of the environment. You need to provide at least one of environment_name or environment_uuid.
                environment_uuid:
                  type: string
                  description: UUID of the environment. You need to provide at least one of environment_name or environment_uuid.
                destination_uuid:
                  type: string
                  description: UUID of the destination if the server has multiple destinations
                mongo_conf:
                  type: string
                  description: MongoDB conf
                mongo_initdb_root_username:
                  type: string
                  description: MongoDB initdb root username
                name:
                  type: string
                  description: Name of the database
                description:
                  type: string
                  description: Description of the database
                image:
                  type: string
                  description: Docker Image of the database
                is_public:
                  type: boolean
                  description: Is the database public?
                public_port:
                  type: integer
                  description: Public port of the database
                limits_memory:
                  type: string
                  description: Memory limit of the database
                limits_memory_swap:
                  type: string
                  description: Memory swap limit of the database
                limits_memory_swappiness:
                  type: integer
                  description: Memory swappiness of the database
                limits_memory_reservation:
                  type: string
                  description: Memory reservation of the database
                limits_cpus:
                  type: string
                  description: CPU limit of the database
                limits_cpuset:
                  type: string
                  description: CPU set of the database
                limits_cpu_shares:
                  type: integer
                  description: CPU shares of the database
                instant_deploy:
                  type: boolean
                  description: Instant deploy the database
              type: object
      responses:
        '200':
          description: Database updated
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
      security:
        - bearerAuth: []
  /databases/{uuid}/start:
    get:
      tags:
        - Databases
      summary: Start
      description: Start database. `Post` request is also accepted.
      operationId: start-database-by-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the database.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Start database.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Database starting request queued.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /databases/{uuid}/stop:
    get:
      tags:
        - Databases
      summary: Stop
      description: Stop database. `Post` request is also accepted.
      operationId: stop-database-by-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the database.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Stop database.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Database stopping request queued.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []
  /databases/{uuid}/restart:
    get:
      tags:
        - Databases
      summary: Restart
      description: Restart database. `Post` request is also accepted.
      operationId: restart-database-by-uuid
      parameters:
        - name: uuid
          in: path
          description: UUID of the database.
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Restart database.
          content:
            application/json:
              schema:
                properties:
                  message:
                    type: string
                    example: Database restaring request queued.
                type: object
        '400':
          $ref: '#/components/responses/400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/404'
      security:
        - bearerAuth: []

```
Page 1/4FirstPrevNextLast