Skip to main content
All 67 tools in the Dokploy MCP Server include semantic annotations that help AI systems (like Claude, ChatGPT, or other MCP clients) understand tool behavior, safety characteristics, and appropriate usage patterns.

What Are Tool Annotations?

Tool annotations are metadata fields attached to each tool definition that describe operational characteristics:
annotations: {
  title?: string;              // Human-readable tool name
  readOnlyHint?: boolean;      // Tool only reads data
  destructiveHint?: boolean;   // Tool modifies/deletes resources
  idempotentHint?: boolean;    // Safe to retry with same result
  openWorldHint?: boolean;     // Interacts with external systems
}
These annotations are defined in src/mcp/tools/toolFactory.ts:19-25 and applied to every tool during creation.

Core Annotations Explained

readOnlyHint

Tools with readOnlyHint: true are guaranteed to never modify system state. They’re safe for exploratory queries and can be called without confirmation.
Characteristics:
  • Only retrieves and returns data
  • No side effects on Dokploy infrastructure
  • Safe to call repeatedly
  • Cannot cause data loss or service disruption
Example from source (src/mcp/tools/project/projectAll.ts:14):
export const projectAll = createTool({
  name: "project-all",
  description: "Lists all projects in Dokploy with optimized response...",
  schema: z.object({}),
  annotations: {
    title: "List All Projects",
    readOnlyHint: true,        // ← Safe read operation
    idempotentHint: true,
    openWorldHint: true,
  },
  handler: async () => {
    const response = await apiClient.get("/project.all");
    // ... returns data without modifications
  },
});
Tools with readOnlyHint:
  • project-all, project-one
  • application-one, application-readAppMonitoring, application-readTraefikConfig
  • domain-byApplicationId, domain-byComposeId, domain-one, domain-validateDomain, domain-generateDomain, domain-canGenerateTraefikMeDomains
  • postgres-one, mysql-one

destructiveHint

Tools with destructiveHint: true modify or delete resources irreversibly. AI systems should request user confirmation before calling these tools.
Characteristics:
  • Modifies existing resources
  • Deletes data or services
  • Stops running services
  • Changes system state in ways that may be hard to reverse
Example from source (src/mcp/tools/project/projectRemove.ts:14):
export const projectRemove = createTool({
  name: "project-remove",
  description: "Removes/deletes an existing project in Dokploy.",
  schema: z.object({
    projectId: z.string().min(1).describe("The ID of the project to remove."),
  }),
  annotations: {
    title: "Remove Project",
    destructiveHint: true,      // ← Irreversible deletion
    idempotentHint: false,
    openWorldHint: true,
  },
  handler: async (input) => {
    const response = await apiClient.post("/project.remove", input);
    return ResponseFormatter.success(
      `Project "${input.projectId}" removed successfully`,
      response.data
    );
  },
});
Destructive operations include:
  • Deletion: project-remove, application-delete, domain-delete, postgres-remove, mysql-remove
  • Stopping services: application-stop, postgres-stop, mysql-stop
  • Configuration changes: application-update, postgres-update, mysql-update, all save* tools
  • State changes: application-cancelDeployment, application-cleanQueues, postgres-changeStatus

idempotentHint

Tools with idempotentHint: true produce the same result when called multiple times with the same input. They’re safe to retry on failure.
Characteristics:
  • Calling the tool multiple times with identical input produces identical results
  • No accumulating side effects
  • Safe to retry on network failures or timeouts
  • Predictable behavior
Idempotent operations:
  • All read-only tools (reading data doesn’t change with repeated calls)
  • Some update operations that are designed to be idempotent (e.g., domain-update)
Non-idempotent operations:
  • application-deploy - each deployment creates a new deployment record
  • project-create - creates a new project each time
  • application-start, application-stop - state changes over time
Example: domain-update is idempotent because updating a domain to the same configuration multiple times results in the same final state.

openWorldHint

All tools in Dokploy MCP Server have openWorldHint: true because they interact with an external Dokploy API over the network.
Characteristics:
  • Makes network requests to external systems
  • Subject to network failures, timeouts, rate limits
  • Depends on external service availability
  • May have latency variability
Implications for AI systems:
  • Expect potential network errors
  • Handle timeouts gracefully
  • Consider rate limiting when making multiple calls
  • Validate authentication before bulk operations

Annotation Patterns by Category

Project Management Tools

ToolreadOnlydestructiveidempotentNotes
project-allSafe listing operation
project-oneSafe retrieval
project-createCreates new resources
project-updateModifies existing project
project-duplicateCreates new project
project-removeIrreversible deletion

Application Lifecycle Tools

ToolreadOnlydestructiveidempotentNotes
application-oneRead operation
application-createCreates new app
application-deployEach deploy is unique
application-startState change
application-stopStops service
application-deletePermanent removal
application-updateModifies configuration

Domain Management Tools

ToolreadOnlydestructiveidempotentNotes
domain-oneRead operation
domain-createCreates new domain
domain-updateIdempotent update
domain-deleteRemoves domain
domain-validateDomainValidation check

Database Tools (PostgreSQL & MySQL)

ToolreadOnlydestructiveidempotentNotes
*-oneRead operation
*-createCreates new database
*-deployDeploys container
*-startStarts database
*-stopStops database
*-removeDeletes database
*-updateModifies configuration

Why Annotations Matter for AI Safety

Semantic annotations enable AI systems to make informed decisions about tool usage:

1. Risk Assessment

AI systems can categorize tools by risk level:
  • Low risk: readOnlyHint: true - Safe for autonomous use
  • Medium risk: destructiveHint: false, readOnlyHint: false - Creates resources
  • High risk: destructiveHint: true - Requires confirmation

2. Retry Logic

idempotentHint informs retry strategies:
// Safe to retry on failure
if (tool.annotations.idempotentHint === true) {
  await retryWithBackoff(() => invokeTool(tool, input));
}
// Avoid automatic retry for non-idempotent operations
else {
  await invokeTool(tool, input); // Single attempt
}

3. User Confirmation

AI can prompt for confirmation on destructive operations:
if (tool.annotations.destructiveHint === true) {
  const confirmed = await askUser(
    `This will ${tool.description.toLowerCase()}. Continue?`
  );
  if (!confirmed) return;
}

4. Exploratory Queries

Read-only tools can be used freely for exploration:
// Safe to call during information gathering
const readOnlyTools = allTools.filter(
  t => t.annotations.readOnlyHint === true
);

Best Practices for Tool Usage

Read Before Write

Always use read-only tools to gather context before calling destructive operations. Example: project-one before project-update.

Confirm Destructive Actions

Request explicit user confirmation for any tool with destructiveHint: true, especially deletions.

Handle Idempotency

Retry idempotent operations on transient failures, but avoid retrying non-idempotent operations automatically.

Expect Network Issues

All tools have openWorldHint: true. Implement timeouts, error handling, and graceful degradation.

Safe Workflow Example

// ✅ GOOD: Read-only exploration first
1. Call `project-all` to list projects (readOnly)
2. Call `project-one` to get specific details (readOnly)
3. Confirm with user: "Update project XYZ?"
4. Call `project-update` with validated input (destructive)
5. Call `project-one` again to verify changes (readOnly)

// ❌ BAD: Destructive operation without context
1. Call `project-remove` immediately (destructive, risky)

Implementation Details

Annotations are defined in the tool factory (src/mcp/tools/toolFactory.ts:42-124):
export function createTool<TShape extends ZodRawShape>(
  definition: ToolDefinition<TShape>
): ToolDefinition<TShape> {
  return {
    ...definition,
    handler: async (input) => {
      // Validation and error handling
      const validationResult = definition.schema.safeParse(input);
      if (!validationResult.success) {
        return ResponseFormatter.error(
          `Invalid input for tool: ${definition.name}`,
          `Validation errors: ${errorMessages}`
        );
      }
      
      // Execute tool with annotations available
      const result = await definition.handler(validationResult.data);
      return result;
    },
  };
}
Annotations are preserved throughout the tool lifecycle and exposed to MCP clients through the protocol’s tool listing mechanism.

Real-World Examples

Example 1: Safe Database Exploration

// 1. Read-only: List all databases (safe, idempotent)
{"tool": "postgres-one", "input": {"postgresId": "db_123"}}

// Response shows database is running
// Now safe to proceed with configuration

// 2. Destructive but reversible: Save external port
{"tool": "postgres-saveExternalPort", "input": {
  "postgresId": "db_123",
  "externalPort": 5432
}}

Example 2: Careful Application Deletion

// 1. Read-only: Verify application exists
{"tool": "application-one", "input": {"applicationId": "app_xyz"}}

// 2. Read-only: Check domains (may need cleanup)
{"tool": "domain-byApplicationId", "input": {"applicationId": "app_xyz"}}

// 3. Destructive: Stop application first
{"tool": "application-stop", "input": {"applicationId": "app_xyz"}}

// 4. Destructive & irreversible: Delete after confirmation
{"tool": "application-delete", "input": {"applicationId": "app_xyz"}}

Summary

Tool annotations provide essential metadata for safe AI interaction:
  • readOnlyHint: Safe for exploration, no modifications
  • destructiveHint: Requires caution, may be irreversible
  • idempotentHint: Safe to retry, consistent results
  • openWorldHint: External dependencies, handle failures
By respecting these annotations, AI systems can operate safely and effectively within the Dokploy infrastructure.

API Overview

Complete guide to all 67 tools

Troubleshooting

Common issues and solutions

Build docs developers (and LLMs) love