Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

## 0.13.0 (TBD)

- [#37](https://github.com/codeocean/codeocean-mcp-server/pull/37) feat: add public release capsule/pipeline API
- **Requires `codeocean>=0.17.0`.**

## 0.12.2 (2026-09-03)

- [#42](https://github.com/codeocean/codeocean-mcp-server/pull/42) fix: run synchronous tool bodies in a worker thread
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Model Context Protocol (MCP) server for Code Ocean.

This MCP server provides tools to search and run capsules and pipelines, and manage data assets.
This MCP server provides tools to search, run, and release capsules and pipelines, and manage data assets.

## Table of Contents

Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "codeocean-mcp-server"
version = "0.12.2"
version = "0.13.0"
authors = [{ name = "Code Ocean", email = "dev@codeocean.com" }]
description = "Code Ocean MCP Server"
readme = "README.md"
Expand All @@ -12,7 +12,7 @@ classifiers = [
]
dependencies = [
"anyio>=4.5",
"codeocean>=0.14.0,<0.15.0",
"codeocean>=0.17.0,<0.18.0",
"mcp>=1.23.0,<1.24.0",
]
license = "MIT"
Expand Down
33 changes: 33 additions & 0 deletions src/codeocean_mcp_server/tools/capsules.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from codeocean.capsule import (
AppPanel,
Capsule,
CapsuleReleaseJob,
CapsuleSearchParams,
Computation,
DataAssetAttachParams,
Expand Down Expand Up @@ -86,3 +87,35 @@ def detach_data_assets(capsule_id: str, data_assets: list[str]) -> None:
def get_capsule_app_panel(capsule_id: str, version: int | None = None) -> AppPanelModel:
"""Retrieve the app panel for a capsule, optionally for a specific version."""
return client.capsules.get_capsule_app_panel(capsule_id, version)

@mcp.tool(description=str(client.capsules.release_capsule.__doc__))
def release_capsule(capsule_id: str) -> CapsuleReleaseJob:
"""Start releasing a new version of an already-released capsule."""
return client.capsules.release_capsule(capsule_id)

@mcp.tool(description=str(client.pipelines.release_pipeline.__doc__))
def release_pipeline(pipeline_id: str) -> CapsuleReleaseJob:
"""Start releasing a new version of an already-released pipeline."""
return client.pipelines.release_pipeline(pipeline_id)

@mcp.tool(description=str(client.capsules.get_release_job.__doc__))
def get_capsule_release_job(capsule_id: str, job_id: str) -> CapsuleReleaseJob:
"""Get the status of a capsule release job."""
return client.capsules.get_release_job(capsule_id, job_id)

@mcp.tool(description=str(client.pipelines.get_release_job.__doc__))
def get_pipeline_release_job(pipeline_id: str, job_id: str) -> CapsuleReleaseJob:
"""Get the status of a pipeline release job."""
return client.pipelines.get_release_job(pipeline_id, job_id)

@mcp.tool(description=str(client.capsules.wait_until_release_completed.__doc__))
def wait_until_capsule_release_completed(capsule_id: str, job_id: str) -> CapsuleReleaseJob:
"""Wait until a capsule release job reaches a terminal state and return it."""
job = client.capsules.get_release_job(capsule_id, job_id)
return client.capsules.wait_until_release_completed(capsule_id, job)

@mcp.tool(description=str(client.pipelines.wait_until_release_completed.__doc__))
def wait_until_pipeline_release_completed(pipeline_id: str, job_id: str) -> CapsuleReleaseJob:
"""Wait until a pipeline release job reaches a terminal state and return it."""
job = client.pipelines.get_release_job(pipeline_id, job_id)
return client.pipelines.wait_until_release_completed(pipeline_id, job)