---
title: "Create an environment"
method: POST
path: "/projects/{projectId}/environments"
tags: ["Environments"]
---

# Create an environment

`POST /projects/{projectId}/environments`

Create a project environment from a host plus, optionally, a standalone server group, a pinned skill selection, and pinned plugin versions. The name must be unique among the project's live environments. Requires project admin.

## Path parameters

- `projectId` string, required

## Request body

- ProjectEnvironmentCreateRequest — Unknown fields are rejected.
  - `name` string, required
  - `description` string
  - `hostId` string, required
  - `serverAttachmentId` string
  - `skillSelection` EnvironmentSkillSelection — An explicit pinned skill selection. Cannot be empty — clear the field instead (send `null` on update) to mean "no pinned skills".
    - `mode` 'explicit', required
    - `skillIds` string[], required — Project-shared skill IDs. Skills carrying supporting files or extra frontmatter, and plugin-component skills, cannot be pinned.
  - `pluginVersionIds` string[] — Pinned plugin VERSION IDs. Narrow by design: the plugin must be installed and enabled, the version must be `ready`, at most one version per plugin may be pinned, and none of its skills may carry supporting files. Not a general-purpose plugin list.
  - `sandboxImageId` string — Optional sandbox-image pin. Must be a project-shared image; personal drafts are rejected — promote them first.

## Response `201`

The created environment.

- ProjectEnvironment — A project environment: a named, live-editable execution bundle that eval suites and journeys run against.
  - `id` string, required
  - `projectId` string, required
  - `name` string, required — Unique among the project's live (non-archived) environments.
  - `description` string
  - `hostId` string, required — The host this environment runs against.
  - `serverAttachmentId` string — Present only when the environment pins a standalone server group; otherwise the host config's own servers apply.
  - `skillSelection` EnvironmentSkillSelection — An explicit pinned skill selection. Cannot be empty — clear the field instead (send `null` on update) to mean "no pinned skills".
    - `mode` 'explicit', required
    - `skillIds` string[], required — Project-shared skill IDs. Skills carrying supporting files or extra frontmatter, and plugin-component skills, cannot be pinned.
  - `pluginVersionIds` string[] — Pinned plugin VERSION IDs. Narrow by design: the plugin must be installed and enabled, the version must be `ready`, at most one version per plugin may be pinned, and none of its skills may carry supporting files. Not a general-purpose plugin list.
  - `sandboxImageId` string — Sandbox-image pin: a project-shared image (see the images endpoints) that eval runs in this environment boot a fresh sandbox from. Absent when unpinned.
  - `revision` integer, required — Optimistic-concurrency counter. Pass this back as `expectedRevision` on the next write; if it no longer matches, the write is rejected with 409 instead of overwriting a concurrent edit.
  - `archived` boolean, required — Archived environments cannot be edited or launched until restored.
  - `archivedAt` number — Unix epoch milliseconds. Present only when archived.
  - `createdAt` number, required — Unix epoch milliseconds.
  - `updatedAt` number, required — Unix epoch milliseconds.

## Other responses

- `400` — Malformed body or parameters.
- `401` — Missing, invalid, revoked, or orphaned key (`UNAUTHORIZED`) — or the **target MCP server** needs an OAuth grant (`OAUTH_REQUIRED`), which is a property of the server, not your key.
- `403` — Key is valid but not allowed to do this.
- `404` — Unknown project, server, or resource.
- `409` — The resource is not in a state that accepts this write — a stale `expectedRevision`, a duplicate name, or an environment that cannot currently be launched. The request was well-formed; re-read the resource and retry.
- `429` — Per-key rate limit exceeded (60 requests/minute sustained, bursts up to 10). Honor `Retry-After` and back off with jitter.
- `500` — Something failed on MCPJam's side.
- `502` — Could not connect to the target MCP server.

---

[API](https://skmtc.net/mcpjam/apis/mcpjam-api.md) · [All operations](https://skmtc.net/mcpjam/apis/mcpjam-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mcpjam/mcpjam-api/versions/b767df188d0c/schema)
