adaptorch-mcp 0.3.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.
@@ -0,0 +1,185 @@
1
+ Metadata-Version: 2.4
2
+ Name: adaptorch-mcp
3
+ Version: 0.3.0
4
+ Summary: Installable MCP bridge for AdaptOrch
5
+ Author: AdaptOrch maintainers
6
+ License: Proprietary — Copyright EGG. All rights reserved.
7
+ Project-URL: Homepage, https://github.com/dmae97/adaptorch_mcp
8
+ Project-URL: Repository, https://github.com/dmae97/adaptorch_mcp
9
+ Project-URL: Issues, https://github.com/dmae97/adaptorch_mcp/issues
10
+ Project-URL: Documentation, https://github.com/dmae97/adaptorch_mcp#readme
11
+ Keywords: mcp,model-context-protocol,adaptorch,agent-orchestration
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: >=3.11
21
+ Description-Content-Type: text/markdown
22
+ Requires-Dist: adaptorch[api]>=0.1.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: build>=1.2; extra == "dev"
25
+ Requires-Dist: mypy>=1.10; extra == "dev"
26
+ Requires-Dist: pytest>=8.2; extra == "dev"
27
+ Requires-Dist: ruff>=0.6; extra == "dev"
28
+
29
+ # adaptorch-mcp
30
+
31
+ Installable Python wrapper for the AdaptOrch MCP server.
32
+
33
+ The package intentionally delegates runtime behavior to `adaptorch.mcp_server`, so MCP tools, transports, safety checks, prompts, and optional algorithm controls stay aligned with AdaptOrch core.
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ pip install adaptorch-mcp
39
+ ```
40
+
41
+ If AdaptOrch is not published to your package index yet:
42
+
43
+ ```bash
44
+ pip install "adaptorch[api] @ git+https://github.com/dmae97/adaptorch.git"
45
+ pip install adaptorch-mcp
46
+ ```
47
+
48
+ One-shot with `uvx`:
49
+
50
+ ```bash
51
+ uvx adaptorch-mcp --help
52
+ uvx --with "adaptorch[api] @ git+https://github.com/dmae97/adaptorch.git" adaptorch-mcp --help
53
+ ```
54
+
55
+ For contributors inside this monorepo:
56
+
57
+ ```bash
58
+ uv sync --all-packages --extra dev
59
+ uv run adaptorch-mcp --help
60
+ ```
61
+
62
+ ## Run stdio MCP
63
+
64
+ Use stdio for Claude Code, Claude Desktop, and other local MCP hosts.
65
+
66
+ ```bash
67
+ export ADAPTORCH_CONTROL_PLANE_TOKEN="<your-token>"
68
+ adaptorch-mcp --transport stdio --base-url https://adaptorch.com
69
+ ```
70
+
71
+ ## Run HTTP MCP
72
+
73
+ Use HTTP for local gateways, reverse proxies, or remote MCP clients. Keep the client-facing MCP token separate from the upstream AdaptOrch token.
74
+
75
+ ```bash
76
+ export ADAPTORCH_CONTROL_PLANE_TOKEN="<upstream-adaptorch-token>"
77
+ export ADAPTORCH_MCP_HTTP_AUTH_TOKEN="<client-facing-mcp-token>"
78
+
79
+ adaptorch-mcp \
80
+ --transport http \
81
+ --base-url https://adaptorch.com \
82
+ --http-host 127.0.0.1 \
83
+ --http-port 8765 \
84
+ --http-auth-token "$ADAPTORCH_MCP_HTTP_AUTH_TOKEN"
85
+ ```
86
+
87
+ Health check:
88
+
89
+ ```bash
90
+ python - <<'PY'
91
+ import httpx
92
+ print(httpx.get('http://127.0.0.1:8765/mcp/health').json())
93
+ PY
94
+ ```
95
+
96
+ ## CLI reference
97
+
98
+ | Command | Purpose | Important options |
99
+ | --- | --- | --- |
100
+ | `adaptorch-mcp` | Start the stdio or HTTP MCP server. | `--transport stdio|http`, `--base-url`, `--api-token`, `--timeout-seconds`, `--stdio-framing`, `--http-host`, `--http-port`, `--http-auth-token` |
101
+ | `adaptorch-mcp-doctor` | Print redacted local diagnostics. | `--json`, `--strict` |
102
+ | `adaptorch-mcp-smoke` | Verify stdio `initialize` + `tools/list`. | `--command`, `--base-url`, `--api-token`, `--timeout-seconds`, repeatable `--expected-tool` |
103
+
104
+ For `adaptorch-mcp`, the public wrapper resolves the control-plane URL in this order: explicit `--base-url`, then trimmed/validated `ADAPTORCH_CONTROL_PLANE_BASE_URL`, then the hosted fallback `https://adaptorch.com`. `adaptorch-mcp-smoke` keeps a local-dev fallback of `http://127.0.0.1:8000` when no base URL is configured. Pass `--base-url` explicitly in checked-in MCP client configs for reproducible behavior.
105
+
106
+ ## Environment variables
107
+
108
+ | Variable | Purpose | Notes |
109
+ | --- | --- | --- |
110
+ | `ADAPTORCH_CONTROL_PLANE_TOKEN` | Upstream AdaptOrch token. | Required unless `--api-token` is passed. |
111
+ | `ADAPTORCH_CONTROL_PLANE_BASE_URL` | Base URL used when `--base-url` is omitted. | Trimmed and validated as HTTP(S); do not embed credentials. |
112
+ | `ADAPTORCH_MCP_HTTP_AUTH_TOKEN` | Client-facing bearer token for HTTP/SSE MCP. | Keep separate from the upstream token. |
113
+ | `ADAPTORCH_MCP_ALLOWED_ORIGINS` | Comma-separated HTTP origin allowlist. | Use with browser or remote HTTP clients. |
114
+ | `ADAPTORCH_MCP_MAX_PAYLOAD_SIZE_BYTES` | Maximum accepted HTTP request body size. | Keep bounded for public deployments. |
115
+ | `ADAPTORCH_MCP_REQUEST_TIMEOUT_SECONDS` | HTTP request timeout budget. | Applies to HTTP server request handling. |
116
+ | `ADAPTORCH_MCP_MAX_SSE_SUBSCRIBERS` | Maximum concurrent SSE subscribers. | Defaults are provided by `adaptorch.mcp_server`. |
117
+ | `ADAPTORCH_MCP_TIMEOUT_SECONDS` | Control-plane client timeout for app-factory usage. | Useful when embedding the ASGI app. |
118
+ | `ADAPTORCH_MCP_HTTP_HOST` / `ADAPTORCH_MCP_HTTP_PORT` | Shell/template values for `--http-host` and `--http-port`. | CLI flags are authoritative. |
119
+ | `ADAPTORCH_REPRODUCIBLE` | Benchmark/eval reproducibility beta. | Benchmark/eval scope only; not general runtime determinism. |
120
+ | `ADAPTORCH_ROUTER_ACCURACY_GATE` | Online-router learned-model gate. | `point` default or `wilson`; advanced/operator use. |
121
+ | `ADAPTORCH_PAPER_SEMANTIC_WEIGHT` | Paper-mode lexical/semantic blend. | Default `0.35`; nonzero values use Python scoring over the native fast path. |
122
+
123
+ ## Engine-delegated optional controls
124
+
125
+ The wrapper forwards these controls to the installed `adaptorch` engine; it does
126
+ not implement routing, synthesis, or benchmark algorithms itself. See the root
127
+ configuration guide for non-env controls such as `manifest_canonical_sha256`,
128
+ `pass_rate_credit`, `quality_signal`, `prefer_multi_model_ensemble_singleton`,
129
+ and MCP `prefer_ensemble_singleton`.
130
+
131
+ ## Tool surface
132
+
133
+ | Tool | Purpose |
134
+ | --- | --- |
135
+ | `adaptorch_run` | Submit an AdaptOrch task payload and optionally wait. |
136
+ | `adaptorch_get_run` | Read run summary by `run_id`. |
137
+ | `adaptorch_get_artifacts` | Read artifact metadata for a run. |
138
+ | `adaptorch_list_runs` | List recent runs. |
139
+ | `adaptorch_get_traces` | Read execution traces. |
140
+ | `adaptorch_cancel_run` | Request run cancellation (write/destructive; keep manually approved). |
141
+ | `adaptorch_route_topology` | Locally route a DAG through AdaptOrch's topology router. |
142
+ | `adaptorch_server_metrics` | Read redacted MCP server metrics. |
143
+ | `adaptorch_capabilities` | Read synthesis modes, connectors, and server features. |
144
+ | `adaptorch_plan_catalog` | Read hosted plan catalog: Starter `$0`, Pro `$39`, Team `$149`. |
145
+
146
+ ## Diagnostics and smoke tests
147
+
148
+ ```bash
149
+ adaptorch-mcp-doctor
150
+ adaptorch-mcp-doctor --json
151
+ adaptorch-mcp-doctor --strict
152
+ ```
153
+
154
+ The doctor command reports package availability, expected MCP tools, redacted environment metadata, and `controlPlane` base-url resolution details without printing token values.
155
+
156
+ ```bash
157
+ export ADAPTORCH_CONTROL_PLANE_TOKEN="<your-token>"
158
+ adaptorch-mcp-smoke --base-url https://adaptorch.com
159
+ ```
160
+
161
+ Expected JSON includes `"ok": true`, `adaptorch_plan_catalog`, and the expected core tool subset. If no base URL is supplied, smoke targets `http://127.0.0.1:8000` for local development. Add repeatable `--expected-tool <name>` flags when validating a specific hosted/core release.
162
+
163
+ ## Example configs
164
+
165
+ - `../../examples/claude_desktop_config.json`
166
+ - `../../examples/omk.mcp.json`
167
+ - `../../examples/mcp-http.env.example`
168
+
169
+ Checked-in examples use placeholders or environment interpolation. Fill real URLs and tokens only in local, uncommitted config files. For shared or production clients, avoid auto-approving run, artifact, and trace readers unless those payloads are already sanitized.
170
+
171
+ ## HTTP app factory
172
+
173
+ `create_default_mcp_http_app()` embeds the canonical AdaptOrch MCP HTTP ASGI app. It requires an upstream control-plane token in the environment.
174
+
175
+ ```bash
176
+ export ADAPTORCH_CONTROL_PLANE_TOKEN="<upstream-adaptorch-token>"
177
+ export ADAPTORCH_CONTROL_PLANE_BASE_URL="https://adaptorch.com"
178
+ export ADAPTORCH_MCP_HTTP_AUTH_TOKEN="<client-facing-mcp-token>"
179
+ ```
180
+
181
+ ```python
182
+ from adaptorch_mcp import create_default_mcp_http_app
183
+
184
+ app = create_default_mcp_http_app()
185
+ ```
@@ -0,0 +1,157 @@
1
+ # adaptorch-mcp
2
+
3
+ Installable Python wrapper for the AdaptOrch MCP server.
4
+
5
+ The package intentionally delegates runtime behavior to `adaptorch.mcp_server`, so MCP tools, transports, safety checks, prompts, and optional algorithm controls stay aligned with AdaptOrch core.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install adaptorch-mcp
11
+ ```
12
+
13
+ If AdaptOrch is not published to your package index yet:
14
+
15
+ ```bash
16
+ pip install "adaptorch[api] @ git+https://github.com/dmae97/adaptorch.git"
17
+ pip install adaptorch-mcp
18
+ ```
19
+
20
+ One-shot with `uvx`:
21
+
22
+ ```bash
23
+ uvx adaptorch-mcp --help
24
+ uvx --with "adaptorch[api] @ git+https://github.com/dmae97/adaptorch.git" adaptorch-mcp --help
25
+ ```
26
+
27
+ For contributors inside this monorepo:
28
+
29
+ ```bash
30
+ uv sync --all-packages --extra dev
31
+ uv run adaptorch-mcp --help
32
+ ```
33
+
34
+ ## Run stdio MCP
35
+
36
+ Use stdio for Claude Code, Claude Desktop, and other local MCP hosts.
37
+
38
+ ```bash
39
+ export ADAPTORCH_CONTROL_PLANE_TOKEN="<your-token>"
40
+ adaptorch-mcp --transport stdio --base-url https://adaptorch.com
41
+ ```
42
+
43
+ ## Run HTTP MCP
44
+
45
+ Use HTTP for local gateways, reverse proxies, or remote MCP clients. Keep the client-facing MCP token separate from the upstream AdaptOrch token.
46
+
47
+ ```bash
48
+ export ADAPTORCH_CONTROL_PLANE_TOKEN="<upstream-adaptorch-token>"
49
+ export ADAPTORCH_MCP_HTTP_AUTH_TOKEN="<client-facing-mcp-token>"
50
+
51
+ adaptorch-mcp \
52
+ --transport http \
53
+ --base-url https://adaptorch.com \
54
+ --http-host 127.0.0.1 \
55
+ --http-port 8765 \
56
+ --http-auth-token "$ADAPTORCH_MCP_HTTP_AUTH_TOKEN"
57
+ ```
58
+
59
+ Health check:
60
+
61
+ ```bash
62
+ python - <<'PY'
63
+ import httpx
64
+ print(httpx.get('http://127.0.0.1:8765/mcp/health').json())
65
+ PY
66
+ ```
67
+
68
+ ## CLI reference
69
+
70
+ | Command | Purpose | Important options |
71
+ | --- | --- | --- |
72
+ | `adaptorch-mcp` | Start the stdio or HTTP MCP server. | `--transport stdio|http`, `--base-url`, `--api-token`, `--timeout-seconds`, `--stdio-framing`, `--http-host`, `--http-port`, `--http-auth-token` |
73
+ | `adaptorch-mcp-doctor` | Print redacted local diagnostics. | `--json`, `--strict` |
74
+ | `adaptorch-mcp-smoke` | Verify stdio `initialize` + `tools/list`. | `--command`, `--base-url`, `--api-token`, `--timeout-seconds`, repeatable `--expected-tool` |
75
+
76
+ For `adaptorch-mcp`, the public wrapper resolves the control-plane URL in this order: explicit `--base-url`, then trimmed/validated `ADAPTORCH_CONTROL_PLANE_BASE_URL`, then the hosted fallback `https://adaptorch.com`. `adaptorch-mcp-smoke` keeps a local-dev fallback of `http://127.0.0.1:8000` when no base URL is configured. Pass `--base-url` explicitly in checked-in MCP client configs for reproducible behavior.
77
+
78
+ ## Environment variables
79
+
80
+ | Variable | Purpose | Notes |
81
+ | --- | --- | --- |
82
+ | `ADAPTORCH_CONTROL_PLANE_TOKEN` | Upstream AdaptOrch token. | Required unless `--api-token` is passed. |
83
+ | `ADAPTORCH_CONTROL_PLANE_BASE_URL` | Base URL used when `--base-url` is omitted. | Trimmed and validated as HTTP(S); do not embed credentials. |
84
+ | `ADAPTORCH_MCP_HTTP_AUTH_TOKEN` | Client-facing bearer token for HTTP/SSE MCP. | Keep separate from the upstream token. |
85
+ | `ADAPTORCH_MCP_ALLOWED_ORIGINS` | Comma-separated HTTP origin allowlist. | Use with browser or remote HTTP clients. |
86
+ | `ADAPTORCH_MCP_MAX_PAYLOAD_SIZE_BYTES` | Maximum accepted HTTP request body size. | Keep bounded for public deployments. |
87
+ | `ADAPTORCH_MCP_REQUEST_TIMEOUT_SECONDS` | HTTP request timeout budget. | Applies to HTTP server request handling. |
88
+ | `ADAPTORCH_MCP_MAX_SSE_SUBSCRIBERS` | Maximum concurrent SSE subscribers. | Defaults are provided by `adaptorch.mcp_server`. |
89
+ | `ADAPTORCH_MCP_TIMEOUT_SECONDS` | Control-plane client timeout for app-factory usage. | Useful when embedding the ASGI app. |
90
+ | `ADAPTORCH_MCP_HTTP_HOST` / `ADAPTORCH_MCP_HTTP_PORT` | Shell/template values for `--http-host` and `--http-port`. | CLI flags are authoritative. |
91
+ | `ADAPTORCH_REPRODUCIBLE` | Benchmark/eval reproducibility beta. | Benchmark/eval scope only; not general runtime determinism. |
92
+ | `ADAPTORCH_ROUTER_ACCURACY_GATE` | Online-router learned-model gate. | `point` default or `wilson`; advanced/operator use. |
93
+ | `ADAPTORCH_PAPER_SEMANTIC_WEIGHT` | Paper-mode lexical/semantic blend. | Default `0.35`; nonzero values use Python scoring over the native fast path. |
94
+
95
+ ## Engine-delegated optional controls
96
+
97
+ The wrapper forwards these controls to the installed `adaptorch` engine; it does
98
+ not implement routing, synthesis, or benchmark algorithms itself. See the root
99
+ configuration guide for non-env controls such as `manifest_canonical_sha256`,
100
+ `pass_rate_credit`, `quality_signal`, `prefer_multi_model_ensemble_singleton`,
101
+ and MCP `prefer_ensemble_singleton`.
102
+
103
+ ## Tool surface
104
+
105
+ | Tool | Purpose |
106
+ | --- | --- |
107
+ | `adaptorch_run` | Submit an AdaptOrch task payload and optionally wait. |
108
+ | `adaptorch_get_run` | Read run summary by `run_id`. |
109
+ | `adaptorch_get_artifacts` | Read artifact metadata for a run. |
110
+ | `adaptorch_list_runs` | List recent runs. |
111
+ | `adaptorch_get_traces` | Read execution traces. |
112
+ | `adaptorch_cancel_run` | Request run cancellation (write/destructive; keep manually approved). |
113
+ | `adaptorch_route_topology` | Locally route a DAG through AdaptOrch's topology router. |
114
+ | `adaptorch_server_metrics` | Read redacted MCP server metrics. |
115
+ | `adaptorch_capabilities` | Read synthesis modes, connectors, and server features. |
116
+ | `adaptorch_plan_catalog` | Read hosted plan catalog: Starter `$0`, Pro `$39`, Team `$149`. |
117
+
118
+ ## Diagnostics and smoke tests
119
+
120
+ ```bash
121
+ adaptorch-mcp-doctor
122
+ adaptorch-mcp-doctor --json
123
+ adaptorch-mcp-doctor --strict
124
+ ```
125
+
126
+ The doctor command reports package availability, expected MCP tools, redacted environment metadata, and `controlPlane` base-url resolution details without printing token values.
127
+
128
+ ```bash
129
+ export ADAPTORCH_CONTROL_PLANE_TOKEN="<your-token>"
130
+ adaptorch-mcp-smoke --base-url https://adaptorch.com
131
+ ```
132
+
133
+ Expected JSON includes `"ok": true`, `adaptorch_plan_catalog`, and the expected core tool subset. If no base URL is supplied, smoke targets `http://127.0.0.1:8000` for local development. Add repeatable `--expected-tool <name>` flags when validating a specific hosted/core release.
134
+
135
+ ## Example configs
136
+
137
+ - `../../examples/claude_desktop_config.json`
138
+ - `../../examples/omk.mcp.json`
139
+ - `../../examples/mcp-http.env.example`
140
+
141
+ Checked-in examples use placeholders or environment interpolation. Fill real URLs and tokens only in local, uncommitted config files. For shared or production clients, avoid auto-approving run, artifact, and trace readers unless those payloads are already sanitized.
142
+
143
+ ## HTTP app factory
144
+
145
+ `create_default_mcp_http_app()` embeds the canonical AdaptOrch MCP HTTP ASGI app. It requires an upstream control-plane token in the environment.
146
+
147
+ ```bash
148
+ export ADAPTORCH_CONTROL_PLANE_TOKEN="<upstream-adaptorch-token>"
149
+ export ADAPTORCH_CONTROL_PLANE_BASE_URL="https://adaptorch.com"
150
+ export ADAPTORCH_MCP_HTTP_AUTH_TOKEN="<client-facing-mcp-token>"
151
+ ```
152
+
153
+ ```python
154
+ from adaptorch_mcp import create_default_mcp_http_app
155
+
156
+ app = create_default_mcp_http_app()
157
+ ```
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "adaptorch-mcp"
7
+ version = "0.3.0"
8
+ description = "Installable MCP bridge for AdaptOrch"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = { text = "Proprietary — Copyright EGG. All rights reserved." }
12
+ authors = [{ name = "AdaptOrch maintainers" }]
13
+ keywords = ["mcp", "model-context-protocol", "adaptorch", "agent-orchestration"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3 :: Only",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Topic :: Software Development :: Libraries :: Python Modules",
22
+ "Typing :: Typed",
23
+ ]
24
+ dependencies = [
25
+ "adaptorch[api]>=0.1.0",
26
+ ]
27
+
28
+ [project.optional-dependencies]
29
+ dev = [
30
+ "build>=1.2",
31
+ "mypy>=1.10",
32
+ "pytest>=8.2",
33
+ "ruff>=0.6",
34
+ ]
35
+
36
+ [project.urls]
37
+ Homepage = "https://github.com/dmae97/adaptorch_mcp"
38
+ Repository = "https://github.com/dmae97/adaptorch_mcp"
39
+ Issues = "https://github.com/dmae97/adaptorch_mcp/issues"
40
+ Documentation = "https://github.com/dmae97/adaptorch_mcp#readme"
41
+
42
+ [project.scripts]
43
+ adaptorch-mcp = "adaptorch_mcp.cli:main"
44
+ adaptorch-mcp-doctor = "adaptorch_mcp.doctor:main"
45
+ adaptorch-mcp-smoke = "adaptorch_mcp.stdio_smoke:main"
46
+
47
+ [tool.setuptools.packages.find]
48
+ where = ["src"]
49
+
50
+ [tool.setuptools.package-data]
51
+ adaptorch_mcp = ["py.typed"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ from adaptorch_mcp.cli import main
4
+ from adaptorch_mcp.diagnostics import collect_diagnostics
5
+ from adaptorch_mcp.server import create_default_mcp_http_app
6
+
7
+ __all__ = ["__version__", "collect_diagnostics", "create_default_mcp_http_app", "main"]
8
+
9
+ __version__ = "0.3.0"
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from adaptorch_mcp.cli import main
4
+
5
+ raise SystemExit(main())
@@ -0,0 +1,104 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import sys
5
+ from collections.abc import Sequence
6
+ from urllib.parse import urlparse
7
+
8
+ _CONTROL_PLANE_BASE_URL_ENV = "ADAPTORCH_CONTROL_PLANE_BASE_URL"
9
+ _HOSTED_BASE_URL = "https://adaptorch.com"
10
+ _ALLOWED_CONTROL_PLANE_SCHEMES = frozenset({"http", "https"})
11
+
12
+ _MISSING_ADAPTORCH_MESSAGE = (
13
+ "adaptorch-mcp requires AdaptOrch. Install with: "
14
+ "pip install 'adaptorch[api] @ git+https://github.com/dmae97/adaptorch.git'"
15
+ )
16
+
17
+
18
+ def _validate_control_plane_base_url(value: str, *, source: str) -> str:
19
+ """Return a stripped http(s) URL or raise for invalid control-plane input."""
20
+ stripped = value.strip()
21
+ parsed = urlparse(stripped)
22
+ if parsed.scheme.lower() not in _ALLOWED_CONTROL_PLANE_SCHEMES or not parsed.netloc:
23
+ raise ValueError(f"{source} must be an http(s) URL with a host")
24
+ if "@" in parsed.netloc:
25
+ raise ValueError(f"{source} must not include embedded credentials")
26
+ return stripped
27
+
28
+
29
+ def _normalize_env_base_url(value: str | None) -> str | None:
30
+ """Normalize the optional base-url environment variable.
31
+
32
+ Empty or whitespace-only values are treated as unset. Non-empty values must
33
+ be syntactically valid HTTP(S) URLs so misconfiguration fails before the
34
+ wrapper submits work to an unexpected control plane.
35
+ """
36
+ if value is None:
37
+ return None
38
+ stripped = value.strip()
39
+ if not stripped:
40
+ return None
41
+ return _validate_control_plane_base_url(stripped, source=_CONTROL_PLANE_BASE_URL_ENV)
42
+
43
+
44
+ def _strip_empty_base_url_equals(argv: Sequence[str]) -> list[str]:
45
+ """Drop empty equals-form base-url tokens so env/hosted defaults can apply."""
46
+ return [arg for arg in argv if arg != "--base-url="]
47
+
48
+
49
+ def _explicit_base_url_value(argv: Sequence[str]) -> str | None:
50
+ """Return the first non-empty explicit base-url value from argv, if present."""
51
+ for index, arg in enumerate(argv):
52
+ if arg == "--base-url" and index + 1 < len(argv):
53
+ return argv[index + 1]
54
+ if arg.startswith("--base-url=") and arg != "--base-url=":
55
+ return arg.split("=", 1)[1]
56
+ return None
57
+
58
+
59
+ def _has_base_url_flag(argv: Sequence[str]) -> bool:
60
+ """Return whether argv already carries a non-empty explicit base-url flag."""
61
+ return _explicit_base_url_value(argv) is not None
62
+
63
+
64
+ def _with_hosted_base_url_default(argv: Sequence[str] | None) -> list[str] | None:
65
+ """Resolve the public wrapper's AdaptOrch control-plane base URL.
66
+
67
+ Precedence is deterministic:
68
+ 1. Explicit ``--base-url`` or ``--base-url=...`` in argv.
69
+ 2. ``ADAPTORCH_CONTROL_PLANE_BASE_URL`` when no explicit flag is present.
70
+ 3. Hosted fallback for user-facing installs.
71
+
72
+ The canonical ``adaptorch.mcp_server`` keeps a localhost default for
73
+ core/local development. The public ``adaptorch-mcp`` package is user-facing,
74
+ so omitting both CLI and env configuration should still make runs visible in
75
+ the hosted dashboard.
76
+ """
77
+ raw_forwarded = list(argv) if argv is not None else sys.argv[1:]
78
+ forwarded = _strip_empty_base_url_equals(raw_forwarded)
79
+ explicit_base_url = _explicit_base_url_value(forwarded)
80
+ if explicit_base_url is not None:
81
+ _validate_control_plane_base_url(explicit_base_url, source="--base-url")
82
+ if argv is None and forwarded == raw_forwarded:
83
+ return None
84
+ return forwarded
85
+
86
+ env_base_url = _normalize_env_base_url(os.getenv(_CONTROL_PLANE_BASE_URL_ENV))
87
+ if env_base_url is not None:
88
+ return ["--base-url", env_base_url, *forwarded]
89
+
90
+ return ["--base-url", _HOSTED_BASE_URL, *forwarded]
91
+
92
+
93
+ def main(argv: Sequence[str] | None = None) -> int:
94
+ """Delegate the public console script to the canonical AdaptOrch MCP server."""
95
+ try:
96
+ from adaptorch.mcp_server import main as adaptorch_mcp_main
97
+ except ModuleNotFoundError as exc:
98
+ if exc.name == "adaptorch":
99
+ print(_MISSING_ADAPTORCH_MESSAGE, file=sys.stderr)
100
+ return 2
101
+ raise
102
+
103
+ forwarded_argv = _with_hosted_base_url_default(argv)
104
+ return int(adaptorch_mcp_main(forwarded_argv))