diff --git a/docs/11-proposals/PROPOSAL_agent_document_support.md b/docs/11-proposals/PROPOSAL_agent_document_support.md index 51c568a0..d6a58b8f 100644 --- a/docs/11-proposals/PROPOSAL_agent_document_support.md +++ b/docs/11-proposals/PROPOSAL_agent_document_support.md @@ -14,7 +14,7 @@ Mendix 11.9 introduces **Agents** as a first-class concept for building agentic | **AgentCommons** | Agent management: versioned agents, tools, knowledge bases, MCP, test cases | | **AgentEditorCommons** | Bridge between Studio Pro Agent Editor extension and AgentCommons runtime entities | | **MCPClient** | Model Context Protocol client: server connections, tool/prompt discovery, execution | -| **ConversationalUI** | Chat widgets, message rendering, tool approval UI, trace monitoring, token dashboards | +| **ConversationalUI** | Chat widgets, message rendering, tool approval UI, trace monitoring, token & observability dashboards | Currently, `mxcli` has no visibility into agent documents. `SHOW STRUCTURE` reports the Agents module as empty because it only contains `CustomBlobDocument` units, which are not parsed. An AI coding agent cannot discover, inspect, or create agents via MDL. @@ -30,7 +30,7 @@ CustomBlobDocuments$CustomBlobDocument: $Type: "CustomBlobDocuments$CustomBlobDocument" Name: string Contents: string (JSON payload — schema depends on CustomDocumentType) - CustomDocumentType: "agenteditor.agent" + DocumentType: "agenteditor.agent" | "agenteditor.model" | "agenteditor.knowledgebase" | "agenteditor.consumedMCPService" @@ -48,7 +48,7 @@ Key observations about the wrapper: - `CustomDocumentType` is the discriminator for the inner JSON schema - `Contents` is a JSON string (not nested BSON) — the agent editor extension owns the inner schema - `Metadata.ReadableTypeName` is a human-friendly label (also used as the UI badge in Studio Pro) -- `Excluded` is `false` for documents created in the new Agent Editor extension; observed as `true` on the 4 older agents in the project (likely pre-release format) +- `Excluded` is `false` by default; can be changed to `true` by the user. Then the document cannot be used by other app logic and no errors will be shown for this document. ### MODEL — `Contents` JSON schema @@ -56,7 +56,7 @@ Observed in `Agents.MyFirstModel`: ```json { - "type": "", + "type": "Text generation", "name": "", "displayName": "", "provider": "MxCloudGenAI", @@ -76,7 +76,7 @@ Observed in `Agents.MyFirstModel`: - `provider` is a top-level discriminator — `"MxCloudGenAI"` is the only observed value. `providerFields` shape depends on `provider`. - `providerFields.key` references a **String constant** (holding the Mendix Cloud GenAI Portal key) by `{documentId, qualifiedName}`. -- `type`, `name`, `displayName`, `environment`, `deepLinkURL`, `keyId`, `keyName`, `resourceName` are all empty in the sample — they're **Portal-populated** when the user clicks **Test Key** in Studio Pro, not user-set fields. +- `type`, `name`, `displayName`, `environment`, `deepLinkURL`, `keyId`, `keyName`, `resourceName` are all empty in the sample — they values are decoded from the key the user selects as a string constant. After decoding the key, a call to the backend might update the reference to the exact model if that was changed in the Mendix Cloud GenAI portal. This check can also be triggered by the user when clicking **Test Key** in Studio Pro. ### KNOWLEDGE BASE — `Contents` JSON schema @@ -94,14 +94,14 @@ Observed in `Agents.Knowledge_base`: "modelDisplayName": "", "modelName": "", "key": { - "documentId": "51b85be5-f040-4562-bf4c-086347d387a9", - "qualifiedName": "Agents.LLMKey" + "documentId": "51b85be5-f040-4562-bf4c-086347d38712", + "qualifiedName": "Agents.KnowledbaseKey" } } } ``` -Same shape as Model, but `providerFields` includes embedding-model info (`modelDisplayName`, `modelName`) instead of `resourceName`. The `key` reference points to the same String constant. +Same shape as Model, but `providerFields` includes embedding-model info (`modelDisplayName`, `modelName`) instead of `resourceName`. The `key` reference points to a String constant with a knowledge base key generated in the Mendix Cloud GenAI portal. ### CONSUMED MCP SERVICE — `Contents` JSON schema @@ -112,13 +112,22 @@ Observed in `Agents.Consumed_MCP_service`: "protocolVersion": "v2025_03_26", "documentation": " fqwef qwec qwefc", "version": "0.0.1", - "connectionTimeoutSeconds": 30 + "connectionTimeoutSeconds": 30, + "endpoint" : { + "documentId": "51b85be5-f040-4562-bf4c-086347d38734", + "qualifiedName": "Agents.MCPEndpoint" + }, + "authenticationMicroflow" : { + "documentId": "51b85be5-f040-4562-bf4c-086347d387ab", + "qualifiedName": "Agents.AuthenticationMicroflow" + } } ``` -Notably **absent**: no endpoint URL and no credentials microflow reference. Those are presumably configured at runtime via the `MCPClient.ConsumedMCPService` entity (see the `Agents.MCP_Server_Endpoint` String constant in the same project — used by a runtime microflow, not embedded in the document). This matches real-world deployment: endpoints typically differ across dev/staging/prod. +Endpoint is a reference to a string constant with the MCP endpoint. If the server requried authentication those can be created in an authentication microflow which the user can optionally select. An authentication microflow cannot have input parameters and needs to return a list of `System.HttpHeader`. +For MCP tool discovery inside Studio Pro, user can add headers in the UI. Those will not be persisted, nor transferred into the authentication microflow to be used at runtime. -Enum values for `protocolVersion`: `"v2024_11_05"` or `"v2025_03_26"`. +Enum values for `protocolVersion`: `"v2024_11_05"` or `"v2025_03_26"`. Use `v2025_03_26` for newer MCP servers that support streamable http transport, `v2024_11_05` for servers that only support SSE transport. ### AGENT — `Contents` JSON schema @@ -138,6 +147,10 @@ Simple agent (observed in `AgentEditorCommons.TranslationAgent`): "entity": { "documentId": "83d81a7b-4a84-416e-a64f-0ffa981c8408", "qualifiedName": "System.Language" + }, + "model": { + "documentId": "3addaaa1-8bd3-4654-8cc9-2c886d0a01e9", + "qualifiedName": "Agents.MyFirstModel" } } ``` @@ -162,6 +175,17 @@ Fully-populated agent (observed in `Agents.Agent007`): "qualifiedName": "Agents.Consumed_MCP_service", "documentId": "47c9987a-e922-44eb-a389-e641f325ce15" } + }, + { + "id": "044bc8c2-8ca6-4166-b8f0-9d2245aba8c7", + "name": "GetBankHolidays", + "description": "Gets bank holidays", + "enabled": true, + "toolType": "Microlfow", + "document": { + "qualifiedName": "Agents.GetBankHolidays", + "documentId": "47c9987a-e922-44eb-a389-e641f325ce18" + } } ], "knowledgebaseTools": [ @@ -176,7 +200,8 @@ Fully-populated agent (observed in `Agents.Agent007`): "documentId": "cccc0b5b-7600-47a9-8f6e-5761ce2fc620" }, "collectionIdentifier": "agent1-collection", - "maxResults": 3 + "maxResults": 3, + "minSimilarity": 0.5 } ], "model": { @@ -184,18 +209,24 @@ Fully-populated agent (observed in `Agents.Agent007`): "qualifiedName": "Agents.MyFirstModel" }, "maxTokens": 16384, - "toolChoice": "Auto" + "temperature": 0.5, + "topP": 1.0, + "toolChoice": "Tool", + "toolChoiceToolName": "GetBankHolidays" } ``` Agent schema observations: -- **`model`**: Reference to a Model document by `{documentId, qualifiedName}`. Optional in the older samples (model set at runtime); present on new Agent Editor agents. -- **`tools[]`**: Array of tool references. Each entry has a UUID `id`, name, description, `enabled` boolean, and a `toolType` discriminator. Observed `toolType` values: `"MCP"` (a whole MCP service attached as tools). A microflow-tool sample is still missing — likely `"Microflow"` with a `microflow` reference instead of `document`. -- **`knowledgebaseTools[]`**: Array of KB references. Same base fields plus `collectionIdentifier` and `maxResults`. No `minSimilarity` observed in current schema. -- **`variables[]`**: Empty in `Agent007`; populated in older samples with `{key, isAttributeInEntity}`. +- **`model`**: Reference to a Model document by `{documentId, qualifiedName}`. +- **`entity`** the prompts might contain some variables (words in the user prompt surrounded by double curly brackets, i.e. {{Language}}). Variables will be replaced at runtime by attribute values on an initialized object of type entity. Therefore it is neccessary that the variables key is the same as an attribute on the entity. +- **`usageType`**: Defaults to `"Task"` agents which have aan optional system prompt and a required user prompt. `"Chat"` agents (introduced in v1.1.0 of the agent editor) do not have a user prompt on the agent definition since that will be provided by the user at runtime. +- **`tools[]`**: Optional. Array of tool references. Each entry has a UUID `id`, unique `name`, `description`, `enabled` boolean, and a `toolType` discriminator. Observed `toolType` values: `"MCP"` (a whole MCP service attached as tools) or a microflow-tool `"Microflow"` where `document` referencces a microflow document. Tool microflows need to return a String and can only have primitive types and GenAICommons.Request or GenAICommons.Tool objects as input parameters. +- **`knowledgebaseTools[]`**: Optional. Array of KB references. Same base fields plus `collectionIdentifier`, `maxResults` and `minSimilarity`. ToolType is irrelevant for knowledgebaseTools. MaxResults needs to be a positive integer, minSimilarity is a decimal between 0 and 1. +- **`variables[]`**: Should be left empty this will be automatically populated by the extension based on the detected variables in the user or system prompt. - **`entity`**: Optional. Present on older agents with `isAttributeInEntity: true` variables; absent on `Agent007`. -- **`maxTokens`**, **`toolChoice`**: Agent-level inference parameters. Enum values for `toolChoice` observed: `"Auto"` (capitalized, not the lowercase `auto` used by `GenAICommons.ENUM_ToolChoice` at runtime). Other likely values: `"None"`, `"Any"`, `"Tool"`. -- **`temperature`**, **`topP`**: Not observed in any sample — omitted when not set. +- **`maxTokens`**: Optional. Can be set by the user to restrict the number of tokens to consume in one agent call. +- **`toolChoice`**: Optional. Agent-level inference parameters. Enum values for `toolChoice` observed: `"Auto"` (capitalized, not the lowercase `auto` used by `GenAICommons.ENUM_ToolChoice` at runtime). Other values: `"None"`, `"Any"`, `"Tool"`. If tool choice is set to `Tool`, then also the `toolChoiceToolName` needs to be set by the unique name referencing one tool in `tools[]`. Only tools where `toolType` = "Microflow" can become tool choice. +- **`temperature`**, **`topP`**: Optional. Can be set by the user to influence the randomness of the response. - **No `UserAccessApproval`/`Access` field** on tools. That's a runtime-only concern (set on `AgentCommons.Tool` entity, not the document). **This is a correction to earlier versions of this proposal.** ### Observed documents in test3 project @@ -293,12 +324,12 @@ CREATE AGENT Agents."Agent007" ( **Block-level property reference:** -Each block maps to one entry in the agent's `Contents` JSON (`tools[]` for TOOL/MCP SERVICE, `knowledgebaseTools[]` for KNOWLEDGE BASE). Block IDs (the `id` UUID field in JSON) are auto-generated by the writer. +Each block maps to one entry in the agent's `Contents` JSON (`tools[]` for TOOL/CONSUMED MCP SERVICE, `knowledgebaseTools[]` for KNOWLEDGE BASE). Block IDs (the `id` UUID field in JSON) are auto-generated by the writer. | Block | Referenced by | Properties | Maps to JSON field | |---|---|---|---| -| `MCP SERVICE { ... }` | ConsumedMCPService document | `Enabled`, `Description` | `tools[]` entry with `toolType: "MCP"`, `document: {...}` | -| `TOOL { Microflow: ... }` | microflow name | `Microflow`, `Enabled`, `Description` | `tools[]` entry with `toolType: "Microflow"` *(shape speculative — see Open Questions)* | +| `CONSUMED MCP SERVICE { ... }` | ConsumedMCPService document | `Enabled`, `Description` | `tools[]` entry with `toolType: "MCP"`, `document: {...}` | +| `TOOL { Microflow: , Description, Enabled }` | microflow name | `Microflow`, `Enabled`, `Description` | `tools[]` entry with `toolType: "Microflow"`, `document: { qualifiedName: , documentId: }`. Microflow tools must be microflow references (qualified name) and the target microflow must return a `String`; input parameters are limited to primitives and `GenAICommons.Request`/`GenAICommons.Tool` types. | | `KNOWLEDGE BASE { Source: ... }` | KB document via `Source:` | `Source` (required), `Collection`, `MaxResults`, `Description`, `Enabled` | `knowledgebaseTools[]` entry | ### DROP AGENT @@ -332,7 +363,7 @@ Example — all of this is stored in the agent document: CREATE AGENT Reviews."SentimentAnalyzer" ( UsageType: Task, -- design-time mode Entity: Reviews.ProductReview, -- context entity contract - Variables: ("ProductName": EntityAttribute, -- input contract + Variables: ("ProductName": EntityAttribute, -- input contract; which attributes to read from the context object at runtime "ReviewText": EntityAttribute), SystemPrompt: 'Analyze the review for {{ProductName}}.', -- prompt template UserPrompt: '{{ReviewText}}' -- prompt template @@ -353,13 +384,14 @@ CALL AGENT WITHOUT HISTORY $Agent CONTEXT $Review INTO $Response; |----------|-----------| | `AGENT` as document type keyword | Matches `Metadata.ReadableTypeName = "Agent"` and Mendix UI terminology | | Top-level `(Key: Value)` config + `{...}` body with singular blocks | Mirrors `CREATE REST CLIENT ... (...) { OPERATION Name {...} }` exactly — same shape, same mental model | -| `Model: ` in top-level config | Agent documents can reference a Model document directly via the `model` JSON field (confirmed in `Agent007`). Making it a peer of `UsageType` mirrors how the Agent Editor UI presents it | -| `ToolChoice: Auto` PascalCase enum literal | Matches the real JSON value (`"Auto"`), which differs from the lowercase `auto` used by `GenAICommons.ENUM_ToolChoice` at runtime. Values: `Auto`, `None`, `Any`, `Tool` | +| `Model: ` in top-level config | Agent documents can reference a Model document directly via the `model` JSON field (confirmed in `Agent007`). | +| `UsageType: Task` determines if user prompt is a template or not | Task agents have a fixed user prompt, potentially containing variables, while `Chat` agents do not have a predefined userprompt, because it is determined by the user at runtime. | +| `ToolChoice: Auto` PascalCase enum literal | Matches the real JSON value (`"Auto"`), which differs from the lowercase `auto` used by `GenAICommons.ENUM_ToolChoice` at runtime. Values: `Auto`, `None`, `Any`, `Tool`. When `ToolChoice` is set to `Tool`, the `toolChoiceToolName` property must be set to the agent-local tool `name` (the `name` field in `tools[]`). The writer/validator must ensure the named tool exists on the agent, is unique, has `toolType: "Microflow"`, and is `Enabled: true`; otherwise emit a validation error. `toolChoiceToolName` selects the microflow tool the agent will prefer when `ToolChoice` is fixed to `Tool`. | | `MaxTokens: ` on the agent | Matches the JSON `maxTokens` field; agent-level inference parameter | | `TOOL`, `KNOWLEDGE BASE`, `MCP SERVICE` as singular block types | Matches the `OPERATION` singular used in REST CLIENT; each block defines one resource | | `MCP SERVICE { Enabled, Description }` | The name is the qualified name of a ConsumedMCPService document (the whole service is attached as a bundle of tools) | | `KNOWLEDGE BASE { Source: , Collection, MaxResults, ... }` | `` is the per-agent identifier stored in JSON `name`; `Source:` references the KB document. Matches `Agent007`'s `My_mem` KB entry | -| `TOOL { Microflow: ..., Description, Enabled }` | Speculative: microflow-tool JSON shape not yet observed (test3 only has MCP tools). Final shape TBD when we capture a sample | +| `TOOL { Microflow: , Description, Enabled }` | Microflow tool references a microflow by qualified name; the writer encodes this in `tools[]` with `toolType: "Microflow"` and `document: { qualifiedName: , documentId: }`. Target microflows must return a `String`; input parameters are restricted to primitives and `GenAICommons.Request`/`GenAICommons.Tool` types. | | `Variables: (...)` is the input-schema analog of REST CLIENT's `Parameters: (...)` | Declares what the caller must supply; values flow in via the `CONTEXT` object at the `CALL AGENT` site. Inline form matches REST CLIENT's `Parameters: ($id: String)` | | No `Access:` on tool blocks | `UserAccessApproval` is NOT stored in the agent document JSON — it's a runtime-only concern on the `AgentCommons.Tool` entity. (Earlier drafts of this proposal incorrectly placed it on the block.) | | Body omitted when there are no tools/KB/MCP | Same concession REST CLIENT makes implicitly — empty bodies are awkward; drop them | @@ -410,13 +442,14 @@ type Agent struct { Entity *EntityRef // optional, points to a domain entity MaxTokens *int // optional ToolChoice string // optional: "Auto", "None", "Any", "Tool" + ToolChoiceToolName *string // optional: when ToolChoice == "Tool", the agent-local tool `name` to prefer Temperature *float64 // optional, not yet observed TopP *float64 // optional, not yet observed } type Variable struct { Key string - IsAttributeInEntity bool + IsAttributeInEntity bool // true when an attribute with name == Key is found on the referenced entity } type EntityRef struct { @@ -425,19 +458,18 @@ type EntityRef struct { } type DocRef struct { - DocumentID string // UUID of the referenced CustomBlobDocument + DocumentID string // UUID of the referenced CustomBlobDocument or a microflow QualifiedName string // Module.DocumentName } // Entry in the agent's tools[] array type ToolRef struct { ID string // per-tool UUID (generated by writer) - Name string - Description string - Enabled bool - ToolType string // "MCP" | "Microflow" (microflow shape TBD) - Document *DocRef // set when ToolType=="MCP", references ConsumedMCPService - Microflow string // set when ToolType=="Microflow" (speculative) + Name string // only relevant for microflow tools; unique tool name (used by `toolChoiceToolName`); Tool name must start with a letter or underscore and contain only letters, numbers, and underscores. + Description string // only relevant for microflow tools + Enabled bool // diabled tools will be ignored at runtime + ToolType string // "MCP" | "Microflow" + Document *DocRef // references ConsumedMCPService for ToolType=="MCP", references a microflow for ToolType=="Microflow" } // Entry in the agent's knowledgebaseTools[] array @@ -446,10 +478,11 @@ type KBToolRef struct { Name string Description string Enabled bool - ToolType string // empty string in observed sample + ToolType string // unused for knowledge base tools Document *DocRef // references KnowledgeBase document CollectionIdentifier string MaxResults int + MinSimilarity float64 // decimal between 0.0 and 1.0 } // Peer document types (same wrapper, different Contents JSON) @@ -475,7 +508,7 @@ type KnowledgeBase struct { Provider string // "MxCloudGenAI" Fields map[string]interface{} // providerFields (includes modelDisplayName, modelName) - KeyConstant *ConstantRef + KeyConstant *ConstantRef // providerFields.key → String constant } type ConsumedMCPService struct { @@ -488,6 +521,8 @@ type ConsumedMCPService struct { Version string // app-specified version InnerDocumentation string // Contents.documentation (free text) ConnectionTimeoutSeconds int + Endpoint *DocRef // reference to a String constant document containing the MCP endpoint + AuthenticationMicroflow *DocRef // optional microflow used to produce auth headers; must have no input params and return List } type ConstantRef struct { @@ -532,7 +567,7 @@ func (r *Reader) ConsumedMCPServiceByQualifiedName(name string) *agenteditor.Con - `CATALOG.AGENTS` (module, name, qualified_name, usage_type, entity, model, variables, tool_count, kb_count) - `CATALOG.MODELS` (module, name, qualified_name, provider, key_constant) - `CATALOG.KNOWLEDGE_BASES` (module, name, qualified_name, provider, key_constant) -- `CATALOG.CONSUMED_MCP_SERVICES` (module, name, qualified_name, protocol_version, timeout_seconds) +- `CATALOG.CONSUMED_MCP_SERVICES` (module, name, qualified_name, endpoint_constant, protocol_version, authentication_microflow, timeout_seconds) #### 1.5 Add Grammar/AST/Visitor/Executor @@ -561,7 +596,7 @@ In `sdk/mpr/writer_customblob.go` (generic wrapper for all four types): - Set `Excluded = false`, `ExportLevel = "Hidden"` (matches the new Agent Editor defaults) - Generate stable UUIDs for `$ID` and `Metadata.$ID` - For `Agent`: generate UUIDs for `id` field on each `tools[]` and `knowledgebaseTools[]` entry -- For `Model` / `KnowledgeBase`: resolve the `Key` constant reference to `{documentId, qualifiedName}` by looking up the String constant in the reader +- For `Model` / `KnowledgeBase` / `ConsumedMCPService`: resolve the `Key` or `Endpoint` constant reference to `{documentId, qualifiedName}` by looking up the String constant in the reader #### 2.2 Add Grammar/AST/Visitor/Executor for CREATE/DROP @@ -573,7 +608,7 @@ In `sdk/mpr/writer_customblob.go` (generic wrapper for all four types): - Entity reference must exist (if specified) - Variables marked `EntityAttribute` must correspond to attributes on the referenced entity -- `UsageType` must be a known value (`Task` or `Conversational`) +- `UsageType` must be a known value (`Task` or `Chat`) - Variable names used in `{{...}}` in prompts should match declared variables (warning, not error) ### Phase 3: Integration & Catalog @@ -610,7 +645,7 @@ Full agent support requires MDL coverage of related `CustomBlobDocument` types a #### 4.1 `CREATE MODEL` Document -Models are peer `CustomBlobDocument`s that reference a Mendix Cloud GenAI Portal key stored in a **String constant**. The minimum input from the user is the provider and the constant reference — Portal metadata (`displayName`, `keyId`, `keyName`, `environment`, `resourceName`, etc.) is filled by Studio Pro when the user clicks **Test Key** and shouldn't be user-set in MDL. +Models are peer `CustomBlobDocument`s that reference a Mendix Cloud GenAI Portal key stored in a **String constant**. The minimum input from the user is the provider and the constant reference — Portal metadata (`displayName`, `keyId`, `keyName`, `environment`, `resourceName`, etc.) is filled by Studio Pro when a constant with a valid key value is selected. Matches the observed BSON for `Agents.MyFirstModel`: @@ -652,12 +687,12 @@ At runtime, `AgentEditorCommons.ASU_AgentEditor` reads the constant and creates #### 4.2 `CREATE KNOWLEDGE BASE` Document -Same shape as Model, but `providerFields` carries embedding-model info instead of model-resource info. User-settable fields are just `Provider` and `Key`: +Same shape as Model, but `providerFields` carries besides information about the knowledgebase also a refrence to an embedding-model. User-settable fields are just `Provider` and `Key`: ```sql CREATE KNOWLEDGE BASE Agents."Knowledge_base" ( Provider: MxCloudGenAI, - Key: Agents.LLMKey + Key: Agents.KBKey ); ``` @@ -666,13 +701,14 @@ CREATE KNOWLEDGE BASE Agents."Knowledge_base" ( ```sql CREATE KNOWLEDGE BASE Agents."Knowledge_base" ( Provider: MxCloudGenAI, - Key: Agents.LLMKey, + Key: Agents.KBKey, ModelDisplayName: 'text-embedding-3-large', -- Portal-populated ModelName: 'text-embedding-3-large' -- Portal-populated ); ``` Referenced from agents via `KNOWLEDGE BASE { Source: , ... }` blocks inside the agent body. +At runtime, `AgentEditorCommons.ASU_AgentEditor` reads the constant and creates the corresponding `GenAICommons.ConsumedKnowledgeBase`. **JSON output shape:** ```json @@ -689,18 +725,21 @@ Referenced from agents via `KNOWLEDGE BASE { Source: , ... #### 4.3 `CREATE CONSUMED MCP SERVICE` Document -Matches the observed BSON for `Agents.Consumed_MCP_service`. Endpoint and credentials are **not** part of the document — they're runtime configuration on the `MCPClient.ConsumedMCPService` entity. The document only carries protocol version, app-level version, timeout, and documentation. +Matches the observed BSON for `Agents.Consumed_MCP_service`. The document carries protocol version, app-level version, timeout, documentation, and an endpoint constant reference. It can also carry an optional authentication microflow reference. ```sql CREATE CONSUMED MCP SERVICE Agents."Consumed_MCP_service" ( ProtocolVersion: v2025_03_26, Version: '0.0.1', ConnectionTimeoutSeconds: 30, + Endpoint: Agents.MCPEndpoint, + AuthenticationMicroflow: Agents.AuthenticationMicroflow, Documentation: 'Description of what this MCP service provides' ); ``` Referenced from agents via `MCP SERVICE { ... }` blocks inside the agent body. +At runtime, `AgentEditorCommons.ASU_AgentEditor` reads the constant and creates the corresponding `MCPClient.ConsumedMCPService`. **JSON output shape:** ```json @@ -708,7 +747,15 @@ Referenced from agents via `MCP SERVICE { ... }` blocks inside t "protocolVersion": "v2025_03_26", "documentation": "Description of what this MCP service provides", "version": "0.0.1", - "connectionTimeoutSeconds": 30 + "connectionTimeoutSeconds": 30, + "endpoint": { + "documentId": "", + "qualifiedName": "Agents.MCPEndpoint" + }, + "authenticationMicroflow": { + "documentId": "", + "qualifiedName": "Agents.AuthenticationMicroflow" + } } ``` @@ -786,7 +833,7 @@ A "smart app" in Mendix typically has these layers, all expressible in MDL: Unlike the initial draft of this proposal, agents in Mendix are **not** wired up by building the request manually in an action microflow. The correct flow is: 1. **Studio Pro design time** — the developer creates agent documents (and model documents) in Studio Pro. Tools, knowledge bases, and MCP servers are **attached to the agent in the agent document itself** (not added at runtime). -2. **Model key** — a Mendix Cloud GenAI Portal key is stored in a String constant on the model document. At runtime, `ASU_AgentEditor` (registered as after-startup microflow) reads the key and auto-creates the corresponding `GenAICommons.DeployedModel`. +2. **Model key** — a Mendix Cloud GenAI Portal key is stored in a String constant on the model document. At runtime, `ASU_AgentEditor` (registered as after-startup microflow) reads the key and auto-creates the corresponding `GenAICommons.DeployedModel`, the `GenAICommons.ConsumedKnowledgeBase`, `MCPlient.ConsumedMCPService` and links all up in `AgentCommons.Agent` objects. 3. **Call Agent activity** — in a microflow, a single **"Call Agent With History"** or **"Call Agent Without History"** toolbox action does everything: resolve the agent's in-use version, select its deployed model, replace variable placeholders from the context object, wire in tools/knowledge bases/MCP servers declared on the agent, and call the LLM. 4. **Conversational UI** — to use the agent in a chat, call **"New Chat for Agent"** which creates a `ChatContext` pre-configured with the agent's deployed model, system prompt, and action microflow. The action microflow for chat just calls **"Call Agent With History"** with the request built by `Default Preprocessing`. @@ -984,7 +1031,7 @@ Tools, knowledge bases, and MCP servers are declared in the **agent document its ```sql -- The agent definition — stored as a CustomBlobDocument in the project CREATE AGENT Support."CustomerSupportAgent" ( - UsageType: Conversational, + UsageType: Chat, Description: 'Customer support agent with lookup and ticketing tools', SystemPrompt: 'You are a helpful customer support agent for an e-commerce company.