Skip to main content
Glama
EasyDeploy-AI

easydeploy-ai-mcp

Official

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
HOSTNoHTTP bind host.0.0.0.0
PORTNoHTTP bind port.8080
EDA_API_KEYNoRequired 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_…>.
EDA_API_BASENoOverrides the default production API. Set only when targeting a non-production endpoint. Trailing /v1 is optional.https://api.easydeploy.ai
EDA_UI_BASE_URLNoPrefix for ui_url fields.https://easydeploy.ai
EDA_OAUTH_ENABLEDNoSet 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.0
MCP_SERVICE_TOKENNoLegacy single-tenant gate. If set, HTTP mode requires Authorization: Bearer <token> for /mcp (not for GET /healthz). Mutually exclusive with EDA_OAUTH_ENABLED.
EDA_COGNITO_REGIONNoAWS region for the user pool.us-east-1
EDA_MCP_OAUTH_ISSUERNoPublic MCP base URL (no path) for authorization_servers and proxy .well-known/oauth-authorization-server issuer. Default: request origin.
EDA_COGNITO_CLIENT_IDNoApp client ID expected in the access token's client_id claim. Required if EDA_OAUTH_ENABLED=1.
EDA_COGNITO_USER_POOL_IDNoCognito user pool that issues access tokens for the EasyDeploy API. Required if EDA_OAUTH_ENABLED=1.
EDA_REPORT_MAX_WAIT_SECONDSNoget_model_report poll budget.300
EDA_TRUST_FORWARDED_HEADERSNoSet to 1 behind ALB/reverse proxy so RFC 9728 resource uses https.0
EDA_REPORT_POLL_INTERVAL_SECONDSNoPoll interval in seconds.10

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
logging
{}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
extensions
{
  "io.modelcontextprotocol/ui": {}
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
get_startedA

Return the EasyDeploy data-science playbook: how to prepare leakage-free training data, keep an honest test split, upload the files, train, validate on the holdout and predict with the model. Useful at the start of a modeling task.

section picks one part (overview, prepare, split, upload, train, validate, predict) or all; the default is overview. The result carries the playbook's guide_version, every section with a one-line summary, and the section that follows. The content ships with the server and changes between releases. Read-only; makes no API call.

get_account_statusA

Get current account status: tier, training credits, prediction usage, endpoint limits. customer_id is optional; the backend resolves the account from the API key.

list_projectsA

List all projects for this API key (id, name, description, timestamps). The ids are the project_id that the other project-scoped tools take.

get_projectC

Fetch a single project by id.

create_projectA

Create or update a project (create-or-update: not idempotent).

  • Create: call with name (and optional description). Each call without project_id creates another project.

  • Update/rename: pass project_id of an existing project plus the fields to change (name and/or description); this PATCHes it.

list_datasetsB

List datasets in a project (id, name, type, timestamps).

get_datasetA

Fetch one dataset by id (name, description, type, timestamps). Read-only.

Datasets are created via complete_upload (the upload flow). To rename a dataset or change its description, use update_dataset.

update_datasetA

Rename a dataset or change its description.

Pass at least one of name or description; fields left empty are not changed. Repeating the same call leaves the dataset in the same state. Returns the updated dataset record.

start_uploadA

Open an upload session for one file and return the ways to send its bytes.

One session carries one file. Train and test files (and an optional validation file) are separate uploads, each with its own start_upload. File bytes never travel through tool arguments or the conversation on any channel:

A. Host file parameter (preferred where available). Hosts that support openai/fileParams (Codex, ChatGPT) hydrate file from a sandbox path. EasyDeploy then fetches the bytes server-side and the session goes straight to RECEIVING, with no network needed from the sandbox. Poll get_upload_status until READY, then call complete_upload.

B. Gateway PUT (default). Called without file, this returns curl_command, the HTTP PUT that sends the file to EasyDeploy's upload gateway. It runs in the shell where the file is, with FILE_PATH replaced by the file's path. Max ~6 MB; it carries a single-use upload token, never the API key. If the sandbox blocks network egress, next_steps names the exact API host the user can allow.

C. Fetch from a share link. If the sandbox cannot reach the network but the file sits at a shareable URL, upload_from_url with the returned upload_request_id has EasyDeploy fetch it.

The returned next_steps is the ordered runbook with the ids filled in, including the web model-builder fallback for hosts with no byte channel at all. The model-builder URL for this environment comes from the API in the fallback string of this result (for example https://www.easydeploy.ai/model-builder).

dataset_id: omit it to create a new dataset when complete_upload runs. Pass an existing dataset's id to add a new version to that dataset instead; complete_upload's name is then ignored and the dataset keeps its current name. The output carries dataset_id only when you passed one.

upload_from_urlA

Hand EasyDeploy a URL to fetch an upload session's bytes from, server-side.

Use this when the sandbox has no network egress (the gateway curl failed with a connection error) but the training file already lives at a shareable URL, or when a host handed you a file download link.

Accepted sources:

  • Google Sheets and Google Drive share links set to anyone with the link (Sheets are exported as CSV).

  • OpenAI file links from a host file parameter.

  • Any other host on the EasyDeploy source allowlist.

EasyDeploy fetches the bytes itself, up to 256 MB. The file never passes through the model, the conversation, or this tool's arguments — pass a URL, never file contents. Private, loopback, and metadata addresses are rejected, as is any host off the allowlist; the error explains which rule refused the URL.

Returns the session in RECEIVING. A 409 means the session already received bytes or expired — call start_upload again for a fresh one. If no channel works at all, the fallback string in the start_upload result carries the web model-builder URL for this environment (for example https://www.easydeploy.ai/model-builder).

get_upload_statusA

Poll an upload session by the upload_request_id from start_upload.

status is one of URL_ISSUED, RECEIVING, UPLOADED, VALIDATING, READY, REJECTED, CONSUMED, EXPIRED. It reports on sessions opened by start_upload, and every channel that feeds one (gateway PUT, host file parameter, upload_from_url) reports through this one tool. Files uploaded through the web model builder are not visible here — the user registers those in the web app; find them with list_datasets.

complete_upload only accepts READY — poll here first. On REJECTED, the error field names the validation check that failed; fix the file and start a new upload rather than retrying this session.

Also returns sizeBytes and rowCount once known — confirm the row count matches the file you handed over before registering the dataset.

complete_uploadA

Register a validated upload as a dataset (the last step of every channel).

upload_request_id: opaque id returned by start_upload. dataset_id: omit it to create a new dataset named name. Pass an existing dataset's id (the one given to start_upload) to add a new version to that dataset; name is then still required but ignored, and the dataset keeps its current name. dataset_type: train | test | validation (default train). You produce these files by splitting the prepared data yourself: train is what the model learns from, test is the holdout you score afterwards with run_batch_prediction, and validation is an optional extra holdout. EasyDeploy stores the type as a label and never splits for you.

The upload session must be in status READY — not UPLOADED. READY means the validator has accepted and promoted the bytes. RECEIVING / UPLOADED / VALIDATING (still in flight), REJECTED (failed validation) and EXPIRED (needs a new start_upload) return 400 naming the current state and what to do. Call get_upload_status first and wait for READY instead of calling this tool on a guess.

Retrying is safe: if the session is already CONSUMED (an earlier call succeeded), the API returns the existing dataset version instead of an error. A 409 means another complete_upload for the same session is still in progress — wait a few seconds and call again.

A file the user uploaded through the web model builder is already a dataset — resolve it with list_datasets rather than calling this.

Returns dataset (id, name, ui_url) and datasetVersion once, at the top level, with its ui_url and columnNames as a list.

qa_status is informational and does not gate anything. version_type matters in one case: submit_training_job with an explicit dataset_version_id rejects a raw version. Omit dataset_version_id to train on the model version's own dataset.

list_dataset_versionsA

List all versions of a dataset (version number, version_type, qa_status, row counts).

project_id is optional — the backend resolves access from dataset_id when omitted. Column names, where present, come back as a columnNames list.

qa_status is informational and does not gate anything. version_type matters in one case: submit_training_job with an explicit dataset_version_id rejects a raw version. Omit dataset_version_id to train on the model version's own dataset.

get_dataset_versionA

Fetch one dataset version by id (row and column counts, columnNames list, qa_status, version_type).

qa_status is informational and does not gate anything. version_type matters in one case: submit_training_job with an explicit dataset_version_id rejects a raw version. Omit dataset_version_id to train on the model version's own dataset.

create_dataset_versionA

Create or update a dataset version.

Create (register an S3 file as a new version): Required: version_type (raw | qa_cleaned | training), file_url, qa_metadata (freeform JSON with QA results). file_url accepts either the file's s3:// URL (s3://{bucket}/users/{userId}/...) or its bare S3 key starting with users/{userId}/ — the s3Key field that complete_upload returns as datasetVersion.s3Key and get_dataset_version returns as s3Key. Any other form (an https URL, a key with another prefix) is refused before calling the API. The file must be under your own storage prefix users/{userId}/; the API rejects any other location with 400.

Update (change qa_status on an existing version): Required: version_id, qa_status (pending | in_progress | ready | blocked).

qa_status is informational and does not gate anything. version_type matters in one case: submit_training_job with an explicit dataset_version_id rejects a raw version. Omit dataset_version_id to train on the model version's own dataset.

create_modelA

Create or update a model (create-or-update: not idempotent).

  • Create: call with project_id and name (and optional description). Each call without model_id creates another model.

  • Update/rename: also pass model_id plus the fields to change; this PATCHes the existing model.

get_modelB

Fetch a single model by id (name, description, version count).

create_model_versionA

Create a model version tied to a dataset version and target column. Then call submit_training_job with the returned model version id.

Pass the train dataset's version, never the test one: a test file that reaches training is no longer a holdout. EasyDeploy does not check the type.

Set time_series_mode=true and time_column when forecasting ordered periods (e.g. weekly business metrics). Time-series mode uses forward-chaining cross-validation (TimeSeriesSplit) instead of shuffled k-fold: each fold trains on earlier periods and scores on later ones. get_model_report records the strategy a run used in metrics.crossValidation.strategy (time_series_split for forward-chaining).

list_modelsA

List all models in a project (id, name).

list_model_versionsB

List model versions. Training state is status (SUBMITTED → TRAINING → TRAINING_COMPLETED or TRAINING_FAILED). Report readiness is edaReportStatus (PENDING | GENERATING | READY | FAILED).

get_model_versionA

Fetch a single model version by id (status, edaReportStatus, target, timestamps). Prefer this over list_model_versions when you already know the version_id.

get_model_reportA

Load the EDA training report (metrics, feature analysis, performance summary).

project_id is optional — the backend resolves it from model_id when omitted.

Omit model_version_id to use the latest version for this model. Pass an id from list_model_versions to read a specific version.

Default response is summary only (token-efficient). Set full_report=true for full detail.

The report is generated after training finishes, so this tool waits for it: 45 s by default (the server's EDA_REPORT_MAX_WAIT_SECONDS, never more than 60 s), since some hosts end a tool call at 60 s. If it is still being generated then, the result has timed_out: true and next_steps: nothing failed, call get_model_report again to keep waiting.

How the model was validated. Model search scores candidates by cross-validation: 10-fold stratified shuffled CV on ROC-AUC for classifiers, 10-fold shuffled CV on negative MSE for regressors; a version created with time_series_mode uses forward-chaining CV (TimeSeriesSplit) instead. The winning pipeline is then refit on all rows. There is no separate test set. Accuracy, the confusion matrix, per-class precision/recall and in-sample ROC-AUC are training fit (computed on the same rows the model learned from), not a holdout estimate. The CV score is the report's out-of-sample estimate, but it is measured inside the training file; the holdout estimate comes from scoring your own test file with run_batch_prediction, not from this report. The prose summary is written by an LLM and may use looser wording than these numbers.

metrics (returned next to the report, passed through unchanged): {taskType, crossValidation: {metric, score, strategy, folds, strategySource ('recorded'|'platform_default'), note}, trainingFit: {note, accuracy?, rocAuc?, confusionMatrix?, perClass?, mse?, rmse?, mae?, r2?, explainedVariance?, mape?}, additionalCv?: {r2?, rmse?}, warnings: []}. metrics is null when it cannot be derived, with metricsUnavailableReason saying why. crossValidation.strategy names the CV used for that run (time_series_split for forward-chaining); read warnings before quoting any number.

submit_training_jobA

Submit a training job for a model version.

Each call starts a separate training job and spends one training credit; get_training_status follows a job already submitted, by its job_id.

Track completion: Poll list_model_versions for the model and watch the target version's status until it reaches TRAINING_COMPLETED or TRAINING_FAILED (same as the web UI). This is the most reliable approach across MCP hosts.

Or pass the returned jobId to get_training_status with wait=true to block until the job finishes. Run time depends on the plan and the data, from minutes to several hours.

dataset_version_id can be omitted when the model version was created with create_model_version in the same flow — the backend resolves target_feature, file, and dataset from the model version record automatically. Omit it to train on the model version's own dataset. Pass it only to override with a different qa_cleaned or training version: an explicit dataset_version_id whose version_type is raw (every upload starts as raw) is rejected with 400 INVALID_VERSION_TYPE.

Returns {jobId, modelVersionId, status}.

get_training_statusA

Check a training job by job_id (the jobId field from submit_training_job).

Response fields:

  • status: PENDING | RUNNING | COMPLETE | FAILED

  • trainingTimeSeconds: wall-clock seconds once the job stops; null while running

  • modelVersionId: the model version being trained

By default returns the current status immediately.

Set wait=true to block until the job reaches a terminal state (COMPLETE or FAILED). Polls every poll_interval_seconds (default 10 s) for up to timeout_seconds (45 s by default, at most 60 s; some hosts end a tool call at 60 s). Training can take from minutes to several hours depending on the plan and the data. If the timeout expires, the last polled status is returned with timed_out: true and next_steps: the job is still running, so call this tool again with the same job_id to keep waiting — do not resubmit the training job.

run_predictionA

Run a single ad-hoc prediction against a trained model version.

Each call is a new prediction and spends a prediction credit; get_prediction follows one still running, by its prediction_id.

project_id and target_feature are auto-resolved from the model version record when omitted. By default waits and returns the predicted label or value in output. For a classifier the result also has probabilities, one {"probability_<class>": p} object per entry of output, named like run_batch_prediction's CSV columns, and classLabels, the label each <class> stands for: {"0": "B", "1": "M"} for a text target, {"0": 0, "1": 1} for a 0/1 target. output follows the model's default rule, so a threshold you chose applies to the probability, not to output. Regressors return neither. Set wait_for_result=false to return immediately with prediction_id. A wait lasts max_wait_seconds (45 s by default, at most 60 s); if the prediction is still running then, the result has timed_out: true and next_steps: poll get_prediction to keep waiting.

run_batch_predictionA

Score an entire dataset against a trained model version.

Each call starts a new batch job and spends one prediction credit per row; get_prediction follows one already started, by its prediction_id.

project_id and target_feature are auto-resolved from the model version record when omitted. dataset_version_id identifies both the input file and the row count for credit billing (one prediction credit per row).

Holdout validation: score your test dataset version with its labels still in it. The CSV you download via get_prediction is that file in its original row order with every column kept (target and ids included), plus prediction and, for classifiers, one probability_<class> column per class (probability_1 is the positive class for a 0/1 target); compute the holdout metrics and decision threshold yourself from it, since EasyDeploy does not return them. For a string target the probability columns are named by encoded class index (probability_0, probability_1, ... in sorted label order), not by label; the completed prediction's classLabels, from get_prediction, maps each index to its label. Columns the model was not trained on, such as ids, are ignored for scoring and kept in the output, so leave them in to join results back; every training feature must be present or the job fails naming the missing one. The download is capped at 9 MB, so keep test files small enough that their scored output fits, or split the test set across several batches.

Returns immediately by default (fire-and-poll). get_prediction(prediction_id) reports the status; for a completed batch it also has batch_output_available: true, download_url and curl_command. Set wait_for_result=true to block for max_wait_seconds (45 s by default, at most 60 s); if the batch is still running then, the result has timed_out: true and next_steps: poll get_prediction to keep waiting.

get_predictionA

Fetch prediction status and result by prediction id.

  • Ad-hoc completed: output has the predicted label or value per row. For a classifier, probabilities has each row's probability_<class> values, in the same order.

  • Batch completed: download_url and curl_command are included automatically. curl_command is the HTTP GET that downloads the scored CSV through EasyDeploy's tokenized gateway; it carries a short-lived download token, never the API key.

  • Classifiers, ad-hoc and batch, also return classLabels: the label each <class> in probability_<class> stands for, such as {"0": "B", "1": "M"}. Regressors, models that give no probabilities, and predictions completed before these fields existed return neither field.

list_predictionsA

List predictions (newest first). Optionally filter by project_id. Use get_prediction(id) for full result + batch download URL.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.8/5.0

Scored across 28 tools

Disambiguation4/5

Most tools target clearly distinct resources and actions, and the upload/train/predict flows are well explained. Minor overlap exists between get_training_status and model-version status tracking, and between complete_upload and create_dataset_version for registering dataset versions.

Naming Consistency5/5

Tool names consistently use snake_case with predictable verb_noun phrasing such as list_projects, get_dataset, create_model_version, and run_batch_prediction. The few create_* tools that also update still follow the same naming convention.

Tool Count3/5

28 tools is heavy, though it reflects a broad MLOps platform spanning projects, datasets, versions, models, training, and predictions. Several list/get pairs could likely be consolidated, but few tools are clearly redundant.

Completeness4/5

The core ML lifecycle is well covered: upload, dataset/model/version creation, training, reporting, and ad-hoc/batch prediction. Gaps remain around deletion operations, model-version updates, and endpoint/deployment management hinted at by account status.

Maintenance

ActivityNo data
ResponsivenessNo issues