From f036819877cdc12f7891ce52a85863ee35419cce Mon Sep 17 00:00:00 2001 From: tomas Date: Fri, 25 Sep 2026 09:43:40 +0000 Subject: [PATCH 1/3] docs: document list_environments and choosing a project's environment The hosted MCP server now advertises list_environments, and create_project and update_project accept an environmentId, so agents can put a project on a chosen Docker image. The nightly drift check flags list_environments as undocumented, and the capability boundary still said the server cannot change environments. Document the tool and the new environmentId arguments from the deepnote-internal implementation, including that changing a project's environment needs admin access to the project and restarts a running machine. Bump both manifests to 0.5.0 so installed plugins pick it up. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01SufsVX7Qvru6rvNpVm8pui --- README.md | 3 ++- plugins/deepnote/.claude-plugin/plugin.json | 2 +- plugins/deepnote/.codex-plugin/plugin.json | 2 +- plugins/deepnote/skills/deepnote-mcp/SKILL.md | 13 +++++++------ plugins/deepnote/skills/deepnote-workspace/SKILL.md | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8b34cc4..a327e2f 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Through the hosted MCP server the agent can: - Search projects, notebooks, blocks, and integrations, and list projects, folders, and integrations - Inspect projects, notebooks, file inventories, input variables, and last-run metadata - Create projects, notebooks, and blocks; rename or duplicate notebooks; and update, delete, or reorder blocks +- List the workspace's environments (Docker images) and choose the one a project runs on - Create, attach, and detach integrations, inspect cached table structure, and map integration usage - Copy an existing file between projects and generate canonical project or notebook URLs - Start notebook runs, optionally with input values, and read run history, status, errors, and snapshot output @@ -123,7 +124,7 @@ Things to know: - Claude Code lists no Deepnote server at all: check that the entry in `plugins/deepnote/.mcp.json` still has `"type": "http"`. - Sign-in says the workspace cannot use the MCP connector, or that MCP access is disabled: a workspace admin needs to enable MCP access for that workspace. - A project, notebook, or integration is missing: the signed-in user, or the API key's creator, needs access to it. -- Creating or editing fails with `Insufficient permissions`: use an editor or admin key, or a user with edit access to the project. +- Creating or editing fails with `Insufficient permissions`: use an editor or admin key, or a user with edit access to the project. Changing a project's environment needs admin access to the project. - Attaching or detaching an integration returns a conflict: inspect the project because the integration is already in the requested state. - `copy_file` reports `File already exists`: the target project already has the same path; the tool never overwrites. - A Streamlit app remains `starting`: it may be slow or may have failed during startup; check the app logs in Deepnote. diff --git a/plugins/deepnote/.claude-plugin/plugin.json b/plugins/deepnote/.claude-plugin/plugin.json index d11bdb3..05eba46 100644 --- a/plugins/deepnote/.claude-plugin/plugin.json +++ b/plugins/deepnote/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "deepnote", - "version": "0.4.0", + "version": "0.5.0", "description": "Search Deepnote workspaces, inspect and edit projects and notebooks, manage integrations, publish static sites and Streamlit apps, generate links, read docs, and run notebooks from Claude Code.", "author": { "name": "Deepnote", diff --git a/plugins/deepnote/.codex-plugin/plugin.json b/plugins/deepnote/.codex-plugin/plugin.json index 4574533..8dff7b8 100644 --- a/plugins/deepnote/.codex-plugin/plugin.json +++ b/plugins/deepnote/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "deepnote", - "version": "0.4.0", + "version": "0.5.0", "description": "Search Deepnote workspaces, inspect and edit projects and notebooks, manage integrations, publish static sites and Streamlit apps, generate links, read docs, and run notebooks from Codex.", "author": { "name": "Deepnote", diff --git a/plugins/deepnote/skills/deepnote-mcp/SKILL.md b/plugins/deepnote/skills/deepnote-mcp/SKILL.md index 36b145c..ad1e8af 100644 --- a/plugins/deepnote/skills/deepnote-mcp/SKILL.md +++ b/plugins/deepnote/skills/deepnote-mcp/SKILL.md @@ -21,7 +21,8 @@ This is the authoritative summary of tool arguments. Workflow skills add only th - `search`: search workspace resources across projects, notebooks, blocks, and integrations. - `list_folders`: list all workspace folders and their `parentFolderId` relationships, optionally filtered by `nameContains`. - `list_projects`: list workspace projects, optionally filtered by name, with cursor pagination (`pageSize`, `pageToken`, `pagination.nextPageToken`, `pagination.hasMore`). Notebook rows expose `isInit`, `isScheduled`, and `lastRunAt`. -- `get_project`: get a project's type, folder, notebooks, attached integration summaries, recursive file inventory, and static-site settings by `projectId`. +- `get_project`: get a project's type, folder, notebooks, attached integration summaries, recursive file inventory, static-site settings, and `environment` by `projectId`. `environment` is `null` when the project builds its image from a Dockerfile or has none set. +- `list_environments`: list the environments (Docker images) projects in the workspace can run on, Deepnote's and the workspace's custom ones, in one unpaginated response. Each has `id`, `name`, `image`, `type` (`deepnote` or `custom`), `language` (`python` or `r`), `isDefault` (one CPU and one GPU default), `isGpu`, and `isDeprecated`; deprecated environments keep working for projects already on them but should not be chosen. A custom image from a private registry is pulled only when its registry integration is attached to the project. - `list_integrations`: list workspace integrations, optionally filtered by name or type. - `get_integration`: get integration details and cached table structure, optionally filtered by `databaseName`, `schemaName`, or exact `tableName`. - `list_integration_project_usages`: list projects connected to an integration, optionally narrowed to one `projectId`. @@ -30,7 +31,7 @@ This is the authoritative summary of tool arguments. Workflow skills add only th - `create_integration`: create a workspace integration of an API-creatable type. Requires `name`, `type`, and connection `metadata`; requires workspace integration-management permission. The response repeats `metadata`, which can contain credentials. - `attach_integration`: attach an integration to a project. Requires `integrationId` and `projectId`; returns a conflict if already attached. - `detach_integration`: detach an integration from a project. Requires `integrationId` and `projectId`; returns a conflict if not attached. -- `create_project`: create a new project. Requires `name`; accepts optional `folderId` and `projectType` (`standard`, `notebook`, or `agent`; defaults to `standard`). The created project includes a default notebook. +- `create_project`: create a new project. Requires `name`; accepts optional `folderId`, `projectType` (`standard`, `notebook`, or `agent`; defaults to `standard`), and `environmentId` from `list_environments` (omitted means the default environment). The created project includes a default notebook. - `create_notebook`: create an empty notebook inside a project. Requires `projectId`; accepts optional `name`. Does not accept starter blocks. - `get_notebook`: get notebook details, blocks, input variables, and last-run metadata by notebook ID. - `update_notebook`: rename a notebook. Requires `notebookId` and `name`; naming it `Init` designates the project init notebook. Rename is the only supported update. @@ -41,7 +42,7 @@ This is the authoritative summary of tool arguments. Workflow skills add only th - `reorder_notebook_blocks`: move one or more existing blocks. Requires `notebookId`, non-empty unique `blockIds` in the desired moved-block order, and `placement` of `{ "type": "start" }`, `{ "type": "end" }`, or `{ "type": "after", "blockId": "anchor-block-id" }`. - `copy_file`: copy one file to a different project at the same normalized path. Requires `sourceProjectId`, `targetProjectId`, and `sourceFilePath`; it accepts no destination path and never overwrites. - `publish_static_site`: publish files beneath a project's static-site root and enable sharing. Requires `projectId` and a non-empty `files` array of `{ path, content, encoding? }`; accepts optional `prune` and `apiAccess` (`enabled` or `disabled`), and returns the canonical URL. -- `update_project`: change static-site access settings. Requires `projectId` and `staticFiles` containing at least one of `sharingEnabled` or `apiAccessEnabled`; API access cannot be enabled while sharing is disabled. +- `update_project`: change a project's static-site access settings or environment. Requires `projectId` and at least one setting. `staticFiles` takes `sharingEnabled` and/or `apiAccessEnabled`; API access cannot be enabled while sharing is disabled. Changing `environmentId` (from `list_environments`) requires admin access to the project and restarts a running machine in the background, which clears kernel state. - `create_streamlit_app`: serve an existing project file as a Streamlit app. Requires `projectId` and project-relative `entrypoint`; returns the app record and URL. - `list_streamlit_apps`: list all Streamlit apps served by a project. Requires `projectId`; the response is unpaginated. - `get_streamlit_app_status`: return `running`, `starting`, or `unavailable` for a `streamlitAppId`. @@ -57,7 +58,7 @@ Before telling a user that a Deepnote action is impossible, check the tools the ## General Rules 1. Use `get_me` when workspace identity, caller role, or API key context would help the answer or troubleshooting. -2. Resolve ambiguous project, folder, notebook, block, or integration names with `search`, `list_projects`, `list_folders`, or `list_integrations` before acting on them. +2. Resolve ambiguous project, folder, notebook, block, integration, or environment names with `search`, `list_projects`, `list_folders`, `list_integrations`, or `list_environments` before acting on them. 3. For complete inventories, page `list_projects` or `list_notebook_runs` with `pageSize: 100` and follow `pagination.nextPageToken` while `pagination.hasMore` is true. Stop early when the user only needs a sample or a filtered answer. Treat page tokens as opaque and tied to the original filters. 4. Use `get_project` for project-wide notebook, integration, file, or static-site state. Call `get_notebook` before reasoning about, editing, or running an existing notebook. 5. Report results with Deepnote object names and IDs when useful, and surface execution errors, missing permissions, input validation errors, or unavailable MCP capabilities. @@ -69,9 +70,9 @@ Before telling a user that a Deepnote action is impossible, check the tools the - Avoid downloading or printing large datasets. Sample, summarize, or aggregate unless the user explicitly asks for an export. - Do not paste `snapshotDownloadUrl` values into answers unless the user asks for a download or file handoff. Snapshot handling is defined in `deepnote-runs`. - Treat notebook execution as potentially stateful and costly. -- Treat resource creation, notebook duplication or renaming, block edits or deletion, file copies, integration creation or attachment changes, app creation, and static-site publishing or sharing changes as persistent writes. Do them only when the user asked, resolve targets carefully, and report affected IDs. +- Treat resource creation, notebook duplication or renaming, block edits or deletion, file copies, integration creation or attachment changes, app creation, static-site publishing or sharing changes, and project environment changes as persistent writes. Do them only when the user asked, resolve targets carefully, and report affected IDs. - If a tool returns `isError`, surface the user-facing error message concisely. -- Capability boundary: the hosted server can create projects, notebooks, blocks, integrations, and Streamlit apps; rename and duplicate notebooks; update, reorder, and delete blocks; copy existing files between projects; attach and detach integrations; and publish or change access to static sites. It cannot upload arbitrary project files, delete projects, notebooks, or Streamlit apps, move notebooks between projects, or change schedules, permissions, environments, hardware, package versions, credentials, or secrets. Check the advertised tools before relying on this boundary. +- Capability boundary: the hosted server can create projects, notebooks, blocks, integrations, and Streamlit apps; rename and duplicate notebooks; update, reorder, and delete blocks; copy existing files between projects; attach and detach integrations; publish or change access to static sites; and choose a project's environment from the existing ones. It cannot upload arbitrary project files, delete projects, notebooks, or Streamlit apps, move notebooks between projects, create custom environments, or change schedules, permissions, hardware, package versions, credentials, or secrets. Check the advertised tools before relying on this boundary. ## Response Style diff --git a/plugins/deepnote/skills/deepnote-workspace/SKILL.md b/plugins/deepnote/skills/deepnote-workspace/SKILL.md index 17194d4..b7ee7fe 100644 --- a/plugins/deepnote/skills/deepnote-workspace/SKILL.md +++ b/plugins/deepnote/skills/deepnote-workspace/SKILL.md @@ -46,7 +46,7 @@ Row rules: ## Project And Folder Inspection -Use `get_project` for a specific project's type, containing folder, notebooks, attached integration summaries, recursive file inventory, and static-site settings. Use `get_notebook` only when block or input detail is needed. Report the relevant notebooks and integrations, a file count unless individual paths were requested, and the current sharing state. +Use `get_project` for a specific project's type, containing folder, notebooks, attached integration summaries, recursive file inventory, static-site settings, and environment. Use `get_notebook` only when block or input detail is needed. Report the relevant notebooks and integrations, a file count unless individual paths were requested, and the current sharing state. Use `list_folders` to resolve the `folderId` for project creation. Folder names are not unique, so resolve nested paths by walking `parentFolderId`; omit `nameContains` when the complete hierarchy is needed. From 2d793ebc4b7e82ebda96ccf641bf1d13c365ae03 Mon Sep 17 00:00:00 2001 From: tomas Date: Fri, 25 Sep 2026 10:35:50 +0000 Subject: [PATCH 2/3] docs: document every update_project setting and its permission update_project also accepts streamlitAppApiAccessEnabled, which lets a project's hosted Streamlit apps call the public API as their signed-in viewers, and get_project returns it. Neither was documented. Every update_project call needs full access to the project (UPDATE_PROJECT_SETTINGS), not only environment changes, so state the requirement once for the whole tool, and point the README troubleshooting at update_project instead of environment changes alone. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01SufsVX7Qvru6rvNpVm8pui --- README.md | 3 ++- plugins/deepnote/skills/deepnote-mcp/SKILL.md | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index a327e2f..89136db 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,8 @@ Things to know: - Claude Code lists no Deepnote server at all: check that the entry in `plugins/deepnote/.mcp.json` still has `"type": "http"`. - Sign-in says the workspace cannot use the MCP connector, or that MCP access is disabled: a workspace admin needs to enable MCP access for that workspace. - A project, notebook, or integration is missing: the signed-in user, or the API key's creator, needs access to it. -- Creating or editing fails with `Insufficient permissions`: use an editor or admin key, or a user with edit access to the project. Changing a project's environment needs admin access to the project. +- Creating or editing fails with `Insufficient permissions`: use an editor or admin key, or a user with edit access to the project. +- `update_project` fails with `Insufficient permissions`: changing a project's static-site access, Streamlit app API access, or environment needs full access to the project, not just edit access. - Attaching or detaching an integration returns a conflict: inspect the project because the integration is already in the requested state. - `copy_file` reports `File already exists`: the target project already has the same path; the tool never overwrites. - A Streamlit app remains `starting`: it may be slow or may have failed during startup; check the app logs in Deepnote. diff --git a/plugins/deepnote/skills/deepnote-mcp/SKILL.md b/plugins/deepnote/skills/deepnote-mcp/SKILL.md index ad1e8af..658d705 100644 --- a/plugins/deepnote/skills/deepnote-mcp/SKILL.md +++ b/plugins/deepnote/skills/deepnote-mcp/SKILL.md @@ -21,7 +21,7 @@ This is the authoritative summary of tool arguments. Workflow skills add only th - `search`: search workspace resources across projects, notebooks, blocks, and integrations. - `list_folders`: list all workspace folders and their `parentFolderId` relationships, optionally filtered by `nameContains`. - `list_projects`: list workspace projects, optionally filtered by name, with cursor pagination (`pageSize`, `pageToken`, `pagination.nextPageToken`, `pagination.hasMore`). Notebook rows expose `isInit`, `isScheduled`, and `lastRunAt`. -- `get_project`: get a project's type, folder, notebooks, attached integration summaries, recursive file inventory, static-site settings, and `environment` by `projectId`. `environment` is `null` when the project builds its image from a Dockerfile or has none set. +- `get_project`: get a project's type, folder, notebooks, attached integration summaries, recursive file inventory, static-site settings, `streamlitAppApiAccessEnabled`, and `environment` by `projectId`. `environment` is `null` when the project builds its image from a Dockerfile or has none set. - `list_environments`: list the environments (Docker images) projects in the workspace can run on, Deepnote's and the workspace's custom ones, in one unpaginated response. Each has `id`, `name`, `image`, `type` (`deepnote` or `custom`), `language` (`python` or `r`), `isDefault` (one CPU and one GPU default), `isGpu`, and `isDeprecated`; deprecated environments keep working for projects already on them but should not be chosen. A custom image from a private registry is pulled only when its registry integration is attached to the project. - `list_integrations`: list workspace integrations, optionally filtered by name or type. - `get_integration`: get integration details and cached table structure, optionally filtered by `databaseName`, `schemaName`, or exact `tableName`. @@ -42,7 +42,7 @@ This is the authoritative summary of tool arguments. Workflow skills add only th - `reorder_notebook_blocks`: move one or more existing blocks. Requires `notebookId`, non-empty unique `blockIds` in the desired moved-block order, and `placement` of `{ "type": "start" }`, `{ "type": "end" }`, or `{ "type": "after", "blockId": "anchor-block-id" }`. - `copy_file`: copy one file to a different project at the same normalized path. Requires `sourceProjectId`, `targetProjectId`, and `sourceFilePath`; it accepts no destination path and never overwrites. - `publish_static_site`: publish files beneath a project's static-site root and enable sharing. Requires `projectId` and a non-empty `files` array of `{ path, content, encoding? }`; accepts optional `prune` and `apiAccess` (`enabled` or `disabled`), and returns the canonical URL. -- `update_project`: change a project's static-site access settings or environment. Requires `projectId` and at least one setting. `staticFiles` takes `sharingEnabled` and/or `apiAccessEnabled`; API access cannot be enabled while sharing is disabled. Changing `environmentId` (from `list_environments`) requires admin access to the project and restarts a running machine in the background, which clears kernel state. +- `update_project`: change a project's settings. Requires `projectId`, full access to the project, and at least one of `staticFiles`, `streamlitAppApiAccessEnabled`, or `environmentId`. `staticFiles` takes `sharingEnabled` and/or `apiAccessEnabled`; API access cannot be enabled while sharing is disabled. `streamlitAppApiAccessEnabled` lets the project's hosted Streamlit apps call the public API as their signed-in viewers. Changing `environmentId` (from `list_environments`) restarts a running machine in the background, which clears kernel state. - `create_streamlit_app`: serve an existing project file as a Streamlit app. Requires `projectId` and project-relative `entrypoint`; returns the app record and URL. - `list_streamlit_apps`: list all Streamlit apps served by a project. Requires `projectId`; the response is unpaginated. - `get_streamlit_app_status`: return `running`, `starting`, or `unavailable` for a `streamlitAppId`. @@ -70,9 +70,9 @@ Before telling a user that a Deepnote action is impossible, check the tools the - Avoid downloading or printing large datasets. Sample, summarize, or aggregate unless the user explicitly asks for an export. - Do not paste `snapshotDownloadUrl` values into answers unless the user asks for a download or file handoff. Snapshot handling is defined in `deepnote-runs`. - Treat notebook execution as potentially stateful and costly. -- Treat resource creation, notebook duplication or renaming, block edits or deletion, file copies, integration creation or attachment changes, app creation, static-site publishing or sharing changes, and project environment changes as persistent writes. Do them only when the user asked, resolve targets carefully, and report affected IDs. +- Treat resource creation, notebook duplication or renaming, block edits or deletion, file copies, integration creation or attachment changes, app creation, static-site publishing or sharing changes, and other project setting changes as persistent writes. Do them only when the user asked, resolve targets carefully, and report affected IDs. - If a tool returns `isError`, surface the user-facing error message concisely. -- Capability boundary: the hosted server can create projects, notebooks, blocks, integrations, and Streamlit apps; rename and duplicate notebooks; update, reorder, and delete blocks; copy existing files between projects; attach and detach integrations; publish or change access to static sites; and choose a project's environment from the existing ones. It cannot upload arbitrary project files, delete projects, notebooks, or Streamlit apps, move notebooks between projects, create custom environments, or change schedules, permissions, hardware, package versions, credentials, or secrets. Check the advertised tools before relying on this boundary. +- Capability boundary: the hosted server can create projects, notebooks, blocks, integrations, and Streamlit apps; rename and duplicate notebooks; update, reorder, and delete blocks; copy existing files between projects; attach and detach integrations; publish or change access to static sites; and change a project's Streamlit app API access and environment. It cannot upload arbitrary project files, delete projects, notebooks, or Streamlit apps, move notebooks between projects, create custom environments, or change schedules, permissions, hardware, package versions, credentials, or secrets. Check the advertised tools before relying on this boundary. ## Response Style From 186e71800699fe5102507aeefb58449d77abef94 Mon Sep 17 00:00:00 2001 From: tomas Date: Wed, 30 Sep 2026 08:41:58 +0000 Subject: [PATCH 3/3] docs: bump the plugin to 0.6.0 main reached 0.5.0 with #20, so this branch's own 0.4.0 -> 0.5.0 bump merged away. Bump again so the environment and update_project details ship as a new version. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01QBB91ZL2r3Qn3T2Bokxfuq --- plugins/deepnote/.claude-plugin/plugin.json | 2 +- plugins/deepnote/.codex-plugin/plugin.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/deepnote/.claude-plugin/plugin.json b/plugins/deepnote/.claude-plugin/plugin.json index 307785c..4387dd3 100644 --- a/plugins/deepnote/.claude-plugin/plugin.json +++ b/plugins/deepnote/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "deepnote", - "version": "0.5.0", + "version": "0.6.0", "description": "Search Deepnote workspaces, inspect and edit projects and notebooks, manage integrations and project machines, publish static sites and Streamlit apps, generate links, read docs, and run notebooks from Claude Code.", "author": { "name": "Deepnote", diff --git a/plugins/deepnote/.codex-plugin/plugin.json b/plugins/deepnote/.codex-plugin/plugin.json index f5f1776..1694f41 100644 --- a/plugins/deepnote/.codex-plugin/plugin.json +++ b/plugins/deepnote/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "deepnote", - "version": "0.5.0", + "version": "0.6.0", "description": "Search Deepnote workspaces, inspect and edit projects and notebooks, manage integrations and project machines, publish static sites and Streamlit apps, generate links, read docs, and run notebooks from Codex.", "author": { "name": "Deepnote",