easydeploy-ai-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.
- easydeploy_ai_mcp-0.1.0/LICENSE +21 -0
- easydeploy_ai_mcp-0.1.0/PKG-INFO +288 -0
- easydeploy_ai_mcp-0.1.0/README.md +252 -0
- easydeploy_ai_mcp-0.1.0/pyproject.toml +64 -0
- easydeploy_ai_mcp-0.1.0/setup.cfg +4 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp/__init__.py +7 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp/__main__.py +6 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp/api_client.py +830 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp/auth.py +127 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp/cli.py +33 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp/credentials.py +81 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp/defaults.py +5 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp/http_main.py +531 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp/oauth_as_metadata.py +99 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp/server.py +978 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp.egg-info/PKG-INFO +288 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp.egg-info/SOURCES.txt +25 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp.egg-info/dependency_links.txt +1 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp.egg-info/entry_points.txt +3 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp.egg-info/requires.txt +13 -0
- easydeploy_ai_mcp-0.1.0/src/easydeploy_ai_mcp.egg-info/top_level.txt +1 -0
- easydeploy_ai_mcp-0.1.0/tests/test_auth.py +521 -0
- easydeploy_ai_mcp-0.1.0/tests/test_cognito_jwt_integration.py +112 -0
- easydeploy_ai_mcp-0.1.0/tests/test_credentials.py +41 -0
- easydeploy_ai_mcp-0.1.0/tests/test_http_main.py +47 -0
- easydeploy_ai_mcp-0.1.0/tests/test_oauth_as_metadata.py +47 -0
- easydeploy_ai_mcp-0.1.0/tests/test_server_tools.py +509 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 EasyDeploy AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: easydeploy-ai-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: EasyDeploy AI MCP server — REST API tools for Claude and other MCP clients
|
|
5
|
+
Author: EasyDeploy AI
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://easydeploy.ai
|
|
8
|
+
Project-URL: Documentation, https://github.com/easydeploy-ai/easydeploy-ai-mcp#readme
|
|
9
|
+
Project-URL: Repository, https://github.com/easydeploy-ai/easydeploy-ai-mcp
|
|
10
|
+
Project-URL: Issues, https://github.com/easydeploy-ai/easydeploy-ai-mcp/issues
|
|
11
|
+
Keywords: mcp,easydeploy,llm,claude,automl
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: fastmcp<4,>=3.1.1
|
|
25
|
+
Requires-Dist: httpx<1,>=0.27
|
|
26
|
+
Requires-Dist: python-dotenv>=1.1.0
|
|
27
|
+
Requires-Dist: uvicorn[standard]<1,>=0.30
|
|
28
|
+
Provides-Extra: oauth
|
|
29
|
+
Requires-Dist: pyjwt[crypto]<3,>=2.8; extra == "oauth"
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest<10,>=8.2; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pyjwt[crypto]<3,>=2.8; extra == "dev"
|
|
34
|
+
Requires-Dist: certifi>=2024.0.0; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# EasyDeploy AI MCP (`easydeploy-ai-mcp`)
|
|
38
|
+
|
|
39
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that exposes the **[EasyDeploy](https://easydeploy.ai)** public REST API as tools for Claude, Cursor, Claude Code, and other MCP clients.
|
|
40
|
+
|
|
41
|
+
**PyPI package name:** `easydeploy-ai-mcp` · **Import package:** `easydeploy_ai_mcp`
|
|
42
|
+
|
|
43
|
+
## Contents
|
|
44
|
+
|
|
45
|
+
- [Connect with Claude](#connect-with-claude)
|
|
46
|
+
- [What you get](#what-you-get)
|
|
47
|
+
- [Requirements](#requirements)
|
|
48
|
+
- [Install](#install)
|
|
49
|
+
- [Environment variables](#environment-variables)
|
|
50
|
+
- [Local MCP (stdio)](#local-mcp-stdio)
|
|
51
|
+
- [Remote MCP (HTTP)](#remote-mcp-http)
|
|
52
|
+
- [Documentation](#documentation)
|
|
53
|
+
- [REST API reference](#rest-api-reference)
|
|
54
|
+
- [Releases and API compatibility](#releases-and-api-compatibility)
|
|
55
|
+
- [Development](#development)
|
|
56
|
+
- [Security](#security)
|
|
57
|
+
- [License](#license)
|
|
58
|
+
|
|
59
|
+
## Connect with Claude
|
|
60
|
+
|
|
61
|
+
### Option A — Hosted connector (zero setup)
|
|
62
|
+
|
|
63
|
+
The fastest way to use EasyDeploy AI tools in Claude. No installation required.
|
|
64
|
+
|
|
65
|
+
1. Open **Claude** (web at [claude.ai](https://claude.ai) or Claude Desktop).
|
|
66
|
+
2. Go to **Settings → Connectors → Add custom connector**.
|
|
67
|
+
3. Fill in the form:
|
|
68
|
+
- **Name:** `EasyDeploy AI`
|
|
69
|
+
- **URL:** `https://mcp.easydeploy.ai/mcp`
|
|
70
|
+
4. Complete the OAuth sign-in flow when prompted. Claude will redirect you to EasyDeploy to authenticate with your account.
|
|
71
|
+
5. Save the connector. EasyDeploy tools will appear in your Claude sessions.
|
|
72
|
+
|
|
73
|
+
> **Note:** The hosted connector uses OAuth — you sign in with your EasyDeploy account; no API key needs to be pasted into Claude.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### Option B — Self-hosted (local stdio)
|
|
78
|
+
|
|
79
|
+
Run the MCP server on your own machine using your EasyDeploy API key. Nothing is exposed to the internet.
|
|
80
|
+
|
|
81
|
+
**1. Install**
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install easydeploy-ai-mcp
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**2. Add to Claude Desktop config**
|
|
88
|
+
|
|
89
|
+
Edit (or create) the Claude Desktop config file:
|
|
90
|
+
|
|
91
|
+
| OS | Path |
|
|
92
|
+
| ------- | ---- |
|
|
93
|
+
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
94
|
+
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
|
|
95
|
+
|
|
96
|
+
Merge the following into the root of that JSON (keep any existing keys):
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"mcpServers": {
|
|
101
|
+
"EasyDeploy AI": {
|
|
102
|
+
"command": "easydeploy-ai-mcp-stdio",
|
|
103
|
+
"env": {
|
|
104
|
+
"EDA_API_KEY": "eda_live_YOUR_KEY"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Replace `eda_live_YOUR_KEY` with your key from **Account → API Keys** in the EasyDeploy dashboard. Use the full path to `easydeploy-ai-mcp-stdio` (run `which easydeploy-ai-mcp-stdio` to find it) if Claude cannot locate it on your `PATH`.
|
|
112
|
+
|
|
113
|
+
**3. Restart Claude Desktop**
|
|
114
|
+
|
|
115
|
+
Fully quit and reopen the app. **EasyDeploy AI** will appear in your MCP servers.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
For self-hosting on Docker or a cloud provider, see [Remote MCP (HTTP)](#remote-mcp-http).
|
|
120
|
+
|
|
121
|
+
## What you get
|
|
122
|
+
|
|
123
|
+
- **24 tools** covering projects, datasets (including upload flow), model versions, training jobs, predictions, and account status.
|
|
124
|
+
- **stdio** transport for local clients, or **HTTP** with Streamable MCP on `/mcp` and **GET /healthz** for load balancers.
|
|
125
|
+
- **Hardening:** HTTPS-only calls to the EasyDeploy API; optional `MCP_SERVICE_TOKEN` for the HTTP MCP surface; response fields trimmed where appropriate for agents.
|
|
126
|
+
|
|
127
|
+
For **production** and **SOC 2–sensitive** setups, prefer self-hosting so your data stays within your own infrastructure. The hosted connector at `https://mcp.easydeploy.ai/mcp` is fine for most users.
|
|
128
|
+
|
|
129
|
+
## Requirements
|
|
130
|
+
|
|
131
|
+
- Python **3.10+**
|
|
132
|
+
- An EasyDeploy **API key** from the dashboard (**Account → API Keys**). The client uses the production EasyDeploy API host by default.
|
|
133
|
+
|
|
134
|
+
## Install
|
|
135
|
+
|
|
136
|
+
### From PyPI (after first release)
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
pip install easydeploy-ai-mcp
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### From source
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
git clone https://github.com/easydeploy-ai/easydeploy-ai-mcp.git
|
|
146
|
+
cd easydeploy-ai-mcp
|
|
147
|
+
pip install -e ".[dev]" # includes pytest
|
|
148
|
+
# or minimal runtime only:
|
|
149
|
+
pip install .
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Environment variables
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
| Variable | Required | Description |
|
|
156
|
+
| ---------------------------------- | -------- | ----------------------------------------------------------------------------------------------- |
|
|
157
|
+
| `EDA_API_KEY` | stdio / legacy HTTP | Required for **stdio** and **legacy** HTTP (no OAuth). **Not** used for outbound API calls when `EDA_OAUTH_ENABLED=1` — each MCP request must include `Authorization: Bearer <JWT or eda_live_…>`. |
|
|
158
|
+
| `EDA_API_BASE` | No | Overrides the default production API (`https://api.easydeploy.ai`). Set only when targeting a non-production endpoint. Trailing `/v1` is optional. |
|
|
159
|
+
| `EDA_UI_BASE_URL` | No | Prefix for `ui_url` fields (default `https://easydeploy.ai`). |
|
|
160
|
+
| `MCP_SERVICE_TOKEN` | No | Legacy single-tenant gate. If set, HTTP mode requires `Authorization: Bearer <token>` for `/mcp` (not for `GET /healthz`). Mutually exclusive with `EDA_OAUTH_ENABLED`. |
|
|
161
|
+
| `EDA_OAUTH_ENABLED` | No | Set to `1` to run the HTTP transport as an OAuth 2.0 resource server. Requires `EDA_COGNITO_USER_POOL_ID` and `EDA_COGNITO_CLIENT_ID`. See [Remote MCP (HTTP)](#remote-mcp-http). |
|
|
162
|
+
| `EDA_COGNITO_USER_POOL_ID` | OAuth | Cognito user pool that issues access tokens for the EasyDeploy API. |
|
|
163
|
+
| `EDA_COGNITO_CLIENT_ID` | OAuth | App client ID expected in the access token's `client_id` claim. |
|
|
164
|
+
| `EDA_COGNITO_REGION` | No | AWS region for the user pool (default `us-east-1`). |
|
|
165
|
+
| `EDA_REPORT_MAX_WAIT_SECONDS` | No | `get_model_report` poll budget (default `300`). |
|
|
166
|
+
| `EDA_REPORT_POLL_INTERVAL_SECONDS` | No | Poll interval in seconds (default `10`). |
|
|
167
|
+
| `HOST` / `PORT` | No | HTTP bind (defaults `0.0.0.0` / `8080`). |
|
|
168
|
+
| `EDA_TRUST_FORWARDED_HEADERS` | No | Set to `1` behind ALB/reverse proxy so RFC 9728 `resource` uses `https` (trusts `X-Forwarded-Proto`). |
|
|
169
|
+
| `EDA_MCP_OAUTH_ISSUER` | No | Public MCP base URL (no path) for `authorization_servers` and proxy `/.well-known/oauth-authorization-server` **`issuer`**. Default: request origin. Use if `Host` / `X-Forwarded-Proto` are wrong behind a proxy. |
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
## Local MCP (stdio)
|
|
173
|
+
|
|
174
|
+
Use when the client **starts** the server as a subprocess (Claude Desktop, Cursor, etc.).
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
export EDA_API_KEY="eda_live_..."
|
|
178
|
+
easydeploy-ai-mcp-stdio
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Or: `python -m easydeploy_ai_mcp`
|
|
182
|
+
|
|
183
|
+
Example config snippet:
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"mcpServers": {
|
|
188
|
+
"easydeploy-ai": {
|
|
189
|
+
"command": "easydeploy-ai-mcp-stdio",
|
|
190
|
+
"env": {
|
|
191
|
+
"EDA_API_KEY": "eda_live_..."
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Remote MCP (HTTP)
|
|
199
|
+
|
|
200
|
+
Serves **Streamable HTTP** via FastMCP on **`/mcp`** (confirm with your pinned **FastMCP 3.x** version). Health checks: **GET /healthz**.
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
export EDA_API_KEY="eda_live_..."
|
|
204
|
+
easydeploy-ai-mcp-http
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Or: `uvicorn easydeploy_ai_mcp.http_main:app --host 0.0.0.0 --port 8080`
|
|
208
|
+
|
|
209
|
+
If you embed `mcp.http_app()` in another ASGI app, pass through **`lifespan`** from the FastMCP HTTP app ([FastMCP ASGI](https://gofastmcp.com/deployment/asgi)); `easydeploy_ai_mcp.http_main` already does this for uvicorn.
|
|
210
|
+
|
|
211
|
+
### Auth modes
|
|
212
|
+
|
|
213
|
+
Pick exactly one (setting both `EDA_OAUTH_ENABLED` and `MCP_SERVICE_TOKEN` raises at import):
|
|
214
|
+
|
|
215
|
+
- **OAuth 2.0 resource server** (multi-tenant): set `EDA_OAUTH_ENABLED=1` plus
|
|
216
|
+
`EDA_COGNITO_USER_POOL_ID` and `EDA_COGNITO_CLIENT_ID`. Install the optional
|
|
217
|
+
extra: `pip install easydeploy-ai-mcp[oauth]`. The server validates incoming
|
|
218
|
+
Cognito **access** JWTs locally against the Cognito JWKS (issuer, signature,
|
|
219
|
+
`exp`, `token_use=='access'`, `client_id`) and forwards the token to the
|
|
220
|
+
EasyDeploy API. EasyDeploy API keys (prefix `eda_live_`) are accepted in the
|
|
221
|
+
same `Authorization: Bearer` header and forwarded as-is — the API is the
|
|
222
|
+
source of truth for revocation. RFC 9728 metadata is published at
|
|
223
|
+
`/.well-known/oauth-protected-resource`; RFC 8414 proxy metadata includes
|
|
224
|
+
**`registration_endpoint`**, and **`POST /oauth/register`** returns the static
|
|
225
|
+
Cognito MCP **`EDA_COGNITO_CLIENT_ID`** (RFC 7591-style, public client). 401
|
|
226
|
+
responses include `WWW-Authenticate: Bearer …` so MCP clients can discover the
|
|
227
|
+
auth server.
|
|
228
|
+
Note: Cognito access tokens carry `client_id`, **not** `aud`; do not configure
|
|
229
|
+
an audience.
|
|
230
|
+
- **Shared-secret gate** (legacy single-tenant): set `MCP_SERVICE_TOKEN`. All
|
|
231
|
+
outbound API calls use the static `EDA_API_KEY`.
|
|
232
|
+
- **No auth**: development only.
|
|
233
|
+
|
|
234
|
+
**Docker — run locally** (same image you deploy to ECS/Fargate; includes `easydeploy-ai-mcp[oauth]`):
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# Convenience: build + run (reads .env in the repo root if present)
|
|
238
|
+
./scripts/run_mcp_docker_local.sh
|
|
239
|
+
|
|
240
|
+
# Explicit env vars (no .env)
|
|
241
|
+
./scripts/run_mcp_docker_local.sh -e EDA_API_KEY="eda_live_..."
|
|
242
|
+
|
|
243
|
+
# Different host port
|
|
244
|
+
PORT=9000 ./scripts/run_mcp_docker_local.sh
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Host on AWS (Fargate + ALB):** build and push this repo’s **Dockerfile** to a container registry, then deploy behind an HTTPS load balancer. Set the env vars listed above on the task/container.
|
|
248
|
+
|
|
249
|
+
Manual equivalent:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
docker build -t easydeploy-ai-mcp .
|
|
253
|
+
docker run --rm -p 8080:8080 \
|
|
254
|
+
-e EDA_API_KEY="eda_live_..." \
|
|
255
|
+
easydeploy-ai-mcp
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Documentation
|
|
259
|
+
|
|
260
|
+
- **[docs/claude-getting-started.md](docs/claude-getting-started.md)** — EasyDeploy + Claude: Connectors or local Desktop config JSON
|
|
261
|
+
- **[docs/claude.md](docs/claude.md)** — Claude Connectors vs Claude Code, transports, headers
|
|
262
|
+
|
|
263
|
+
## REST API reference
|
|
264
|
+
|
|
265
|
+
This MCP server is a thin client over the **EasyDeploy public REST API**. Endpoint behavior, request bodies, and response shapes are defined by **EasyDeploy** (dashboard, product help, and official API materials at [easydeploy.ai](https://easydeploy.ai)). This repo does not duplicate the full OpenAPI spec; it maps those operations to MCP tools.
|
|
266
|
+
|
|
267
|
+
## Releases and API compatibility
|
|
268
|
+
|
|
269
|
+
**This repository** is the open-source home of the EasyDeploy MCP server. New releases track the **EasyDeploy public REST API** as documented for customers (dashboard and official API materials). If the API adds or changes endpoints, expect corresponding updates here. Contributors should follow [CONTRIBUTING.md](CONTRIBUTING.md) when changing tools or client behavior.
|
|
270
|
+
|
|
271
|
+
## Development
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
pip install -e ".[dev]"
|
|
275
|
+
pytest
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Optional — real Cognito JWT against the HTTP app** (live JWKS, no mocks): set `EDA_INTEGRATION_COGNITO_ACCESS_TOKEN` plus the same `EDA_COGNITO_*` vars you use for OAuth mode, then run `pytest tests/test_cognito_jwt_integration.py -v`. See the docstring in that file.
|
|
279
|
+
|
|
280
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for pull requests and reporting issues.
|
|
281
|
+
|
|
282
|
+
## Security
|
|
283
|
+
|
|
284
|
+
See [SECURITY.md](SECURITY.md) for vulnerability reporting and deployment notes.
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
# EasyDeploy AI MCP (`easydeploy-ai-mcp`)
|
|
2
|
+
|
|
3
|
+
A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server that exposes the **[EasyDeploy](https://easydeploy.ai)** public REST API as tools for Claude, Cursor, Claude Code, and other MCP clients.
|
|
4
|
+
|
|
5
|
+
**PyPI package name:** `easydeploy-ai-mcp` · **Import package:** `easydeploy_ai_mcp`
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
- [Connect with Claude](#connect-with-claude)
|
|
10
|
+
- [What you get](#what-you-get)
|
|
11
|
+
- [Requirements](#requirements)
|
|
12
|
+
- [Install](#install)
|
|
13
|
+
- [Environment variables](#environment-variables)
|
|
14
|
+
- [Local MCP (stdio)](#local-mcp-stdio)
|
|
15
|
+
- [Remote MCP (HTTP)](#remote-mcp-http)
|
|
16
|
+
- [Documentation](#documentation)
|
|
17
|
+
- [REST API reference](#rest-api-reference)
|
|
18
|
+
- [Releases and API compatibility](#releases-and-api-compatibility)
|
|
19
|
+
- [Development](#development)
|
|
20
|
+
- [Security](#security)
|
|
21
|
+
- [License](#license)
|
|
22
|
+
|
|
23
|
+
## Connect with Claude
|
|
24
|
+
|
|
25
|
+
### Option A — Hosted connector (zero setup)
|
|
26
|
+
|
|
27
|
+
The fastest way to use EasyDeploy AI tools in Claude. No installation required.
|
|
28
|
+
|
|
29
|
+
1. Open **Claude** (web at [claude.ai](https://claude.ai) or Claude Desktop).
|
|
30
|
+
2. Go to **Settings → Connectors → Add custom connector**.
|
|
31
|
+
3. Fill in the form:
|
|
32
|
+
- **Name:** `EasyDeploy AI`
|
|
33
|
+
- **URL:** `https://mcp.easydeploy.ai/mcp`
|
|
34
|
+
4. Complete the OAuth sign-in flow when prompted. Claude will redirect you to EasyDeploy to authenticate with your account.
|
|
35
|
+
5. Save the connector. EasyDeploy tools will appear in your Claude sessions.
|
|
36
|
+
|
|
37
|
+
> **Note:** The hosted connector uses OAuth — you sign in with your EasyDeploy account; no API key needs to be pasted into Claude.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
### Option B — Self-hosted (local stdio)
|
|
42
|
+
|
|
43
|
+
Run the MCP server on your own machine using your EasyDeploy API key. Nothing is exposed to the internet.
|
|
44
|
+
|
|
45
|
+
**1. Install**
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install easydeploy-ai-mcp
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**2. Add to Claude Desktop config**
|
|
52
|
+
|
|
53
|
+
Edit (or create) the Claude Desktop config file:
|
|
54
|
+
|
|
55
|
+
| OS | Path |
|
|
56
|
+
| ------- | ---- |
|
|
57
|
+
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
58
|
+
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
|
|
59
|
+
|
|
60
|
+
Merge the following into the root of that JSON (keep any existing keys):
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"mcpServers": {
|
|
65
|
+
"EasyDeploy AI": {
|
|
66
|
+
"command": "easydeploy-ai-mcp-stdio",
|
|
67
|
+
"env": {
|
|
68
|
+
"EDA_API_KEY": "eda_live_YOUR_KEY"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Replace `eda_live_YOUR_KEY` with your key from **Account → API Keys** in the EasyDeploy dashboard. Use the full path to `easydeploy-ai-mcp-stdio` (run `which easydeploy-ai-mcp-stdio` to find it) if Claude cannot locate it on your `PATH`.
|
|
76
|
+
|
|
77
|
+
**3. Restart Claude Desktop**
|
|
78
|
+
|
|
79
|
+
Fully quit and reopen the app. **EasyDeploy AI** will appear in your MCP servers.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
For self-hosting on Docker or a cloud provider, see [Remote MCP (HTTP)](#remote-mcp-http).
|
|
84
|
+
|
|
85
|
+
## What you get
|
|
86
|
+
|
|
87
|
+
- **24 tools** covering projects, datasets (including upload flow), model versions, training jobs, predictions, and account status.
|
|
88
|
+
- **stdio** transport for local clients, or **HTTP** with Streamable MCP on `/mcp` and **GET /healthz** for load balancers.
|
|
89
|
+
- **Hardening:** HTTPS-only calls to the EasyDeploy API; optional `MCP_SERVICE_TOKEN` for the HTTP MCP surface; response fields trimmed where appropriate for agents.
|
|
90
|
+
|
|
91
|
+
For **production** and **SOC 2–sensitive** setups, prefer self-hosting so your data stays within your own infrastructure. The hosted connector at `https://mcp.easydeploy.ai/mcp` is fine for most users.
|
|
92
|
+
|
|
93
|
+
## Requirements
|
|
94
|
+
|
|
95
|
+
- Python **3.10+**
|
|
96
|
+
- An EasyDeploy **API key** from the dashboard (**Account → API Keys**). The client uses the production EasyDeploy API host by default.
|
|
97
|
+
|
|
98
|
+
## Install
|
|
99
|
+
|
|
100
|
+
### From PyPI (after first release)
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
pip install easydeploy-ai-mcp
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### From source
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
git clone https://github.com/easydeploy-ai/easydeploy-ai-mcp.git
|
|
110
|
+
cd easydeploy-ai-mcp
|
|
111
|
+
pip install -e ".[dev]" # includes pytest
|
|
112
|
+
# or minimal runtime only:
|
|
113
|
+
pip install .
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Environment variables
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
| Variable | Required | Description |
|
|
120
|
+
| ---------------------------------- | -------- | ----------------------------------------------------------------------------------------------- |
|
|
121
|
+
| `EDA_API_KEY` | stdio / legacy HTTP | Required for **stdio** and **legacy** HTTP (no OAuth). **Not** used for outbound API calls when `EDA_OAUTH_ENABLED=1` — each MCP request must include `Authorization: Bearer <JWT or eda_live_…>`. |
|
|
122
|
+
| `EDA_API_BASE` | No | Overrides the default production API (`https://api.easydeploy.ai`). Set only when targeting a non-production endpoint. Trailing `/v1` is optional. |
|
|
123
|
+
| `EDA_UI_BASE_URL` | No | Prefix for `ui_url` fields (default `https://easydeploy.ai`). |
|
|
124
|
+
| `MCP_SERVICE_TOKEN` | No | Legacy single-tenant gate. If set, HTTP mode requires `Authorization: Bearer <token>` for `/mcp` (not for `GET /healthz`). Mutually exclusive with `EDA_OAUTH_ENABLED`. |
|
|
125
|
+
| `EDA_OAUTH_ENABLED` | No | Set to `1` to run the HTTP transport as an OAuth 2.0 resource server. Requires `EDA_COGNITO_USER_POOL_ID` and `EDA_COGNITO_CLIENT_ID`. See [Remote MCP (HTTP)](#remote-mcp-http). |
|
|
126
|
+
| `EDA_COGNITO_USER_POOL_ID` | OAuth | Cognito user pool that issues access tokens for the EasyDeploy API. |
|
|
127
|
+
| `EDA_COGNITO_CLIENT_ID` | OAuth | App client ID expected in the access token's `client_id` claim. |
|
|
128
|
+
| `EDA_COGNITO_REGION` | No | AWS region for the user pool (default `us-east-1`). |
|
|
129
|
+
| `EDA_REPORT_MAX_WAIT_SECONDS` | No | `get_model_report` poll budget (default `300`). |
|
|
130
|
+
| `EDA_REPORT_POLL_INTERVAL_SECONDS` | No | Poll interval in seconds (default `10`). |
|
|
131
|
+
| `HOST` / `PORT` | No | HTTP bind (defaults `0.0.0.0` / `8080`). |
|
|
132
|
+
| `EDA_TRUST_FORWARDED_HEADERS` | No | Set to `1` behind ALB/reverse proxy so RFC 9728 `resource` uses `https` (trusts `X-Forwarded-Proto`). |
|
|
133
|
+
| `EDA_MCP_OAUTH_ISSUER` | No | Public MCP base URL (no path) for `authorization_servers` and proxy `/.well-known/oauth-authorization-server` **`issuer`**. Default: request origin. Use if `Host` / `X-Forwarded-Proto` are wrong behind a proxy. |
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
## Local MCP (stdio)
|
|
137
|
+
|
|
138
|
+
Use when the client **starts** the server as a subprocess (Claude Desktop, Cursor, etc.).
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
export EDA_API_KEY="eda_live_..."
|
|
142
|
+
easydeploy-ai-mcp-stdio
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Or: `python -m easydeploy_ai_mcp`
|
|
146
|
+
|
|
147
|
+
Example config snippet:
|
|
148
|
+
|
|
149
|
+
```json
|
|
150
|
+
{
|
|
151
|
+
"mcpServers": {
|
|
152
|
+
"easydeploy-ai": {
|
|
153
|
+
"command": "easydeploy-ai-mcp-stdio",
|
|
154
|
+
"env": {
|
|
155
|
+
"EDA_API_KEY": "eda_live_..."
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Remote MCP (HTTP)
|
|
163
|
+
|
|
164
|
+
Serves **Streamable HTTP** via FastMCP on **`/mcp`** (confirm with your pinned **FastMCP 3.x** version). Health checks: **GET /healthz**.
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
export EDA_API_KEY="eda_live_..."
|
|
168
|
+
easydeploy-ai-mcp-http
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Or: `uvicorn easydeploy_ai_mcp.http_main:app --host 0.0.0.0 --port 8080`
|
|
172
|
+
|
|
173
|
+
If you embed `mcp.http_app()` in another ASGI app, pass through **`lifespan`** from the FastMCP HTTP app ([FastMCP ASGI](https://gofastmcp.com/deployment/asgi)); `easydeploy_ai_mcp.http_main` already does this for uvicorn.
|
|
174
|
+
|
|
175
|
+
### Auth modes
|
|
176
|
+
|
|
177
|
+
Pick exactly one (setting both `EDA_OAUTH_ENABLED` and `MCP_SERVICE_TOKEN` raises at import):
|
|
178
|
+
|
|
179
|
+
- **OAuth 2.0 resource server** (multi-tenant): set `EDA_OAUTH_ENABLED=1` plus
|
|
180
|
+
`EDA_COGNITO_USER_POOL_ID` and `EDA_COGNITO_CLIENT_ID`. Install the optional
|
|
181
|
+
extra: `pip install easydeploy-ai-mcp[oauth]`. The server validates incoming
|
|
182
|
+
Cognito **access** JWTs locally against the Cognito JWKS (issuer, signature,
|
|
183
|
+
`exp`, `token_use=='access'`, `client_id`) and forwards the token to the
|
|
184
|
+
EasyDeploy API. EasyDeploy API keys (prefix `eda_live_`) are accepted in the
|
|
185
|
+
same `Authorization: Bearer` header and forwarded as-is — the API is the
|
|
186
|
+
source of truth for revocation. RFC 9728 metadata is published at
|
|
187
|
+
`/.well-known/oauth-protected-resource`; RFC 8414 proxy metadata includes
|
|
188
|
+
**`registration_endpoint`**, and **`POST /oauth/register`** returns the static
|
|
189
|
+
Cognito MCP **`EDA_COGNITO_CLIENT_ID`** (RFC 7591-style, public client). 401
|
|
190
|
+
responses include `WWW-Authenticate: Bearer …` so MCP clients can discover the
|
|
191
|
+
auth server.
|
|
192
|
+
Note: Cognito access tokens carry `client_id`, **not** `aud`; do not configure
|
|
193
|
+
an audience.
|
|
194
|
+
- **Shared-secret gate** (legacy single-tenant): set `MCP_SERVICE_TOKEN`. All
|
|
195
|
+
outbound API calls use the static `EDA_API_KEY`.
|
|
196
|
+
- **No auth**: development only.
|
|
197
|
+
|
|
198
|
+
**Docker — run locally** (same image you deploy to ECS/Fargate; includes `easydeploy-ai-mcp[oauth]`):
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# Convenience: build + run (reads .env in the repo root if present)
|
|
202
|
+
./scripts/run_mcp_docker_local.sh
|
|
203
|
+
|
|
204
|
+
# Explicit env vars (no .env)
|
|
205
|
+
./scripts/run_mcp_docker_local.sh -e EDA_API_KEY="eda_live_..."
|
|
206
|
+
|
|
207
|
+
# Different host port
|
|
208
|
+
PORT=9000 ./scripts/run_mcp_docker_local.sh
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Host on AWS (Fargate + ALB):** build and push this repo’s **Dockerfile** to a container registry, then deploy behind an HTTPS load balancer. Set the env vars listed above on the task/container.
|
|
212
|
+
|
|
213
|
+
Manual equivalent:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
docker build -t easydeploy-ai-mcp .
|
|
217
|
+
docker run --rm -p 8080:8080 \
|
|
218
|
+
-e EDA_API_KEY="eda_live_..." \
|
|
219
|
+
easydeploy-ai-mcp
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Documentation
|
|
223
|
+
|
|
224
|
+
- **[docs/claude-getting-started.md](docs/claude-getting-started.md)** — EasyDeploy + Claude: Connectors or local Desktop config JSON
|
|
225
|
+
- **[docs/claude.md](docs/claude.md)** — Claude Connectors vs Claude Code, transports, headers
|
|
226
|
+
|
|
227
|
+
## REST API reference
|
|
228
|
+
|
|
229
|
+
This MCP server is a thin client over the **EasyDeploy public REST API**. Endpoint behavior, request bodies, and response shapes are defined by **EasyDeploy** (dashboard, product help, and official API materials at [easydeploy.ai](https://easydeploy.ai)). This repo does not duplicate the full OpenAPI spec; it maps those operations to MCP tools.
|
|
230
|
+
|
|
231
|
+
## Releases and API compatibility
|
|
232
|
+
|
|
233
|
+
**This repository** is the open-source home of the EasyDeploy MCP server. New releases track the **EasyDeploy public REST API** as documented for customers (dashboard and official API materials). If the API adds or changes endpoints, expect corresponding updates here. Contributors should follow [CONTRIBUTING.md](CONTRIBUTING.md) when changing tools or client behavior.
|
|
234
|
+
|
|
235
|
+
## Development
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
pip install -e ".[dev]"
|
|
239
|
+
pytest
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Optional — real Cognito JWT against the HTTP app** (live JWKS, no mocks): set `EDA_INTEGRATION_COGNITO_ACCESS_TOKEN` plus the same `EDA_COGNITO_*` vars you use for OAuth mode, then run `pytest tests/test_cognito_jwt_integration.py -v`. See the docstring in that file.
|
|
243
|
+
|
|
244
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for pull requests and reporting issues.
|
|
245
|
+
|
|
246
|
+
## Security
|
|
247
|
+
|
|
248
|
+
See [SECURITY.md](SECURITY.md) for vulnerability reporting and deployment notes.
|
|
249
|
+
|
|
250
|
+
## License
|
|
251
|
+
|
|
252
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "easydeploy-ai-mcp"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "EasyDeploy AI MCP server — REST API tools for Claude and other MCP clients"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "EasyDeploy AI" }]
|
|
13
|
+
keywords = ["mcp", "easydeploy", "llm", "claude", "automl"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Programming Language :: Python :: 3.14",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
dependencies = [
|
|
27
|
+
"fastmcp>=3.1.1,<4",
|
|
28
|
+
"httpx>=0.27,<1",
|
|
29
|
+
"python-dotenv>=1.1.0",
|
|
30
|
+
"uvicorn[standard]>=0.30,<1",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
oauth = [
|
|
35
|
+
"pyjwt[crypto]>=2.8,<3",
|
|
36
|
+
]
|
|
37
|
+
dev = [
|
|
38
|
+
"pytest>=8.2,<10",
|
|
39
|
+
"pytest-asyncio>=0.24.0",
|
|
40
|
+
"pyjwt[crypto]>=2.8,<3",
|
|
41
|
+
"certifi>=2024.0.0",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
easydeploy-ai-mcp-stdio = "easydeploy_ai_mcp.cli:run_stdio"
|
|
46
|
+
easydeploy-ai-mcp-http = "easydeploy_ai_mcp.cli:run_http"
|
|
47
|
+
|
|
48
|
+
[project.urls]
|
|
49
|
+
Homepage = "https://easydeploy.ai"
|
|
50
|
+
Documentation = "https://github.com/easydeploy-ai/easydeploy-ai-mcp#readme"
|
|
51
|
+
Repository = "https://github.com/easydeploy-ai/easydeploy-ai-mcp"
|
|
52
|
+
Issues = "https://github.com/easydeploy-ai/easydeploy-ai-mcp/issues"
|
|
53
|
+
|
|
54
|
+
[tool.setuptools.packages.find]
|
|
55
|
+
where = ["src"]
|
|
56
|
+
|
|
57
|
+
[tool.pytest.ini_options]
|
|
58
|
+
asyncio_mode = "auto"
|
|
59
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
60
|
+
pythonpath = ["src"]
|
|
61
|
+
testpaths = ["tests"]
|
|
62
|
+
markers = [
|
|
63
|
+
"integration: optional tests that need a real Cognito access JWT and network (see test_cognito_jwt_integration.py)",
|
|
64
|
+
]
|