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 +1 -0
- aris_mcp-0.1.0/PKG-INFO +207 -0
- aris_mcp-0.1.0/README.md +178 -0
- aris_mcp-0.1.0/aris_mcp/__init__.py +64 -0
- aris_mcp-0.1.0/aris_mcp/__main__.py +4 -0
- aris_mcp-0.1.0/aris_mcp/agent_server.py +75 -0
- aris_mcp-0.1.0/aris_mcp/api/__init__.py +0 -0
- aris_mcp-0.1.0/aris_mcp/api/api_client_aris.py +96 -0
- aris_mcp-0.1.0/aris_mcp/api/api_client_base.py +92 -0
- aris_mcp-0.1.0/aris_mcp/api_client.py +12 -0
- aris_mcp-0.1.0/aris_mcp/auth.py +87 -0
- aris_mcp-0.1.0/aris_mcp/mcp/__init__.py +0 -0
- aris_mcp-0.1.0/aris_mcp/mcp/mcp_aris.py +90 -0
- aris_mcp-0.1.0/aris_mcp/mcp_server.py +68 -0
- aris_mcp-0.1.0/aris_mcp/prompts/__init__.py +0 -0
- aris_mcp-0.1.0/aris_mcp/prompts/main_agent.json +20 -0
- aris_mcp-0.1.0/aris_mcp/skills/__init__.py +0 -0
- aris_mcp-0.1.0/aris_mcp/skills/aris-starter/SKILL.md +19 -0
- aris_mcp-0.1.0/aris_mcp.egg-info/PKG-INFO +207 -0
- aris_mcp-0.1.0/aris_mcp.egg-info/SOURCES.txt +26 -0
- aris_mcp-0.1.0/aris_mcp.egg-info/dependency_links.txt +1 -0
- aris_mcp-0.1.0/aris_mcp.egg-info/entry_points.txt +9 -0
- aris_mcp-0.1.0/aris_mcp.egg-info/requires.txt +17 -0
- aris_mcp-0.1.0/aris_mcp.egg-info/top_level.txt +5 -0
- aris_mcp-0.1.0/pyproject.toml +59 -0
- aris_mcp-0.1.0/setup.cfg +4 -0
- aris_mcp-0.1.0/tests/test_api_client_aris.py +81 -0
- aris_mcp-0.1.0/tests/test_startup.py +37 -0
aris_mcp-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MIT License
|
aris_mcp-0.1.0/PKG-INFO
ADDED
|
@@ -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 -->
|
aris_mcp-0.1.0/README.md
ADDED
|
@@ -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,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
|
+
)
|