Skip to content

Commit ec582b8

Browse files
authored
Merge branch 'main' into feature/docu-chapter-fairification-with-CM-CMEM-8258
2 parents bd04826 + 1b6939a commit ec582b8

12 files changed

Lines changed: 463 additions & 19 deletions

File tree

‎data/integrations.yml‎

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,48 @@ integrations:
8888
(LLMs).
8989
9090
- name: OpenAI
91-
icon: ":simple-openai:"
91+
icon: ":fontawesome-brands-openai:"
9292
content: |
9393
Use the {{p.cmem_plugin_llm_ExecuteInstructions}} or {{p.cmem_plugin_llm_CreateEmbeddings}} task
9494
to interact with any [OpenAI provided Large Language Models](https://platform.openai.com/docs/models) (LLMs).
9595
96+
- name: Mistral AI
97+
icon: ":simple-mistralai:"
98+
content: |
99+
Use the {{p.cmem_plugin_llm_ExecuteInstructions}} or {{p.cmem_plugin_llm_CreateEmbeddings}} task
100+
to interact with any
101+
[Mistral AI provided Large Language Models](https://docs.mistral.ai/getting-started/models/models_overview/)
102+
(LLMs) through their OpenAI-compatible endpoint.
103+
104+
#####
105+
# AI Agents
106+
#####
107+
108+
- name: Antigravity CLI
109+
icon: ":simple-googlegemini:"
110+
content: |
111+
Connect the [Antigravity CLI](https://antigravity.google/docs/cli) (`agy`) to the Corporate Memory MCP
112+
servers with a bearer token, see [Agent Integration](../../automate/agent-integration/index.md).
113+
114+
- name: Claude Code
115+
icon: ":simple-claude:"
116+
content: |
117+
Connect [Claude Code](https://claude.com/product/claude-code) to the Corporate Memory MCP servers and let it
118+
inspect, author and run projects, datasets, transformations and workflows, see
119+
[Agent Integration](../../automate/agent-integration/index.md).
120+
121+
- name: Codex
122+
icon: ":fontawesome-brands-openai:"
123+
content: |
124+
Connect [Codex](https://developers.openai.com/codex/cli/) to the Corporate Memory MCP servers with an OAuth
125+
sign-in or a bearer token, see [Agent Integration](../../automate/agent-integration/index.md).
126+
127+
- name: Mistral Vibe
128+
icon: ":simple-mistralai:"
129+
content: |
130+
Connect [Mistral Vibe](https://github.com/mistralai/mistral-vibe) to the Corporate Memory MCP servers with
131+
an OAuth sign-in or a bearer token, see [Agent Integration](../../automate/agent-integration/index.md).
132+
96133
#####
97134
# Services
98135
#####

‎docs/automate/.pages‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ nav:
66
- Scheduling Workflows: scheduling-workflows
77
- Continuous Integration: continuous-integration
88
- n8n Integration: n8n-node
9+
- Agent Integration: agent-integration
910

Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
---
2+
title: "Agent Integration: Automate Corporate Memory with AI Agents"
3+
icon: material/robot-outline
4+
status: new
5+
tags:
6+
- Automate
7+
- Integration
8+
- Security
9+
---
10+
# Agent Integration
11+
12+
## Introduction
13+
14+
This page describes how to let an AI agent, such as a coding agent in a terminal, work with eccenca Corporate Memory.
15+
It compares the three mechanisms an agent can use to control Corporate Memory and gives configuration recipes for concrete agent products.
16+
17+
The recipes use `https://your-cmem.example.org` as the base URL.
18+
Replace it with the base URL of the Corporate Memory deployment.
19+
20+
## Choose a control mechanism
21+
22+
An agent can control Corporate Memory through the Model Context Protocol (MCP) servers, through the REST APIs and through the command line client cmemc.
23+
24+
| | MCP | API | cmemc |
25+
| --- | --- | --- | --- |
26+
| What the agent uses | Tools that the server advertises | HTTP endpoints described by an OpenAPI specification | Shell commands |
27+
| Discovery | The agent lists the available tools and their parameters | The agent or developer reads the specification | The agent reads `cmemc --help` and `cmemc <group> --help`, or the whole manual from `cmemc manual --format markdown-single-page` |
28+
| Authentication | OAuth sign-in as a user, or a bearer token | Bearer token | A cmemc connection |
29+
| Requires | An agent that supports MCP | Code that sends HTTP requests | An agent that can run shell commands |
30+
| Fits | Interactive exploration and authoring | Custom integrations and services | Repeatable scripts, bulk operations, backups and pipelines |
31+
32+
### MCP
33+
34+
An MCP client lists the tools of a server and calls them on request of the model.
35+
No glue code is needed, and the tool descriptions come from the server.
36+
Corporate Memory exposes three MCP servers:
37+
38+
| Server | Component | Endpoint | Purpose |
39+
| --- | --- | --- | --- |
40+
| `cmem-build` | Build (DataIntegration) | `/dataintegration/mcp` | Inspect, author and run projects, datasets, transformations and workflows |
41+
| `cmem-explore` | Explore (DataPlatform) | `/dataplatform/mcp/streamable` | Work with the Knowledge Graph |
42+
| `cmem-marketplace` | eccenca Marketplace | `/marketplace/mcp` | Find, inspect and install packages, and validate package manifests |
43+
44+
The names of the servers are free to choose.
45+
The Build MCP server is part of Build (DataIntegration) since v26.2.
46+
It inspects the workspace, describes plugins and task types, previews data and, when changes are allowed, creates and runs tasks.
47+
The Marketplace MCP server is part of [eccenca Marketplace](../../distribution/marketplace/index.md) since v26.2.8, and is reachable where that component is deployed, under the root path of its deployment.
48+
49+
!!! info
50+
51+
The Build and Marketplace MCP servers are enabled by default and offer only read-only tools.
52+
`com.eccenca.di.assistant.McpConfig.readOnly` controls this for Build, and `ECC_MARKETPLACE_MCP_READ_ONLY` for Marketplace, where it decides whether the tools that install and uninstall packages are registered at all.
53+
The default does not apply to the API or cmemc: an agent that uses them is limited only by the permissions of its account.
54+
See [Allow changes through the Build MCP server](#allow-changes-through-the-build-mcp-server).
55+
56+
### API
57+
58+
The [Build (DataIntegration) APIs](../../develop/dataintegration-apis/index.md) and the [Explore backend APIs](../../develop/dataplatform-apis/index.md) publish an OpenAPI specification.
59+
An agent that writes or runs its own HTTP client uses them directly.
60+
The API gives the most control, but the agent has to know the endpoints and handle authentication itself.
61+
It is the only mechanism in which the agent handles the token value itself, see [Protect the token](#protect-the-token).
62+
63+
### cmemc
64+
65+
An agent with shell access can run [cmemc](../cmemc-command-line-interface/index.md).
66+
Commands are grouped by resource type and each command documents itself with `--help`.
67+
`cmemc manual --format markdown-single-page` writes the complete command reference to standard output, which gives an agent the whole command surface in one step.
68+
Options such as `--id-only` and `--raw` produce output that is suited for further processing, see [Scripting with cmemc](../cmemc-command-line-interface/scripting-with-cmemc/index.md).
69+
The agent works with the permissions of the configured cmemc connection.
70+
71+
## Authentication and credentials
72+
73+
### Choose a method
74+
75+
The available methods depend on the mechanism.
76+
The MCP servers accept an OAuth sign-in or a bearer token, and the API accepts a bearer token.
77+
cmemc resolves the credential of its [connection](../cmemc-command-line-interface/configuration/file-based-configuration/index.md) itself, so the agent never handles the token value.
78+
79+
The two token methods work as follows:
80+
81+
- **OAuth sign-in:** The agent opens a browser window and the user signs in to Keycloak.
82+
The agent receives an access token and refreshes it without further interaction.
83+
This method needs an agent that supports OAuth for MCP servers.
84+
- **Bearer token:** The agent sends a fixed token in the `Authorization` header.
85+
This method works with any agent that supports custom headers, but the token expires.
86+
87+
The OAuth sign-in uses the `cmem` Keycloak client, which is a public client with the standard flow enabled.
88+
The recipes name its client ID, because Keycloak rejects the dynamic client registration that an agent attempts when no client ID is given.
89+
Depending on the agent, the client ID is a command line option or an entry in its configuration file.
90+
In a deployment that does not use the shipped `cmem` client, use the ID of the client that the web interface uses.
91+
92+
### Protect the token
93+
94+
A token from `cmemc admin token` expires after the access token lifetime of the realm, which is 10 minutes by default.
95+
After that, Corporate Memory rejects the requests and the agent needs a fresh token.
96+
`cmemc admin token --ttl` outputs the remaining lifetime of the token.
97+
98+
For an agent that depends on a bearer token, create a dedicated Keycloak client instead of reusing the account of a person:
99+
100+
1. Create a client as described in [Add the `cmem-service-account` client](../../deploy-and-configure/configuration/keycloak/index.md#add-the-cmem-service-account-client), with a different name such as `cmem-agent`.
101+
2. Give the client only the roles and [access conditions](../../deploy-and-configure/configuration/access-conditions/index.md) that the agent needs.
102+
3. Set a longer access token lifespan in the advanced settings of the client.
103+
4. Create a cmemc connection for the client with `OAUTH_GRANT_TYPE=client_credentials`, and fetch the token with `cmemc -c cmem-agent admin token`.
104+
105+
!!! warning
106+
107+
A token in a configuration file, such as `mcp_config.json`, is stored in plain text, and a longer lifetime extends the time in which a leaked token is usable.
108+
An agent that writes a token into a request or a script sends that token to its model provider with the rest of the conversation.
109+
Keep the token lifespan as short as the use case allows and restrict the client to the permissions the agent needs.
110+
Pass the token to generated code through an environment variable instead of embedding the value, and keep it out of committed files.
111+
112+
## Recipes
113+
114+
=== "Claude Code"
115+
116+
Claude Code discovers the OAuth configuration of the server and supports the sign-in directly.
117+
118+
1. Register the two MCP servers for the current user:
119+
120+
``` shell-session
121+
$ claude mcp add --scope user --transport http --client-id cmem cmem-explore https://your-cmem.example.org/dataplatform/mcp/streamable
122+
$ claude mcp add --scope user --transport http --client-id cmem cmem-build https://your-cmem.example.org/dataintegration/mcp
123+
```
124+
125+
2. Start `claude` and enter `/mcp`.
126+
3. Select a server and start the authentication.
127+
4. Sign in to Corporate Memory in the browser window that opens.
128+
129+
The `--scope` option controls where Claude Code stores the registration:
130+
131+
- `user`: for all projects of the current user
132+
- `local`: for the current project and the current user (default)
133+
- `project`: in a `.mcp.json` file in the project directory, which can be committed
134+
135+
With `--scope project`, the registration for the Build server looks like this:
136+
137+
``` json title=".mcp.json"
138+
{
139+
"mcpServers": {
140+
"cmem-build": {
141+
"type": "http",
142+
"url": "https://your-cmem.example.org/dataintegration/mcp",
143+
"oauth": {
144+
"clientId": "cmem"
145+
}
146+
}
147+
}
148+
}
149+
```
150+
151+
=== "Codex"
152+
153+
Codex registers the server first and signs in with a separate command.
154+
155+
1. Register the two MCP servers:
156+
157+
``` shell-session
158+
$ codex mcp add cmem-explore --oauth-client-id cmem --url https://your-cmem.example.org/dataplatform/mcp/streamable
159+
$ codex mcp add cmem-build --oauth-client-id cmem --url https://your-cmem.example.org/dataintegration/mcp
160+
```
161+
162+
2. Sign in to each server:
163+
164+
``` shell-session
165+
$ codex mcp login cmem-explore
166+
$ codex mcp login cmem-build
167+
```
168+
169+
On a machine without a browser, add `--no-browser`.
170+
The command prints the authorization URL and accepts the callback URL.
171+
172+
The registration is stored in `~/.codex/config.toml`:
173+
174+
``` toml title="~/.codex/config.toml"
175+
[mcp_servers.cmem-build]
176+
url = "https://your-cmem.example.org/dataintegration/mcp"
177+
178+
[mcp_servers.cmem-build.oauth]
179+
client_id = "cmem"
180+
callback_url = "http://127.0.0.1/callback/<random-path>"
181+
```
182+
183+
Codex can also read a bearer token from an environment variable, which keeps the token out of the configuration file:
184+
185+
``` shell-session
186+
$ codex mcp add cmem-build --bearer-token-env-var CMEM_TOKEN --url https://your-cmem.example.org/dataintegration/mcp
187+
$ export CMEM_TOKEN=$(cmemc -c your-config admin token)
188+
```
189+
190+
The variable has to be set again after the token expires, see [Protect the token](#protect-the-token).
191+
192+
=== "Antigravity CLI"
193+
194+
`agy mcp add` of the [Antigravity CLI](https://antigravity.google/docs/cli) has no option for an OAuth sign-in, and the sign-in that Antigravity performs by itself covers servers that support dynamic client registration, which Keycloak rejects, see [Choose a method](#choose-a-method).
195+
Pass a bearer token in a header instead.
196+
197+
1. Fetch an access token with cmemc:
198+
199+
``` bash
200+
TOKEN=$(cmemc -c your-config admin token)
201+
```
202+
203+
2. Register the two MCP servers with the token:
204+
205+
``` shell-session
206+
$ agy mcp add --header "Authorization: Bearer $TOKEN" --type http cmem-explore https://your-cmem.example.org/dataplatform/mcp/streamable
207+
$ agy mcp add --header "Authorization: Bearer $TOKEN" --type http cmem-build https://your-cmem.example.org/dataintegration/mcp
208+
```
209+
210+
Flags must come before the server name.
211+
212+
The registration, including the token, is stored in `~/.gemini/config/mcp_config.json`:
213+
214+
``` json title="~/.gemini/config/mcp_config.json"
215+
{
216+
"mcpServers": {
217+
"cmem-explore": {
218+
"disabled": false,
219+
"headers": {
220+
"Authorization": "Bearer <token>"
221+
},
222+
"serverUrl": "https://your-cmem.example.org/dataplatform/mcp/streamable"
223+
},
224+
"cmem-build": {
225+
"disabled": false,
226+
"headers": {
227+
"Authorization": "Bearer <token>"
228+
},
229+
"serverUrl": "https://your-cmem.example.org/dataintegration/mcp"
230+
}
231+
}
232+
}
233+
```
234+
235+
The token expires, see [Protect the token](#protect-the-token).
236+
237+
=== "Mistral Vibe"
238+
239+
Vibe reads the OAuth configuration of the server, but it takes the client ID from its configuration file instead of a command line option.
240+
241+
1. Register the two MCP servers without signing in:
242+
243+
``` shell-session
244+
$ vibe mcp add cmem-explore --no-login --url https://your-cmem.example.org/dataplatform/mcp/streamable
245+
$ vibe mcp add cmem-build --no-login --url https://your-cmem.example.org/dataintegration/mcp
246+
```
247+
248+
2. Add `client_id` to the `auth` table of each server in `~/.vibe/config.toml`:
249+
250+
``` toml title="~/.vibe/config.toml"
251+
[[mcp_servers]]
252+
url = "https://your-cmem.example.org/dataintegration/mcp"
253+
name = "cmem-build"
254+
transport = "streamable-http"
255+
256+
[mcp_servers.auth]
257+
type = "oauth"
258+
scopes = []
259+
client_id = "cmem"
260+
```
261+
262+
3. Start `vibe` and enter `/mcp login cmem-build`.
263+
4. Sign in to Corporate Memory in the browser window that opens.
264+
265+
Without `client_id`, Vibe registers a client dynamically, and Keycloak rejects the request with `Policy 'Trusted Hosts' rejected request to client-registration service`.
266+
267+
Vibe can also read a bearer token from an environment variable:
268+
269+
``` shell-session
270+
$ vibe mcp add cmem-build --api-key-env CMEM_TOKEN --url https://your-cmem.example.org/dataintegration/mcp
271+
$ export CMEM_TOKEN=$(cmemc -c your-config admin token)
272+
```
273+
274+
The variable has to be set again after the token expires, see [Protect the token](#protect-the-token).
275+
276+
=== "cmemc"
277+
278+
Any agent that can run shell commands needs no MCP registration to use cmemc.
279+
Configure a [cmemc connection](../cmemc-command-line-interface/configuration/file-based-configuration/index.md) and name it in the instructions of the agent, see [Instructions for the agent](#instructions-for-the-agent).
280+
281+
## Instructions for the agent
282+
283+
A registration connects an agent to Corporate Memory, but it does not tell the agent how to use it.
284+
An instruction file in the project does:
285+
286+
``` text title="AGENTS.md"
287+
Use `cmemc -c your-config` to work with Corporate Memory.
288+
Run `cmemc --help` and `cmemc <group> --help` to discover commands.
289+
Use `--id-only` and `--raw` for machine-readable output.
290+
```
291+
292+
The file name depends on the agent, for example `CLAUDE.md` for Claude Code or `AGENTS.md` for Codex.
293+
294+
The [cmem-package-template](https://github.com/eccenca/cmem-package-template) goes further than a single file.
295+
Package repositories generated from it ship agent rules and authoring skills for Marketplace packages, which read the manifest format from the Marketplace MCP server.
296+
297+
## Permissions of the agent
298+
299+
An agent acts with the permissions of the account that signs in, of the account that owns the bearer token, or of the configured cmemc connection.
300+
A dedicated account or client with limited permissions therefore bounds what an agent can do, whichever mechanism it uses.
301+
302+
### Allow changes through the Build MCP server
303+
304+
The Build MCP server offers only read-only tools: it inspects the workspace but does not create, change, delete or execute anything.
305+
The authoring, deletion and execution tools are exposed after setting `com.eccenca.di.assistant.McpConfig.readOnly = false` in the Build configuration.
306+
`com.eccenca.di.assistant.McpConfig.enabled = false` disables the server, and requests then return 404.
307+
308+
!!! warning
309+
310+
With the read-only mode off, an agent can delete projects and run workflows with the permissions of the authenticated account.
311+
Use a dedicated account or client with limited permissions, and review the actions of the agent.

0 commit comments

Comments
 (0)