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 = "[email protected]" }]
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
2 changes: 2 additions & 0 deletions src/codeocean_mcp_server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
computations,
custom_metadata,
data_assets,
release,
)


Expand Down Expand Up @@ -94,6 +95,7 @@ def main():
data_assets.add_tools(mcp, client)
computations.add_tools(mcp, client)
custom_metadata.add_tools(mcp, client)
release.add_tools(mcp, client)

mcp.run(transport=args.transport)

Expand Down
39 changes: 39 additions & 0 deletions src/codeocean_mcp_server/tools/release.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from codeocean import CodeOcean
from codeocean.capsule import CapsuleReleaseJob
from mcp.server.fastmcp import FastMCP


def add_tools(mcp: FastMCP, client: CodeOcean):
"""Add capsule and pipeline release tools to the MCP server."""

@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)
14 changes: 7 additions & 7 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.