ADR-011: com.cloudempiere.ai Integration for Deep iDempiere Context

Status: Proposed Date: 2025-12-01 Context: Leverage existing cloudempiere.ai OSGi plugin for deeper iDempiere context in CLI and MCP server

Context

The idempiere-cli currently provides AI integration through:

However, these approaches have limitations:

The com.cloudempiere.ai Opportunity

We have an existing OSGi plugin (com.cloudempiere.ai) that provides:

  1. Deep iDempiere integration - Runs inside iDempiere JVM with full context
  2. Role-based security - Inherits iDempiere's entire permission model
  3. Multi-provider AI - Claude, AWS Bedrock, Ollama support
  4. Agent framework - Tool execution with safety boundaries
  5. Audit trail - Complete logging for compliance

Current Architecture Gap

┌─────────────────────────────────────────────────────────────────┐
│                    Claude Code / Claude Desktop                  │
└──────────────────────────┬──────────────────────────────────────┘
                           │ JSON-RPC over stdio
┌──────────────────────────▼──────────────────────────────────────┐
│              idempiere-mcp-server (Planned - ADR-010)           │
│                                                                  │
│  ┌──────────────────────────────────────────────────────────┐   │
│  │ Backend Options:                                          │   │
│  │  - CLI subprocess (current)                               │   │
│  │  - REST API (limited)                                     │   │
│  │  - Direct DB (no security) ← GAP                          │   │
│  │  - com.cloudempiere.ai ← NEW (deep integration)           │   │
│  └──────────────────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────────────────────┘

Why Reuse com.cloudempiere.ai?

Aspect Without cloudempiere.ai With cloudempiere.ai
Security Manual implementation Inherits MRole, AccessSqlParser
Context Static registry export Live Application Dictionary
Audit Custom logging AIG_QueryAudit table
Business Logic None Model validators, callouts
Multi-tenancy Manual Client/Org filtering Automatic via MRole
Cost Control None Built-in limits and tracking

Decision

Integrate com.cloudempiere.ai as an optional backend for the MCP server, providing deep iDempiere context while maintaining the CLI's standalone capabilities.


Architecture

Integration Options

The cloudempiere.ai plugin exposes HTTP endpoints that the MCP server calls:

┌─────────────────────────────────────────────────────────────────┐
│                    Claude Code / Claude Desktop                  │
└──────────────────────────┬──────────────────────────────────────┘
                           │ stdio (JSON-RPC)
┌──────────────────────────▼──────────────────────────────────────┐
│                    idempiere-mcp-server                          │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │ AiBackend implements BackendAdapter                        │ │
│  │                                                             │ │
│  │   POST /api/ai/query                                        │ │
│  │   POST /api/ai/metadata                                     │ │
│  │   POST /api/ai/context                                      │ │
│  └────────────────────────────────────────────────────────────┘ │
└──────────────────────────┬──────────────────────────────────────┘
                           │ HTTPS
┌──────────────────────────▼──────────────────────────────────────┐
│                    iDempiere Server                              │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │ com.cloudempiere.ai (OSGi Plugin)                          │ │
│  │                                                             │ │
│  │  - SecureDatabaseQueryExecutor                              │ │
│  │  - TableMetadataTool                                        │ │
│  │  - WindowContextProvider                                    │ │
│  │  - AIG_QueryAudit (audit trail)                             │ │
│  └────────────────────────────────────────────────────────────┘ │
│                                                                  │
│  iDempiere Core (MRole, AccessSqlParser, DB, Models)            │
└─────────────────────────────────────────────────────────────────┘

Pros:

Cons:

Option B: Shared Library (Alternative)

Extract core security/metadata classes from cloudempiere.ai into a shared library:

┌─────────────────────────────────────────────────────────────────┐
│                    idempiere-mcp-server                          │
│  ┌────────────────────────────────────────────────────────────┐ │
│  │ cloudempiere-ai-core (shared library)                      │ │
│  │                                                             │ │
│  │  - SecureDatabaseQueryExecutor                              │ │
│  │  - ADMetadataService                                        │ │
│  │  - BoundaryValidator                                        │ │
│  └────────────────────────────────────────────────────────────┘ │
│                                                                  │
│  Direct JDBC → PostgreSQL                                        │
└─────────────────────────────────────────────────────────────────┘

Pros:

Cons:

Support multiple backends that can be selected at runtime:

public interface BackendAdapter {
    // Core operations
    QueryResult executeSecureQuery(String sql, Map<String, Object> params);
    TableMetadata getTableMetadata(String tableName);
    List<WindowInfo> searchWindows(String pattern);

    // Context operations (only available with AI backend)
    Optional<JSONObject> getWindowContext(int windowNo);
    Optional<JSONObject> getChartContext(int chartId);
}

// Backend implementations
CliBackend          // Calls idempiere-cli subprocess
RestApiBackend      // Calls iDempiere REST API
DirectDbBackend     // Direct JDBC (existing)
AiBackend           // Calls cloudempiere.ai HTTP API (NEW)

Key Reusable Components from com.cloudempiere.ai

1. Secure Database Query Executor

Location: com.cloudempiere.ai.database.SecureDatabaseQueryExecutor

What it does:

Reuse in CLI:

// In AiBackend
public QueryResult executeSecureQuery(String sql, Map<String, Object> params) {
    // POST to iDempiere: /api/ai/query
    // {
    //   "sql": "SELECT * FROM C_BPartner WHERE Name LIKE ?",
    //   "params": ["%test%"],
    //   "roleId": 102,
    //   "maxRows": 100
    // }
    // Returns: secure, filtered, audited results
}

2. Table Metadata Tool

Location: com.cloudempiere.ai.tool.TableMetadataTool

What it does:

Reuse:

public TableMetadata getTableMetadata(String tableName) {
    // GET /api/ai/metadata/table/{tableName}
    // Returns:
    // - Table description, access level
    // - All columns with types, references
    // - Foreign key relationships
    // - Display logic, validation rules
}

3. Context Providers

Location: com.cloudempiere.ai.context.*

WindowContextProvider:

ChartContextProvider:

Reuse:

// Only available when connected to live iDempiere
public Optional<JSONObject> getWindowContext(int windowNo) {
    // GET /api/ai/context/window/{windowNo}
    // Returns current window state for AI context
}

4. Boundary Validator

Location: com.cloudempiere.ai.agent.BoundaryValidator

What it does:

Reuse in MCP Server:

public class McpBoundaryValidator {
    // Adapt cloudempiere.ai patterns
    public void validateBeforeExecution(McpContext context, String toolName) {
        // Check cost limits
        if (context.getTotalCost() > context.getCostLimit()) {
            throw new CostLimitExceededException();
        }
        // Check rate limits
        if (context.getCallsThisMinute() > context.getRateLimit()) {
            throw new RateLimitExceededException();
        }
        // Validate tool permission
        if (!context.hasToolPermission(toolName)) {
            throw new PermissionDeniedException();
        }
    }
}

5. Audit Trail Model

Location: com.cloudempiere.ai.model.MAIQueryAudit

Fields tracked:

Reuse: All queries through cloudempiere.ai are automatically audited. For CLI-only operations, implement similar audit logging.


Implementation Plan

Phase 1: API Endpoint Design (Week 1-2)

Define HTTP API contract between MCP server and cloudempiere.ai:

openapi: 3.0.0
info:
  title: cloudempiere.ai Integration API
  version: 1.0.0

paths:
  /api/ai/query:
    post:
      summary: Execute secure database query
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                sql:
                  type: string
                params:
                  type: array
                roleId:
                  type: integer
                maxRows:
                  type: integer
                  default: 100
      responses:
        200:
          description: Query results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QueryResult'

  /api/ai/metadata/table/{tableName}:
    get:
      summary: Get table metadata
      responses:
        200:
          description: Table metadata
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TableMetadata'

  /api/ai/metadata/window/{windowId}:
    get:
      summary: Get window metadata
      responses:
        200:
          description: Window metadata

  /api/ai/context/window/{windowNo}:
    get:
      summary: Get current window context
      responses:
        200:
          description: Window context

  /api/ai/health:
    get:
      summary: Health check
      responses:
        200:
          description: Service healthy

Phase 2: cloudempiere.ai HTTP Endpoints (Week 3-4)

Add REST endpoints to cloudempiere.ai plugin:

@Path("/api/ai")
@Produces(MediaType.APPLICATION_JSON)
public class AIIntegrationEndpoint {

    @Inject
    SecureDatabaseQueryExecutor queryExecutor;

    @Inject
    ADMetadataService metadataService;

    @POST
    @Path("/query")
    public Response executeQuery(QueryRequest request) {
        // Validate authentication
        // Execute secure query
        // Return results
    }

    @GET
    @Path("/metadata/table/{tableName}")
    public Response getTableMetadata(@PathParam("tableName") String tableName) {
        return Response.ok(metadataService.getTableMetadata(tableName)).build();
    }
}

Phase 3: MCP Server AiBackend (Week 5-6)

Implement AiBackend in idempiere-mcp-server:

public class AiBackend implements BackendAdapter {

    private final String aiApiUrl;
    private final OkHttpClient client;

    public AiBackend(String aiApiUrl, String apiToken) {
        this.aiApiUrl = aiApiUrl;
        this.client = new OkHttpClient.Builder()
            .addInterceptor(new AuthInterceptor(apiToken))
            .build();
    }

    @Override
    public QueryResult executeSecureQuery(String sql, Map<String, Object> params) {
        Request request = new Request.Builder()
            .url(aiApiUrl + "/api/ai/query")
            .post(RequestBody.create(toJson(sql, params), JSON))
            .build();

        try (Response response = client.newCall(request).execute()) {
            return parseQueryResult(response.body().string());
        }
    }

    @Override
    public TableMetadata getTableMetadata(String tableName) {
        Request request = new Request.Builder()
            .url(aiApiUrl + "/api/ai/metadata/table/" + tableName)
            .get()
            .build();

        try (Response response = client.newCall(request).execute()) {
            return parseTableMetadata(response.body().string());
        }
    }
}

Phase 4: Configuration & Documentation (Week 7-8)

MCP Server Configuration:

{
  "mcpServers": {
    "idempiere": {
      "command": "java",
      "args": ["-jar", "/path/to/idempiere-mcp-server.jar"],
      "env": {
        "BACKEND": "ai",
        "AI_API_URL": "http://localhost:8080",
        "AI_API_TOKEN": "${IDEMPIERE_AI_TOKEN}",
        "AI_ROLE_ID": "102"
      }
    }
  }
}

Backend Selection:

# Use CLI backend (default, no iDempiere server needed)
java -jar idempiere-mcp-server.jar --backend=cli

# Use REST API backend
java -jar idempiere-mcp-server.jar --backend=rest \
  --api-url=http://localhost:8080 \
  --api-token=xxx

# Use AI backend (deep integration)
java -jar idempiere-mcp-server.jar --backend=ai \
  --ai-api-url=http://localhost:8080 \
  --ai-api-token=xxx \
  --ai-role-id=102

Security Considerations

Authentication Flow

Claude Code Agent
    │
    │ 1. Connects via stdio
    ▼
MCP Server (idempiere-mcp-server)
    │
    │ 2. Reads AI_API_TOKEN from env
    │
    │ 3. HTTP request with Bearer token
    ▼
iDempiere (cloudempiere.ai plugin)
    │
    │ 4. Validates token → maps to AI User
    │
    │ 5. Loads Role from request
    │
    │ 6. Applies MRole.addAccessSQL()
    │
    │ 7. Logs to AIG_QueryAudit
    ▼
Database (with security filters)

Permission Model

AI User Account (AD_User)
    │
    ├─ Has Role (AD_Role)
    │   ├─ Table Access (AD_Table_Access)
    │   ├─ Column Access (AD_Column_Access)
    │   ├─ Record Access (AD_Record_Access)
    │   ├─ Window Access (AD_Window_Access)
    │   └─ Process Access (AD_Process_Access)
    │
    └─ Client/Org Restrictions
        ├─ AD_Client_ID filter
        └─ AD_Org_ID filter

Sensitive Data Handling

cloudempiere.ai automatically redacts:


Benefits

For CLI Development

  1. Deep AD Context - Access live Application Dictionary, not static exports
  2. Security Inheritance - Leverage existing iDempiere security model
  3. Audit Compliance - All AI operations automatically logged
  4. Business Logic Awareness - Can understand validators, callouts
  5. Multi-tenant Safe - Automatic Client/Org filtering

For AI Agents

  1. Accurate Metadata - Always-current table/window information
  2. Safe Queries - Cannot exceed role permissions
  3. Cost Control - Built-in limits prevent runaway usage
  4. Context Awareness - Can see what user is viewing

For iDempiere Ecosystem

  1. Reuse Investment - Leverage existing cloudempiere.ai work
  2. Consistent Security - Same model for UI and AI access
  3. Unified Audit - Single place for compliance tracking
  4. Gradual Adoption - Optional backend, not mandatory

Risks & Mitigations

Risk Impact Mitigation
iDempiere server dependency High Keep CLI/REST backends as fallbacks
API versioning conflicts Medium Version API endpoints, maintain compatibility
Performance overhead Medium Caching in MCP server, batch operations
Security misconfiguration High Default to minimal permissions, audit all access
cloudempiere.ai maintenance Medium Document integration points, minimize coupling

Alternatives Considered

1. Fork cloudempiere.ai Security Code

Rejected - Would duplicate maintenance effort and miss runtime context.

2. Direct OSGi Integration

Rejected - MCP server would need to run inside iDempiere, too tightly coupled.

3. GraphQL Gateway

Deferred - HTTP REST is simpler for initial implementation, GraphQL could be added later.


Consequences

Positive

Negative

Neutral


References

cloudempiere.ai Source Code

iDempiere Documentation

External References

Path: /docs/developers/architecture/idempiere-hub/011-cloudempiere-ai-integration