aris-mcp 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
aris_mcp-0.1.0/LICENSE ADDED
@@ -0,0 +1 @@
1
+ MIT License
@@ -0,0 +1,207 @@
1
+ Metadata-Version: 2.4
2
+ Name: aris-mcp
3
+ Version: 0.1.0
4
+ Summary: Software AG ARIS REST API + MCP Server + A2A Server for Agentic AI!
5
+ Author-email: Audel Rouhi <knucklessg1@gmail.com>
6
+ License: MIT
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Environment :: Console
10
+ Classifier: Operating System :: POSIX :: Linux
11
+ Classifier: Programming Language :: Python :: 3
12
+ Requires-Python: <3.15,>=3.11
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: agent-utilities>=0.50.0
16
+ Requires-Dist: requests>=2.31.0
17
+ Provides-Extra: mcp
18
+ Requires-Dist: agent-utilities[mcp]>=0.50.0; extra == "mcp"
19
+ Provides-Extra: agent
20
+ Requires-Dist: agent-utilities[agent,logfire]>=0.50.0; extra == "agent"
21
+ Provides-Extra: all
22
+ Requires-Dist: agent-utilities[agent,logfire,mcp]>=0.50.0; extra == "all"
23
+ Provides-Extra: test
24
+ Requires-Dist: pytest-xdist>=3.6.0; extra == "test"
25
+ Requires-Dist: pytest; extra == "test"
26
+ Requires-Dist: pytest-asyncio; extra == "test"
27
+ Requires-Dist: pytest-cov; extra == "test"
28
+ Dynamic: license-file
29
+
30
+ # aris-mcp
31
+
32
+ Software AG **ARIS** REST API + MCP Server + A2A Server for Agentic AI.
33
+
34
+ `aris-mcp` connects the agent ecosystem to an ARIS tenant (ARIS Connect / ARIS
35
+ Enterprise / ARIS Cloud). It is the inbound *and* outbound bridge for the
36
+ agent-utilities Knowledge Graph's Camunda + ARIS ↔ KG integration:
37
+
38
+ - **Inbound** — the KG ARIS extractor (`enrichment/extractors/aris.py`) consumes
39
+ this client to lift ARIS models + their EPC structure (functions → BusinessTask,
40
+ rule operators → gateways, events collapsed, connections → FLOWS_TO) into the
41
+ canonical ArchiMate ontology, where they reconcile with Camunda/Egeria via
42
+ `ALIGNED_WITH` and are reasoned over in OWL/RDF.
43
+ - **Outbound** — the KG process-intelligence writeback (`enrichment/process_writeback.py`)
44
+ uses `set_model_attributes` to write a `kg_intelligence` attribute back onto
45
+ ARIS models (gated by `ARIS_ENABLE_WRITE`).
46
+
47
+ ## Available MCP Tools
48
+
49
+ The table below is auto-generated from the live server — do not edit by hand.
50
+
51
+ <!-- MCP-TOOLS-TABLE:START -->
52
+
53
+ | MCP Tool | Toggle Env Var | Description |
54
+ |----------|----------------|-------------|
55
+ | `aris_model` | `ARISTOOL` | Work with ARIS models and their EPC structure. |
56
+ | `aris_object` | `ARISTOOL` | Write attributes on a single ARIS object. |
57
+
58
+ _2 action-routed tools (default `MCP_TOOL_MODE=condensed`). Each is enabled unless its toggle is set false; set `MCP_TOOL_MODE=verbose` (or `both`) for the 1:1 per-operation surface. Auto-generated — do not edit._
59
+ <!-- MCP-TOOLS-TABLE:END -->
60
+
61
+ > Writes require `ARIS_ENABLE_WRITE=True`.
62
+
63
+ ## Environment Variables
64
+
65
+ Every variable the server reads, grouped by concern.
66
+
67
+ ### Connection & Credentials
68
+ | Variable | Purpose | Default |
69
+ |----------|---------|---------|
70
+ | `ARIS_API_BASE` | ARIS REST base URL (tenant API root) | `http://localhost/abs/api` |
71
+ | `ARIS_SSL_VERIFY` | verify TLS | `True` |
72
+ | `ARIS_OAUTH_URL` / `ARIS_CLIENT_ID` / `ARIS_CLIENT_SECRET` / `ARIS_TENANT` | OAuth2 client-credentials (preferred) | — |
73
+ | `ARIS_TOKEN` | static bearer token (alt to OAuth) | — |
74
+ | `ARIS_USERNAME` / `ARIS_PASSWORD` | HTTP basic (alt) | — |
75
+ | `ARIS_PATHS_JSON` | JSON overriding REST path templates per tenant | — |
76
+ | `ARIS_ENABLE_WRITE` | allow attribute writes | `False` |
77
+
78
+ > **Tenant differences.** ARIS deployments vary (Connect ABS portal vs the public
79
+ > ARIS API; on-prem vs Cloud). The defaults follow the common ARIS Connect ABS
80
+ > REST layout. If your tenant's paths differ, set `ARIS_PATHS_JSON`, e.g.
81
+ > `{"models":"v2/repository/models","model_objects":"v2/models/{model_id}/objects"}`.
82
+
83
+ ### MCP server / transport
84
+ | Variable | Description | Default |
85
+ |----------|-------------|---------|
86
+ | `TRANSPORT` | `stdio`, `streamable-http`, or `sse` | `stdio` |
87
+ | `HOST` | Bind host (HTTP transports) | `0.0.0.0` |
88
+ | `PORT` | Bind port (HTTP transports) | `8000` |
89
+ | `MCP_TOOL_MODE` | Tool surface: `condensed`, `verbose`, or `both` | `condensed` |
90
+ | `MCP_ENABLED_TOOLS` / `MCP_DISABLED_TOOLS` | Comma-separated tool allow/deny list | — |
91
+ | `MCP_ENABLED_TAGS` / `MCP_DISABLED_TAGS` | Comma-separated tag allow/deny list | — |
92
+ | `DEBUG` | Verbose logging | `False` |
93
+ | `PYTHONUNBUFFERED` | Unbuffered stdout (recommended in containers) | `1` |
94
+
95
+ ### Tool toggles
96
+ The action-routed tools can be disabled via their toggle env var (set to `false`):
97
+ `ARISTOOL` (see the [Available MCP Tools](#available-mcp-tools) table above).
98
+
99
+ ### Telemetry & governance
100
+ | Variable | Description | Default |
101
+ |----------|-------------|---------|
102
+ | `ENABLE_OTEL` | Enable OpenTelemetry export | `True` |
103
+ | `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector endpoint | — |
104
+ | `OTEL_EXPORTER_OTLP_PUBLIC_KEY` / `OTEL_EXPORTER_OTLP_SECRET_KEY` | OTLP auth keys | — |
105
+ | `OTEL_EXPORTER_OTLP_PROTOCOL` | OTLP protocol (e.g. `http/protobuf`) | — |
106
+ | `EUNOMIA_TYPE` | Authorization mode: `none`, `embedded`, `remote` | `none` |
107
+ | `EUNOMIA_POLICY_FILE` | Embedded policy file | `mcp_policies.json` |
108
+ | `EUNOMIA_REMOTE_URL` | Remote Eunomia server URL | — |
109
+
110
+ ### Agent CLI (full `[agent]` runtime only)
111
+ | Variable | Description | Default |
112
+ |----------|-------------|---------|
113
+ | `MCP_URL` | URL of the MCP server the agent connects to | `http://localhost:8000/mcp` |
114
+ | `PROVIDER` | LLM provider (e.g. `openai`) | `openai` |
115
+ | `MODEL_ID` | Model id (e.g. `gpt-4o`) | `gpt-4o` |
116
+ | `ENABLE_WEB_UI` | Serve the AG-UI web interface | `True` |
117
+
118
+ ## Installation
119
+
120
+ > **Install the slim `[mcp]` extra.** Install `aris-mcp[mcp]` — the MCP-server extra
121
+ > that pulls only the FastMCP / FastAPI tooling (`agent-utilities[mcp]`). It deliberately
122
+ > **excludes** the heavy agent runtime (the epistemic-graph engine, `pydantic-ai`,
123
+ > `dspy`, `llama-index`, `tree-sitter`), so `uvx`/container installs are dramatically
124
+ > smaller and faster. Use the full `[agent]` extra only when you need the integrated
125
+ > Pydantic AI agent.
126
+
127
+ Pick the extra that matches what you want to run:
128
+
129
+ | Extra | Installs | Use when |
130
+ |-------|----------|----------|
131
+ | `aris-mcp[mcp]` | Slim MCP server only (`agent-utilities[mcp]` — FastMCP/FastAPI) | You only run the **MCP server** (smallest install / image) |
132
+ | `aris-mcp[agent]` | Full agent runtime (`agent-utilities[agent,logfire]` — Pydantic AI + the epistemic-graph engine) | You run the **integrated agent** |
133
+ | `aris-mcp[all]` | Everything (`mcp` + `agent` + `logfire`) | Development / both surfaces |
134
+
135
+ ```bash
136
+ # MCP server only (recommended for tool hosting — slim deps)
137
+ uv pip install "aris-mcp[mcp]"
138
+
139
+ # Full agent runtime (Pydantic AI + epistemic-graph engine)
140
+ uv pip install "aris-mcp[agent]"
141
+
142
+ # Everything (development)
143
+ uv pip install "aris-mcp[all]" # or: python -m pip install "aris-mcp[all]"
144
+ ```
145
+
146
+ ### Container images (`:mcp` vs `:agent`)
147
+
148
+ One multi-stage `docker/Dockerfile` builds two right-sized images, selected by `--target`:
149
+
150
+ | Image tag | Build target | Contents | Entrypoint |
151
+ |-----------|--------------|----------|------------|
152
+ | `knucklessg1/aris-mcp:mcp` | `--target mcp` | `aris-mcp[mcp]` — **slim**, no engine/`pydantic-ai`/`dspy`/`llama-index`/`tree-sitter` | `aris-mcp` |
153
+ | `knucklessg1/aris-mcp:latest` | `--target agent` (default) | `aris-mcp[agent]` — **full** agent runtime + epistemic-graph engine | `aris-agent` |
154
+
155
+ ```bash
156
+ docker build --target mcp -t knucklessg1/aris-mcp:mcp docker/ # slim MCP server
157
+ docker build --target agent -t knucklessg1/aris-mcp:latest docker/ # full agent
158
+ ```
159
+
160
+ `docker/mcp.compose.yml` runs the slim `:mcp` server; `docker/agent.compose.yml` runs the
161
+ agent (`:latest`) with a co-located `:mcp` sidecar.
162
+
163
+ ### Knowledge-graph database (`epistemic-graph`)
164
+
165
+ The **full agent** (`[agent]` / `:latest`) embeds the **epistemic-graph** engine (pulled in
166
+ transitively via `agent-utilities[agent]`). For production — or to share one knowledge graph
167
+ across multiple agents — run **epistemic-graph as its own database container** and point the
168
+ agent at it instead of embedding it. Deployment recipes (single-node + Raft HA), connection
169
+ config, and the full database architecture (with diagrams) are documented in the
170
+ [epistemic-graph deployment guide](https://knuckles-team.github.io/epistemic-graph/deployment/).
171
+ The slim `[mcp]` server does **not** require the database.
172
+
173
+ ## Run
174
+
175
+ ```bash
176
+ aris-mcp # stdio (default)
177
+ aris-mcp --transport streamable-http --host 0.0.0.0 --port 8000
178
+ ```
179
+
180
+ ## Deployment
181
+
182
+ 1. **stdio** — `uv run aris-mcp` (see `mcp_config.json`).
183
+ 2. **streamable-http** — `aris-mcp --transport streamable-http --port 8000`.
184
+ 3. **local container** — build from `docker/` and run with the env above.
185
+ 4. **remote** — point your client at `http://aris-mcp.arpa/mcp`.
186
+
187
+
188
+ <!-- BEGIN agent-os-genesis-deploy (generated; do not edit between markers) -->
189
+
190
+ ## Deploy with `agent-os-genesis`
191
+
192
+ This package can be provisioned for you — skill-guided — by the **`agent-os-genesis`**
193
+ universal skill (its *single-package deploy mode*): it picks your install method, seeds
194
+ secrets to OpenBao/Vault (or `.env`), trusts your enterprise CA, registers the MCP
195
+ server, and verifies it — the same machinery that stands up the whole Agent OS, narrowed
196
+ to just this package. Ask your agent to **"deploy `aris-mcp` with agent-os-genesis"**.
197
+
198
+ | Install mode | Command |
199
+ |------|---------|
200
+ | Bare-metal, prod (PyPI) | `uvx aris-mcp` · or `uv tool install aris-mcp` |
201
+ | Bare-metal, dev (editable) | `uv pip install -e ".[all]"` · or `pip install -e ".[all]"` |
202
+ | Container, prod | deploy `knucklessg1/aris-mcp:latest` via docker-compose / swarm / podman / podman-compose / kubernetes |
203
+ | Container, dev (editable) | deploy `docker/compose.dev.yml` (source-mounted at `/src`; edits live on restart) |
204
+
205
+ Secrets are read-existing + seeded via `vault_sync` — you are only prompted for what's missing.
206
+
207
+ <!-- END agent-os-genesis-deploy -->
@@ -0,0 +1,178 @@
1
+ # aris-mcp
2
+
3
+ Software AG **ARIS** REST API + MCP Server + A2A Server for Agentic AI.
4
+
5
+ `aris-mcp` connects the agent ecosystem to an ARIS tenant (ARIS Connect / ARIS
6
+ Enterprise / ARIS Cloud). It is the inbound *and* outbound bridge for the
7
+ agent-utilities Knowledge Graph's Camunda + ARIS ↔ KG integration:
8
+
9
+ - **Inbound** — the KG ARIS extractor (`enrichment/extractors/aris.py`) consumes
10
+ this client to lift ARIS models + their EPC structure (functions → BusinessTask,
11
+ rule operators → gateways, events collapsed, connections → FLOWS_TO) into the
12
+ canonical ArchiMate ontology, where they reconcile with Camunda/Egeria via
13
+ `ALIGNED_WITH` and are reasoned over in OWL/RDF.
14
+ - **Outbound** — the KG process-intelligence writeback (`enrichment/process_writeback.py`)
15
+ uses `set_model_attributes` to write a `kg_intelligence` attribute back onto
16
+ ARIS models (gated by `ARIS_ENABLE_WRITE`).
17
+
18
+ ## Available MCP Tools
19
+
20
+ The table below is auto-generated from the live server — do not edit by hand.
21
+
22
+ <!-- MCP-TOOLS-TABLE:START -->
23
+
24
+ | MCP Tool | Toggle Env Var | Description |
25
+ |----------|----------------|-------------|
26
+ | `aris_model` | `ARISTOOL` | Work with ARIS models and their EPC structure. |
27
+ | `aris_object` | `ARISTOOL` | Write attributes on a single ARIS object. |
28
+
29
+ _2 action-routed tools (default `MCP_TOOL_MODE=condensed`). Each is enabled unless its toggle is set false; set `MCP_TOOL_MODE=verbose` (or `both`) for the 1:1 per-operation surface. Auto-generated — do not edit._
30
+ <!-- MCP-TOOLS-TABLE:END -->
31
+
32
+ > Writes require `ARIS_ENABLE_WRITE=True`.
33
+
34
+ ## Environment Variables
35
+
36
+ Every variable the server reads, grouped by concern.
37
+
38
+ ### Connection & Credentials
39
+ | Variable | Purpose | Default |
40
+ |----------|---------|---------|
41
+ | `ARIS_API_BASE` | ARIS REST base URL (tenant API root) | `http://localhost/abs/api` |
42
+ | `ARIS_SSL_VERIFY` | verify TLS | `True` |
43
+ | `ARIS_OAUTH_URL` / `ARIS_CLIENT_ID` / `ARIS_CLIENT_SECRET` / `ARIS_TENANT` | OAuth2 client-credentials (preferred) | — |
44
+ | `ARIS_TOKEN` | static bearer token (alt to OAuth) | — |
45
+ | `ARIS_USERNAME` / `ARIS_PASSWORD` | HTTP basic (alt) | — |
46
+ | `ARIS_PATHS_JSON` | JSON overriding REST path templates per tenant | — |
47
+ | `ARIS_ENABLE_WRITE` | allow attribute writes | `False` |
48
+
49
+ > **Tenant differences.** ARIS deployments vary (Connect ABS portal vs the public
50
+ > ARIS API; on-prem vs Cloud). The defaults follow the common ARIS Connect ABS
51
+ > REST layout. If your tenant's paths differ, set `ARIS_PATHS_JSON`, e.g.
52
+ > `{"models":"v2/repository/models","model_objects":"v2/models/{model_id}/objects"}`.
53
+
54
+ ### MCP server / transport
55
+ | Variable | Description | Default |
56
+ |----------|-------------|---------|
57
+ | `TRANSPORT` | `stdio`, `streamable-http`, or `sse` | `stdio` |
58
+ | `HOST` | Bind host (HTTP transports) | `0.0.0.0` |
59
+ | `PORT` | Bind port (HTTP transports) | `8000` |
60
+ | `MCP_TOOL_MODE` | Tool surface: `condensed`, `verbose`, or `both` | `condensed` |
61
+ | `MCP_ENABLED_TOOLS` / `MCP_DISABLED_TOOLS` | Comma-separated tool allow/deny list | — |
62
+ | `MCP_ENABLED_TAGS` / `MCP_DISABLED_TAGS` | Comma-separated tag allow/deny list | — |
63
+ | `DEBUG` | Verbose logging | `False` |
64
+ | `PYTHONUNBUFFERED` | Unbuffered stdout (recommended in containers) | `1` |
65
+
66
+ ### Tool toggles
67
+ The action-routed tools can be disabled via their toggle env var (set to `false`):
68
+ `ARISTOOL` (see the [Available MCP Tools](#available-mcp-tools) table above).
69
+
70
+ ### Telemetry & governance
71
+ | Variable | Description | Default |
72
+ |----------|-------------|---------|
73
+ | `ENABLE_OTEL` | Enable OpenTelemetry export | `True` |
74
+ | `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP collector endpoint | — |
75
+ | `OTEL_EXPORTER_OTLP_PUBLIC_KEY` / `OTEL_EXPORTER_OTLP_SECRET_KEY` | OTLP auth keys | — |
76
+ | `OTEL_EXPORTER_OTLP_PROTOCOL` | OTLP protocol (e.g. `http/protobuf`) | — |
77
+ | `EUNOMIA_TYPE` | Authorization mode: `none`, `embedded`, `remote` | `none` |
78
+ | `EUNOMIA_POLICY_FILE` | Embedded policy file | `mcp_policies.json` |
79
+ | `EUNOMIA_REMOTE_URL` | Remote Eunomia server URL | — |
80
+
81
+ ### Agent CLI (full `[agent]` runtime only)
82
+ | Variable | Description | Default |
83
+ |----------|-------------|---------|
84
+ | `MCP_URL` | URL of the MCP server the agent connects to | `http://localhost:8000/mcp` |
85
+ | `PROVIDER` | LLM provider (e.g. `openai`) | `openai` |
86
+ | `MODEL_ID` | Model id (e.g. `gpt-4o`) | `gpt-4o` |
87
+ | `ENABLE_WEB_UI` | Serve the AG-UI web interface | `True` |
88
+
89
+ ## Installation
90
+
91
+ > **Install the slim `[mcp]` extra.** Install `aris-mcp[mcp]` — the MCP-server extra
92
+ > that pulls only the FastMCP / FastAPI tooling (`agent-utilities[mcp]`). It deliberately
93
+ > **excludes** the heavy agent runtime (the epistemic-graph engine, `pydantic-ai`,
94
+ > `dspy`, `llama-index`, `tree-sitter`), so `uvx`/container installs are dramatically
95
+ > smaller and faster. Use the full `[agent]` extra only when you need the integrated
96
+ > Pydantic AI agent.
97
+
98
+ Pick the extra that matches what you want to run:
99
+
100
+ | Extra | Installs | Use when |
101
+ |-------|----------|----------|
102
+ | `aris-mcp[mcp]` | Slim MCP server only (`agent-utilities[mcp]` — FastMCP/FastAPI) | You only run the **MCP server** (smallest install / image) |
103
+ | `aris-mcp[agent]` | Full agent runtime (`agent-utilities[agent,logfire]` — Pydantic AI + the epistemic-graph engine) | You run the **integrated agent** |
104
+ | `aris-mcp[all]` | Everything (`mcp` + `agent` + `logfire`) | Development / both surfaces |
105
+
106
+ ```bash
107
+ # MCP server only (recommended for tool hosting — slim deps)
108
+ uv pip install "aris-mcp[mcp]"
109
+
110
+ # Full agent runtime (Pydantic AI + epistemic-graph engine)
111
+ uv pip install "aris-mcp[agent]"
112
+
113
+ # Everything (development)
114
+ uv pip install "aris-mcp[all]" # or: python -m pip install "aris-mcp[all]"
115
+ ```
116
+
117
+ ### Container images (`:mcp` vs `:agent`)
118
+
119
+ One multi-stage `docker/Dockerfile` builds two right-sized images, selected by `--target`:
120
+
121
+ | Image tag | Build target | Contents | Entrypoint |
122
+ |-----------|--------------|----------|------------|
123
+ | `knucklessg1/aris-mcp:mcp` | `--target mcp` | `aris-mcp[mcp]` — **slim**, no engine/`pydantic-ai`/`dspy`/`llama-index`/`tree-sitter` | `aris-mcp` |
124
+ | `knucklessg1/aris-mcp:latest` | `--target agent` (default) | `aris-mcp[agent]` — **full** agent runtime + epistemic-graph engine | `aris-agent` |
125
+
126
+ ```bash
127
+ docker build --target mcp -t knucklessg1/aris-mcp:mcp docker/ # slim MCP server
128
+ docker build --target agent -t knucklessg1/aris-mcp:latest docker/ # full agent
129
+ ```
130
+
131
+ `docker/mcp.compose.yml` runs the slim `:mcp` server; `docker/agent.compose.yml` runs the
132
+ agent (`:latest`) with a co-located `:mcp` sidecar.
133
+
134
+ ### Knowledge-graph database (`epistemic-graph`)
135
+
136
+ The **full agent** (`[agent]` / `:latest`) embeds the **epistemic-graph** engine (pulled in
137
+ transitively via `agent-utilities[agent]`). For production — or to share one knowledge graph
138
+ across multiple agents — run **epistemic-graph as its own database container** and point the
139
+ agent at it instead of embedding it. Deployment recipes (single-node + Raft HA), connection
140
+ config, and the full database architecture (with diagrams) are documented in the
141
+ [epistemic-graph deployment guide](https://knuckles-team.github.io/epistemic-graph/deployment/).
142
+ The slim `[mcp]` server does **not** require the database.
143
+
144
+ ## Run
145
+
146
+ ```bash
147
+ aris-mcp # stdio (default)
148
+ aris-mcp --transport streamable-http --host 0.0.0.0 --port 8000
149
+ ```
150
+
151
+ ## Deployment
152
+
153
+ 1. **stdio** — `uv run aris-mcp` (see `mcp_config.json`).
154
+ 2. **streamable-http** — `aris-mcp --transport streamable-http --port 8000`.
155
+ 3. **local container** — build from `docker/` and run with the env above.
156
+ 4. **remote** — point your client at `http://aris-mcp.arpa/mcp`.
157
+
158
+
159
+ <!-- BEGIN agent-os-genesis-deploy (generated; do not edit between markers) -->
160
+
161
+ ## Deploy with `agent-os-genesis`
162
+
163
+ This package can be provisioned for you — skill-guided — by the **`agent-os-genesis`**
164
+ universal skill (its *single-package deploy mode*): it picks your install method, seeds
165
+ secrets to OpenBao/Vault (or `.env`), trusts your enterprise CA, registers the MCP
166
+ server, and verifies it — the same machinery that stands up the whole Agent OS, narrowed
167
+ to just this package. Ask your agent to **"deploy `aris-mcp` with agent-os-genesis"**.
168
+
169
+ | Install mode | Command |
170
+ |------|---------|
171
+ | Bare-metal, prod (PyPI) | `uvx aris-mcp` · or `uv tool install aris-mcp` |
172
+ | Bare-metal, dev (editable) | `uv pip install -e ".[all]"` · or `pip install -e ".[all]"` |
173
+ | Container, prod | deploy `knucklessg1/aris-mcp:latest` via docker-compose / swarm / podman / podman-compose / kubernetes |
174
+ | Container, dev (editable) | deploy `docker/compose.dev.yml` (source-mounted at `/src`; edits live on restart) |
175
+
176
+ Secrets are read-existing + seeded via `vault_sync` — you are only prompted for what's missing.
177
+
178
+ <!-- END agent-os-genesis-deploy -->
@@ -0,0 +1,64 @@
1
+ """aris-mcp: Software AG ARIS REST API + MCP Server + A2A Server."""
2
+
3
+ import importlib
4
+ import inspect
5
+ from typing import Any
6
+
7
+ __version__ = "0.1.0"
8
+ __all__: list[str] = []
9
+
10
+ CORE_MODULES = ["aris_mcp.api_client"]
11
+ OPTIONAL_MODULES = {
12
+ "aris_mcp.agent_server": "agent",
13
+ "aris_mcp.mcp_server": "mcp",
14
+ }
15
+
16
+
17
+ def _expose_members(module):
18
+ for name, obj in inspect.getmembers(module):
19
+ if (inspect.isclass(obj) or inspect.isfunction(obj)) and not name.startswith(
20
+ "_"
21
+ ):
22
+ globals()[name] = obj
23
+ if name not in __all__:
24
+ __all__.append(name)
25
+
26
+
27
+ for module_name in CORE_MODULES:
28
+ module = importlib.import_module(module_name)
29
+ _expose_members(module)
30
+
31
+ _loaded_optional_modules: dict[str, Any] = {}
32
+
33
+
34
+ def _import_module_safely(module_name: str):
35
+ try:
36
+ return importlib.import_module(module_name)
37
+ except ImportError:
38
+ return None
39
+
40
+
41
+ def __getattr__(name: str) -> Any:
42
+ if name == "_MCP_AVAILABLE":
43
+ mcp_key = next((k for k in OPTIONAL_MODULES if "mcp_server" in k), None)
44
+ return _import_module_safely(mcp_key) is not None if mcp_key else False
45
+ if name == "_AGENT_AVAILABLE":
46
+ agent_key = next((k for k in OPTIONAL_MODULES if "agent_server" in k), None)
47
+ return _import_module_safely(agent_key) is not None if agent_key else False
48
+
49
+ for module_name in OPTIONAL_MODULES:
50
+ if module_name not in _loaded_optional_modules:
51
+ module = _import_module_safely(module_name)
52
+ if module is not None:
53
+ _loaded_optional_modules[module_name] = module
54
+ _expose_members(module)
55
+
56
+ module = _loaded_optional_modules.get(module_name)
57
+ if module is not None and hasattr(module, name):
58
+ return getattr(module, name)
59
+
60
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
61
+
62
+
63
+ def __dir__() -> list[str]:
64
+ return sorted(list(globals().keys()) + __all__)
@@ -0,0 +1,4 @@
1
+ from aris_mcp.agent_server import agent_server
2
+
3
+ if __name__ == "__main__":
4
+ agent_server()
@@ -0,0 +1,75 @@
1
+ """Graph-based Pydantic AI agent server entry point for aris-mcp."""
2
+
3
+ import logging
4
+ import os
5
+ import sys
6
+ import warnings
7
+
8
+ __version__ = "0.1.0"
9
+
10
+ logging.basicConfig(
11
+ level=logging.INFO,
12
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
13
+ )
14
+ logger = logging.getLogger(__name__)
15
+
16
+ DEFAULT_AGENT_NAME = None
17
+ DEFAULT_AGENT_DESCRIPTION = None
18
+ DEFAULT_AGENT_SYSTEM_PROMPT = None
19
+
20
+
21
+ def agent_server():
22
+ """Start the graph-based Pydantic AI agent server for ARIS."""
23
+ from agent_utilities import (
24
+ build_system_prompt_from_workspace,
25
+ create_agent_parser,
26
+ create_agent_server,
27
+ initialize_workspace,
28
+ load_identity,
29
+ )
30
+
31
+ global DEFAULT_AGENT_NAME, DEFAULT_AGENT_DESCRIPTION, DEFAULT_AGENT_SYSTEM_PROMPT
32
+ initialize_workspace()
33
+ meta = load_identity()
34
+ DEFAULT_AGENT_NAME = os.getenv("DEFAULT_AGENT_NAME", meta.get("name", "ARIS Agent"))
35
+ DEFAULT_AGENT_DESCRIPTION = os.getenv(
36
+ "AGENT_DESCRIPTION",
37
+ meta.get("description", "AI agent for Software AG ARIS operations."),
38
+ )
39
+ DEFAULT_AGENT_SYSTEM_PROMPT = os.getenv(
40
+ "AGENT_SYSTEM_PROMPT",
41
+ meta.get("content") or build_system_prompt_from_workspace(),
42
+ )
43
+
44
+ warnings.filterwarnings("ignore", message=".*urllib3.*")
45
+ warnings.filterwarnings("ignore", category=DeprecationWarning, module="fastmcp")
46
+
47
+ print(f"{DEFAULT_AGENT_NAME} v{__version__}", file=sys.stderr)
48
+ parser = create_agent_parser()
49
+ args = parser.parse_args()
50
+
51
+ create_agent_server(
52
+ mcp_url=args.mcp_url,
53
+ mcp_config=args.mcp_config or "mcp_config.json",
54
+ host=args.host,
55
+ port=args.port,
56
+ provider=args.provider,
57
+ model_id=args.model_id,
58
+ router_model=args.model_id,
59
+ agent_model=args.model_id,
60
+ base_url=args.base_url,
61
+ api_key=args.api_key,
62
+ custom_skills_directory=args.custom_skills_directory,
63
+ enable_web_ui=args.web,
64
+ enable_otel=args.otel,
65
+ otel_endpoint=args.otel_endpoint,
66
+ otel_headers=args.otel_headers,
67
+ otel_public_key=args.otel_public_key,
68
+ otel_secret_key=args.otel_secret_key,
69
+ otel_protocol=args.otel_protocol,
70
+ debug=args.debug,
71
+ )
72
+
73
+
74
+ if __name__ == "__main__":
75
+ agent_server()
File without changes
@@ -0,0 +1,96 @@
1
+ """Software AG ARIS REST API wrapper.
2
+
3
+ Client for the ARIS REST API (ARIS Connect / ARIS Enterprise / ARIS Cloud)
4
+ covering the surface the agent-utilities KG ARIS extractor and the outbound
5
+ process-intelligence writeback consume:
6
+
7
+ * **read** — model inventory, per-model EPC objects (functions/events/rules) and
8
+ their control-flow connections, and attribute read-back.
9
+ * **write** — model / object attribute writes (the outbound ``kg_intelligence``
10
+ enrichment); gated at the MCP-tool layer by ``ARIS_ENABLE_WRITE``.
11
+
12
+ ARIS deployments differ (Connect ABS portal vs the public ARIS API; on-prem vs
13
+ Cloud), so the **endpoint path templates are configurable** — pass overrides
14
+ (or set the matching env vars in :mod:`aris_mcp.auth`) to match your tenant.
15
+ The defaults follow the common ARIS Connect ABS REST layout
16
+ (``{base}/models``, ``{base}/models/{id}/objects`` …). Method names are stable;
17
+ only the paths move.
18
+ """
19
+
20
+ from typing import Any
21
+
22
+ from aris_mcp.api.api_client_base import ApiClientBase
23
+
24
+ # Default ARIS Connect ABS REST path templates. Override per tenant if needed.
25
+ DEFAULT_PATHS = {
26
+ "models": "models",
27
+ "model": "models/{model_id}",
28
+ "model_objects": "models/{model_id}/objects",
29
+ "model_connections": "models/{model_id}/connections",
30
+ "model_attributes": "models/{model_id}/attributes",
31
+ "object_attributes": "objects/{object_id}/attributes",
32
+ }
33
+
34
+
35
+ class ArisApi(ApiClientBase):
36
+ """Read/write client for an ARIS REST API tenant."""
37
+
38
+ def __init__(
39
+ self,
40
+ base_url: str,
41
+ token: str | None = None,
42
+ username: str | None = None,
43
+ password: str | None = None,
44
+ verify: bool = True,
45
+ paths: dict[str, str] | None = None,
46
+ ):
47
+ super().__init__(
48
+ base_url, token=token, username=username, password=password, verify=verify
49
+ )
50
+ self.paths = {**DEFAULT_PATHS, **(paths or {})}
51
+
52
+ # ── reads (consumed by the KG ARIS extractor) ──────────────────────────
53
+ def list_models(self, params: dict[str, Any] | None = None) -> Any:
54
+ """List models in the tenant/database (process + architecture)."""
55
+ return self.request("GET", self.paths["models"], params=params)
56
+
57
+ def get_model(self, model_id: str) -> Any:
58
+ """Get a single model's metadata (including its attributes)."""
59
+ return self.request("GET", self.paths["model"].format(model_id=model_id))
60
+
61
+ def list_model_objects(self, model_id: str) -> Any:
62
+ """List the EPC objects (functions/events/rule operators) of a model."""
63
+ return self.request(
64
+ "GET", self.paths["model_objects"].format(model_id=model_id)
65
+ )
66
+
67
+ def list_model_connections(self, model_id: str) -> Any:
68
+ """List the directed control-flow connections between a model's objects."""
69
+ return self.request(
70
+ "GET", self.paths["model_connections"].format(model_id=model_id)
71
+ )
72
+
73
+ def list_model_attributes(self, model_id: str) -> Any:
74
+ """Get a model's attributes (used for writeback idempotency read-back)."""
75
+ return self.request(
76
+ "GET", self.paths["model_attributes"].format(model_id=model_id)
77
+ )
78
+
79
+ # ── writes (outbound enrichment; gated by ARIS_ENABLE_WRITE at the tool) ─
80
+ def set_model_attributes(self, model_id: str, attributes: dict[str, Any]) -> Any:
81
+ """Write/update attributes on a model (e.g. the ``kg_intelligence`` blob)."""
82
+ return self.request(
83
+ "PUT",
84
+ self.paths["model_attributes"].format(model_id=model_id),
85
+ json={"attributes": attributes},
86
+ content_type="application/json",
87
+ )
88
+
89
+ def set_object_attributes(self, object_id: str, attributes: dict[str, Any]) -> Any:
90
+ """Write/update attributes on a single object."""
91
+ return self.request(
92
+ "PUT",
93
+ self.paths["object_attributes"].format(object_id=object_id),
94
+ json={"attributes": attributes},
95
+ content_type="application/json",
96
+ )