codeocean-mcp-server 0.1.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/.gitignore +8 -0
- codeocean_mcp_server-0.3.0/CHANGELOG.md +15 -0
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/PKG-INFO +14 -8
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/README.md +12 -6
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/pyproject.toml +2 -2
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/server.py +2 -1
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/tools/capsules.py +12 -20
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/tools/computations.py +13 -21
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/tools/data_assets.py +15 -31
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/tests/test_multi_tool_calling.py +1 -1
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/tests/test_tool_calling.py +1 -1
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/uv.lock +5 -5
- codeocean_mcp_server-0.1.0/CHANGELOG.md +0 -6
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/.python-version +0 -0
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/LICENSE +0 -0
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/RELEASE.md +0 -0
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/__init__.py +0 -0
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/file_utils.py +0 -0
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/models.py +0 -0
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/tools/__init__.py +0 -0
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/tests/bedrock_call.py +0 -0
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/tests/bedrock_tools_converter.py +0 -0
- {codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/tests/mcp_client.py +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
CHANGELOG
|
|
2
|
+
=========
|
|
3
|
+
|
|
4
|
+
## 0.3.0 (2025-07-14)
|
|
5
|
+
|
|
6
|
+
- [#5](https://github.com/codeocean/codeocean-mcp-server/pull/5) feat: Add support for AI agent ID in server configuration
|
|
7
|
+
- [#4](https://github.com/codeocean/codeocean-mcp-server/pull/4) fix: ignore CI artifacts in sdist
|
|
8
|
+
|
|
9
|
+
## 0.2.0 (2025-07-02)
|
|
10
|
+
|
|
11
|
+
- [#2](https://github.com/codeocean/codeocean-mcp-server/pull/2) fix: return native client objects instead of Pydantic models
|
|
12
|
+
|
|
13
|
+
## 0.1.0 (2025-07-01)
|
|
14
|
+
|
|
15
|
+
- [#1](https://github.com/codeocean/codeocean-mcp-server/pull/1) Initial version
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeocean-mcp-server
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Code Ocean MCP Server
|
|
5
5
|
Project-URL: Homepage, https://github.com/codeocean/codeocean-mcp-server
|
|
6
6
|
Project-URL: Issues, https://github.com/codeocean/codeocean-mcp-server/issues
|
|
@@ -12,7 +12,7 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
14
|
Requires-Python: >=3.10
|
|
15
|
-
Requires-Dist: codeocean
|
|
15
|
+
Requires-Dist: codeocean<0.9.0,>=0.8.0
|
|
16
16
|
Requires-Dist: fastmcp>=2.9.2
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
|
|
@@ -63,7 +63,8 @@ Here's an example VS Code MCP server configuration:
|
|
|
63
63
|
"args": ["codeocean-mcp-server"],
|
|
64
64
|
"env": {
|
|
65
65
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
66
|
-
"CODEOCEAN_TOKEN": "${input:codeocean-token}"
|
|
66
|
+
"CODEOCEAN_TOKEN": "${input:codeocean-token}",
|
|
67
|
+
"AGENT_ID": "VS Code"
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
},
|
|
@@ -88,7 +89,8 @@ Here's an example VS Code MCP server configuration:
|
|
|
88
89
|
"args": ["codeocean-mcp-server"],
|
|
89
90
|
"env": {
|
|
90
91
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
91
|
-
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>"
|
|
92
|
+
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>",
|
|
93
|
+
"AGENT_ID": "Claude Desktop"
|
|
92
94
|
}
|
|
93
95
|
}
|
|
94
96
|
}
|
|
@@ -111,7 +113,8 @@ Cline stores all of its MCP settings in a JSON file called cline_mcp_settings.js
|
|
|
111
113
|
"args": ["codeocean-mcp-server"],
|
|
112
114
|
"env": {
|
|
113
115
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
114
|
-
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>"
|
|
116
|
+
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>",
|
|
117
|
+
"AGENT_ID": "Cline"
|
|
115
118
|
},
|
|
116
119
|
"alwaysAllow": [], // optional: list of tools to auto-approve
|
|
117
120
|
"disabled": false // ensure it’s enabled
|
|
@@ -140,7 +143,8 @@ Roo Code’s MCP support is configured globally across all workspaces via a JSON
|
|
|
140
143
|
"args": ["codeocean-mcp-server"],
|
|
141
144
|
"env": {
|
|
142
145
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
143
|
-
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>"
|
|
146
|
+
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>",
|
|
147
|
+
"AGENT_ID": "Roo Code"
|
|
144
148
|
}
|
|
145
149
|
}
|
|
146
150
|
}
|
|
@@ -168,7 +172,8 @@ Cursor stores MCP servers in a JSON file at either ~/.cursor/mcp.json (global) o
|
|
|
168
172
|
"args": ["codeocean-mcp-server"],
|
|
169
173
|
"env": {
|
|
170
174
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
171
|
-
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>"
|
|
175
|
+
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>",
|
|
176
|
+
"AGENT_ID": "Cursor"
|
|
172
177
|
}
|
|
173
178
|
}
|
|
174
179
|
}
|
|
@@ -191,7 +196,8 @@ Windsurf (Cascade) uses mcp_config.json under ~/.codeium/windsurf/ (or via the C
|
|
|
191
196
|
"args": ["codeocean-mcp-server"],
|
|
192
197
|
"env": {
|
|
193
198
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
194
|
-
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>"
|
|
199
|
+
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>",
|
|
200
|
+
"AGENT_ID": "Windsurf"
|
|
195
201
|
}
|
|
196
202
|
}
|
|
197
203
|
}
|
|
@@ -45,7 +45,8 @@ Here's an example VS Code MCP server configuration:
|
|
|
45
45
|
"args": ["codeocean-mcp-server"],
|
|
46
46
|
"env": {
|
|
47
47
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
48
|
-
"CODEOCEAN_TOKEN": "${input:codeocean-token}"
|
|
48
|
+
"CODEOCEAN_TOKEN": "${input:codeocean-token}",
|
|
49
|
+
"AGENT_ID": "VS Code"
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
},
|
|
@@ -70,7 +71,8 @@ Here's an example VS Code MCP server configuration:
|
|
|
70
71
|
"args": ["codeocean-mcp-server"],
|
|
71
72
|
"env": {
|
|
72
73
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
73
|
-
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>"
|
|
74
|
+
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>",
|
|
75
|
+
"AGENT_ID": "Claude Desktop"
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
}
|
|
@@ -93,7 +95,8 @@ Cline stores all of its MCP settings in a JSON file called cline_mcp_settings.js
|
|
|
93
95
|
"args": ["codeocean-mcp-server"],
|
|
94
96
|
"env": {
|
|
95
97
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
96
|
-
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>"
|
|
98
|
+
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>",
|
|
99
|
+
"AGENT_ID": "Cline"
|
|
97
100
|
},
|
|
98
101
|
"alwaysAllow": [], // optional: list of tools to auto-approve
|
|
99
102
|
"disabled": false // ensure it’s enabled
|
|
@@ -122,7 +125,8 @@ Roo Code’s MCP support is configured globally across all workspaces via a JSON
|
|
|
122
125
|
"args": ["codeocean-mcp-server"],
|
|
123
126
|
"env": {
|
|
124
127
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
125
|
-
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>"
|
|
128
|
+
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>",
|
|
129
|
+
"AGENT_ID": "Roo Code"
|
|
126
130
|
}
|
|
127
131
|
}
|
|
128
132
|
}
|
|
@@ -150,7 +154,8 @@ Cursor stores MCP servers in a JSON file at either ~/.cursor/mcp.json (global) o
|
|
|
150
154
|
"args": ["codeocean-mcp-server"],
|
|
151
155
|
"env": {
|
|
152
156
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
153
|
-
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>"
|
|
157
|
+
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>",
|
|
158
|
+
"AGENT_ID": "Cursor"
|
|
154
159
|
}
|
|
155
160
|
}
|
|
156
161
|
}
|
|
@@ -173,7 +178,8 @@ Windsurf (Cascade) uses mcp_config.json under ~/.codeium/windsurf/ (or via the C
|
|
|
173
178
|
"args": ["codeocean-mcp-server"],
|
|
174
179
|
"env": {
|
|
175
180
|
"CODEOCEAN_DOMAIN": "https://codeocean.acme.com",
|
|
176
|
-
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>"
|
|
181
|
+
"CODEOCEAN_TOKEN": "<YOUR_API_KEY>",
|
|
182
|
+
"AGENT_ID": "Windsurf"
|
|
177
183
|
}
|
|
178
184
|
}
|
|
179
185
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codeocean-mcp-server"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
4
4
|
authors = [{ name = "Code Ocean", email = "dev@codeocean.com" }]
|
|
5
5
|
description = "Code Ocean MCP Server"
|
|
6
6
|
readme = "README.md"
|
|
@@ -11,7 +11,7 @@ classifiers = [
|
|
|
11
11
|
"Operating System :: OS Independent",
|
|
12
12
|
]
|
|
13
13
|
dependencies = [
|
|
14
|
-
"codeocean>=0.
|
|
14
|
+
"codeocean>=0.8.0,<0.9.0",
|
|
15
15
|
"fastmcp>=2.9.2",
|
|
16
16
|
]
|
|
17
17
|
license = "MIT"
|
{codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/server.py
RENAMED
|
@@ -15,7 +15,8 @@ def main():
|
|
|
15
15
|
"Environment variables CODEOCEAN_DOMAIN and "
|
|
16
16
|
"CODEOCEAN_TOKEN must be set."
|
|
17
17
|
)
|
|
18
|
-
|
|
18
|
+
agent_id = os.getenv("AGENT_ID", "AI Agent")
|
|
19
|
+
client = CodeOcean(domain=domain, token=token, agent_id=agent_id)
|
|
19
20
|
|
|
20
21
|
mcp = FastMCP(
|
|
21
22
|
name="Code Ocean",
|
{codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/tools/capsules.py
RENAMED
|
@@ -11,12 +11,8 @@ from mcp.server.fastmcp import FastMCP
|
|
|
11
11
|
|
|
12
12
|
from codeocean_mcp_server.models import dataclass_to_pydantic
|
|
13
13
|
|
|
14
|
-
CapsuleModel = dataclass_to_pydantic(Capsule)
|
|
15
14
|
CapsuleSearchParamsModel = dataclass_to_pydantic(CapsuleSearchParams)
|
|
16
|
-
CapsuleSearchResultsModel = dataclass_to_pydantic(CapsuleSearchResults)
|
|
17
|
-
ComputationModel = dataclass_to_pydantic(Computation)
|
|
18
15
|
DataAssetAttachParamsModel = dataclass_to_pydantic(DataAssetAttachParams)
|
|
19
|
-
DataAssetAttachResultsModel = dataclass_to_pydantic(DataAssetAttachResults)
|
|
20
16
|
|
|
21
17
|
|
|
22
18
|
def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
@@ -31,12 +27,10 @@ def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
|
31
27
|
"like sort_by or sort_order unless requested."
|
|
32
28
|
)
|
|
33
29
|
)
|
|
34
|
-
def search_capsules(
|
|
35
|
-
search_params: CapsuleSearchParamsModel,
|
|
36
|
-
) -> CapsuleSearchResultsModel:
|
|
30
|
+
def search_capsules(search_params: CapsuleSearchParamsModel) -> CapsuleSearchResults:
|
|
37
31
|
"""Search for capsules matching specified criteria."""
|
|
38
32
|
params = CapsuleSearchParams(**search_params.model_dump(exclude_none=True))
|
|
39
|
-
return
|
|
33
|
+
return client.capsules.search_capsules(params)
|
|
40
34
|
|
|
41
35
|
@mcp.tool(
|
|
42
36
|
description=(
|
|
@@ -47,13 +41,14 @@ def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
|
47
41
|
)
|
|
48
42
|
def attach_data_assets(
|
|
49
43
|
capsule_id: str,
|
|
50
|
-
|
|
51
|
-
) -> list[
|
|
44
|
+
attach_params: list[DataAssetAttachParamsModel],
|
|
45
|
+
) -> list[DataAssetAttachResults]:
|
|
52
46
|
"""Attach data assets to a capsule."""
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
for
|
|
47
|
+
params = [
|
|
48
|
+
DataAssetAttachParams(**p.model_dump(exclude_none=True))
|
|
49
|
+
for p in attach_params
|
|
56
50
|
]
|
|
51
|
+
return client.capsules.attach_data_assets(capsule_id, params)
|
|
57
52
|
|
|
58
53
|
@mcp.tool(
|
|
59
54
|
description=(
|
|
@@ -62,14 +57,11 @@ def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
|
62
57
|
"Do not use for searching."
|
|
63
58
|
)
|
|
64
59
|
)
|
|
65
|
-
def get_capsule(capsule_id: str) ->
|
|
60
|
+
def get_capsule(capsule_id: str) -> Capsule:
|
|
66
61
|
"""Retrieve a capsule by its ID."""
|
|
67
|
-
return
|
|
62
|
+
return client.capsules.get_capsule(capsule_id)
|
|
68
63
|
|
|
69
64
|
@mcp.tool(description=client.capsules.list_computations.__doc__)
|
|
70
|
-
def list_computations(capsule_id: str) -> list[
|
|
65
|
+
def list_computations(capsule_id: str) -> list[Computation]:
|
|
71
66
|
"""List all computations for a capsule."""
|
|
72
|
-
return
|
|
73
|
-
dataclass_to_pydantic(computation)
|
|
74
|
-
for computation in client.capsules.list_computations(capsule_id)
|
|
75
|
-
]
|
|
67
|
+
return client.capsules.list_computations(capsule_id)
|
|
@@ -10,9 +10,6 @@ from mcp.server.fastmcp import FastMCP
|
|
|
10
10
|
from codeocean_mcp_server.file_utils import download_and_read_file
|
|
11
11
|
from codeocean_mcp_server.models import dataclass_to_pydantic
|
|
12
12
|
|
|
13
|
-
ComputationModel = dataclass_to_pydantic(Computation)
|
|
14
|
-
DownloadFileURLModel = dataclass_to_pydantic(DownloadFileURL)
|
|
15
|
-
FolderModel = dataclass_to_pydantic(Folder)
|
|
16
13
|
RunParamsModel = dataclass_to_pydantic(RunParams)
|
|
17
14
|
|
|
18
15
|
|
|
@@ -20,12 +17,9 @@ def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
|
20
17
|
"""Add capsule tools to the MCP server."""
|
|
21
18
|
|
|
22
19
|
@mcp.tool(description=client.computations.get_computation.__doc__)
|
|
23
|
-
def get_computation(computation_id: str) ->
|
|
20
|
+
def get_computation(computation_id: str) -> Computation:
|
|
24
21
|
"""Retrieve a specific computation by its unique identifier."""
|
|
25
|
-
return
|
|
26
|
-
dataclass_to_pydantic(computation)
|
|
27
|
-
for computation in client.computations.get_computation(computation_id)
|
|
28
|
-
]
|
|
22
|
+
return client.computations.get_computation(computation_id)
|
|
29
23
|
|
|
30
24
|
@mcp.tool(
|
|
31
25
|
description=(
|
|
@@ -36,16 +30,17 @@ def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
|
36
30
|
"to retrieve outputs."
|
|
37
31
|
)
|
|
38
32
|
)
|
|
39
|
-
def run_capsule(run_params: RunParamsModel) ->
|
|
33
|
+
def run_capsule(run_params: RunParamsModel) -> Computation:
|
|
40
34
|
"""Execute a capsule or a pipeline in Code Ocean and don't wait."""
|
|
41
|
-
|
|
35
|
+
params = RunParams(**run_params.model_dump(exclude_none=True))
|
|
36
|
+
return client.computations.run_capsule(params)
|
|
42
37
|
|
|
43
38
|
@mcp.tool(description=client.computations.wait_until_completed.__doc__)
|
|
44
|
-
def wait_until_completed(computation_id: str) ->
|
|
39
|
+
def wait_until_completed(computation_id: str) -> Computation:
|
|
45
40
|
"""Wait until a computation completes and return its details."""
|
|
46
|
-
# first get the computation based on the computation_id:
|
|
47
41
|
computation = client.computations.get_computation(computation_id)
|
|
48
|
-
return
|
|
42
|
+
return client.computations.wait_until_completed(computation)
|
|
43
|
+
|
|
49
44
|
|
|
50
45
|
@mcp.tool(
|
|
51
46
|
description=(
|
|
@@ -53,18 +48,15 @@ def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
|
53
48
|
+ " computation_id is required as string"
|
|
54
49
|
)
|
|
55
50
|
)
|
|
56
|
-
def list_computation_results(computation_id: str) ->
|
|
51
|
+
def list_computation_results(computation_id: str) -> Folder:
|
|
57
52
|
"""List the output files generated by a completed computation."""
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
)
|
|
53
|
+
return client.computations.list_computation_results(computation_id)
|
|
54
|
+
|
|
61
55
|
|
|
62
56
|
@mcp.tool(description=(client.computations.get_result_file_download_url.__doc__))
|
|
63
|
-
def get_result_file_download_url(computation_id: str, file_path: str) ->
|
|
57
|
+
def get_result_file_download_url(computation_id: str, file_path: str) -> DownloadFileURL:
|
|
64
58
|
"""Get download URL for a specific result file from computation."""
|
|
65
|
-
return
|
|
66
|
-
client.computations.get_result_file_download_url(computation_id, file_path),
|
|
67
|
-
)
|
|
59
|
+
return client.computations.get_result_file_download_url(computation_id, file_path)
|
|
68
60
|
|
|
69
61
|
@mcp.tool(
|
|
70
62
|
description=(
|
|
@@ -3,7 +3,6 @@ import os
|
|
|
3
3
|
from codeocean import CodeOcean
|
|
4
4
|
from codeocean.data_asset import (
|
|
5
5
|
DataAsset,
|
|
6
|
-
DataAssetAttachParams,
|
|
7
6
|
DataAssetParams,
|
|
8
7
|
DataAssetSearchParams,
|
|
9
8
|
DataAssetSearchResults,
|
|
@@ -16,14 +15,10 @@ from mcp.server.fastmcp import FastMCP
|
|
|
16
15
|
from codeocean_mcp_server.file_utils import download_and_read_file
|
|
17
16
|
from codeocean_mcp_server.models import dataclass_to_pydantic
|
|
18
17
|
|
|
19
|
-
DataAssetAttachParamsModel = dataclass_to_pydantic(DataAssetAttachParams)
|
|
20
18
|
DataAssetModel = dataclass_to_pydantic(DataAsset)
|
|
21
19
|
DataAssetParamsModel = dataclass_to_pydantic(DataAssetParams)
|
|
22
20
|
DataAssetSearchParamsModel = dataclass_to_pydantic(DataAssetSearchParams)
|
|
23
|
-
DataAssetSearchResultsModel = dataclass_to_pydantic(DataAssetSearchResults)
|
|
24
21
|
DataAssetUpdateParamsModel = dataclass_to_pydantic(DataAssetUpdateParams)
|
|
25
|
-
DownloadFileURLModel = dataclass_to_pydantic(DownloadFileURL)
|
|
26
|
-
FolderModel = dataclass_to_pydantic(Folder)
|
|
27
22
|
|
|
28
23
|
|
|
29
24
|
def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
@@ -37,10 +32,10 @@ def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
|
37
32
|
"SDK."
|
|
38
33
|
)
|
|
39
34
|
)
|
|
40
|
-
def search_data_assets(search_params: DataAssetSearchParamsModel) ->
|
|
35
|
+
def search_data_assets(search_params: DataAssetSearchParamsModel) -> DataAssetSearchResults:
|
|
41
36
|
"""Retrieve data assets matching search criteria for datasets."""
|
|
42
37
|
params = DataAssetSearchParams(**search_params.model_dump(exclude_none=True))
|
|
43
|
-
return
|
|
38
|
+
return client.data_assets.search_data_assets(params)
|
|
44
39
|
|
|
45
40
|
@mcp.tool(
|
|
46
41
|
description=(
|
|
@@ -51,14 +46,9 @@ def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
|
51
46
|
"download URL."
|
|
52
47
|
)
|
|
53
48
|
)
|
|
54
|
-
def get_data_asset_file_download_url(
|
|
55
|
-
data_asset_id: str,
|
|
56
|
-
file_path: str | None = None,
|
|
57
|
-
) -> DownloadFileURLModel:
|
|
49
|
+
def get_data_asset_file_download_url(data_asset_id: str, file_path: str) -> DownloadFileURL:
|
|
58
50
|
"""Get a download URL for a specific file in a data asset."""
|
|
59
|
-
return
|
|
60
|
-
client.data_assets.get_data_asset_file_download_url(data_asset_id, file_path),
|
|
61
|
-
)
|
|
51
|
+
return client.data_assets.get_data_asset_file_download_url(data_asset_id, file_path)
|
|
62
52
|
|
|
63
53
|
@mcp.tool(
|
|
64
54
|
description=(
|
|
@@ -71,22 +61,18 @@ def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
|
71
61
|
return download_and_read_file(file_url.url)
|
|
72
62
|
|
|
73
63
|
@mcp.tool(description=client.data_assets.list_data_asset_files.__doc__)
|
|
74
|
-
def list_data_asset_files(data_asset_id: str) ->
|
|
64
|
+
def list_data_asset_files(data_asset_id: str) -> Folder:
|
|
75
65
|
"""List files in a data asset."""
|
|
76
|
-
return
|
|
77
|
-
client.data_assets.list_data_asset_files(data_asset_id),
|
|
78
|
-
)
|
|
66
|
+
return client.data_assets.list_data_asset_files(data_asset_id)
|
|
79
67
|
|
|
80
68
|
@mcp.tool(description=client.data_assets.update_metadata.__doc__)
|
|
81
69
|
def update_metadata(
|
|
82
70
|
data_asset_id: str,
|
|
83
71
|
update_params: DataAssetUpdateParamsModel,
|
|
84
|
-
) ->
|
|
72
|
+
) -> DataAsset:
|
|
85
73
|
"""Update metadata for a specific data asset."""
|
|
86
|
-
|
|
87
|
-
return
|
|
88
|
-
client.data_assets.update_metadata(data_asset_id, update_params)
|
|
89
|
-
)
|
|
74
|
+
params = DataAssetUpdateParams(**update_params.model_dump(exclude_none=True))
|
|
75
|
+
return client.data_assets.update_metadata(data_asset_id, params)
|
|
90
76
|
|
|
91
77
|
@mcp.tool(
|
|
92
78
|
description=(
|
|
@@ -100,16 +86,14 @@ def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
|
100
86
|
data_asset: DataAssetModel,
|
|
101
87
|
polling_interval: float = 5,
|
|
102
88
|
timeout: float | None = None,
|
|
103
|
-
) ->
|
|
89
|
+
) -> DataAsset:
|
|
104
90
|
"""Wait until a data asset is ready."""
|
|
105
|
-
|
|
91
|
+
return client.data_assets.wait_until_ready(
|
|
106
92
|
DataAsset(**data_asset.model_dump(exclude_none=True)),
|
|
107
|
-
polling_interval
|
|
108
|
-
timeout
|
|
93
|
+
polling_interval,
|
|
94
|
+
timeout,
|
|
109
95
|
)
|
|
110
96
|
|
|
111
|
-
return dataclass_to_pydantic(result)
|
|
112
|
-
|
|
113
97
|
@mcp.tool(
|
|
114
98
|
description=(
|
|
115
99
|
str(client.data_assets.create_data_asset.__doc__)
|
|
@@ -117,7 +101,7 @@ def add_tools(mcp: FastMCP, client: CodeOcean):
|
|
|
117
101
|
f"with the pattern: {os.getenv('CODEOCEAN_DOMAIN', 'unknown')} with /data-assets/<data_asset_id>."
|
|
118
102
|
)
|
|
119
103
|
)
|
|
120
|
-
def create_data_asset(data_asset_params: DataAssetParamsModel) ->
|
|
104
|
+
def create_data_asset(data_asset_params: DataAssetParamsModel) -> DataAsset:
|
|
121
105
|
"""Create a new data asset."""
|
|
122
106
|
params = DataAssetParams(**data_asset_params.model_dump(exclude_none=True))
|
|
123
|
-
return
|
|
107
|
+
return client.data_assets.create_data_asset(params)
|
|
@@ -46,7 +46,7 @@ def test_prompt_generates_correct_tool_usage_sequence(
|
|
|
46
46
|
if not prompt:
|
|
47
47
|
prompt = agentic_prompt_chain["prompt"]
|
|
48
48
|
else:
|
|
49
|
-
prompt += str(responses) + "\nwhat is the next
|
|
49
|
+
prompt += str(responses) + "\nwhat is the next step?\n"
|
|
50
50
|
response = call_bedrock(prompt=prompt, tools=tools)
|
|
51
51
|
check_diff(step[0], response)
|
|
52
52
|
responses.append(
|
|
@@ -399,7 +399,7 @@ test_response = [
|
|
|
399
399
|
},
|
|
400
400
|
},
|
|
401
401
|
# --------------------------------------------------------------
|
|
402
|
-
# update
|
|
402
|
+
# update metadata: custom metadata
|
|
403
403
|
{
|
|
404
404
|
"id": "update_metadata_custom_metadata",
|
|
405
405
|
"prompt": "update metadata for data asset with id: data_asset102, set custom metadata 'key1' to 'value1' and 'key2' to 'value2'", # noqa: E501
|
|
@@ -350,7 +350,7 @@ wheels = [
|
|
|
350
350
|
|
|
351
351
|
[[package]]
|
|
352
352
|
name = "codeocean"
|
|
353
|
-
version = "0.
|
|
353
|
+
version = "0.8.0"
|
|
354
354
|
source = { registry = "https://pypi.org/simple" }
|
|
355
355
|
dependencies = [
|
|
356
356
|
{ name = "backports-strenum", marker = "python_full_version < '3.11'" },
|
|
@@ -358,14 +358,14 @@ dependencies = [
|
|
|
358
358
|
{ name = "requests" },
|
|
359
359
|
{ name = "requests-toolbelt" },
|
|
360
360
|
]
|
|
361
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
361
|
+
sdist = { url = "https://files.pythonhosted.org/packages/e6/66/c947525bd7bdbc8dd337b3ab0badd4be9c47a4869404640c6e000e3ec5a8/codeocean-0.8.0.tar.gz", hash = "sha256:fbbff4de028f034495584731ca3a4830d9a90a97b88839cfe16aeaebb5caa561", size = 15530, upload-time = "2025-07-11T16:50:17.372Z" }
|
|
362
362
|
wheels = [
|
|
363
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
363
|
+
{ url = "https://files.pythonhosted.org/packages/9e/16/d8a220ef5ea2f938be973394f23687208dcfb3ba737c022e88f3d6a97134/codeocean-0.8.0-py3-none-any.whl", hash = "sha256:73feba7c9c2c03a21ba07feaf0e946e3087d2d29af38efbd61d452dd7a8ef1a5", size = 16365, upload-time = "2025-07-11T16:50:18.622Z" },
|
|
364
364
|
]
|
|
365
365
|
|
|
366
366
|
[[package]]
|
|
367
367
|
name = "codeocean-mcp-server"
|
|
368
|
-
version = "0.
|
|
368
|
+
version = "0.3.0"
|
|
369
369
|
source = { editable = "." }
|
|
370
370
|
dependencies = [
|
|
371
371
|
{ name = "codeocean" },
|
|
@@ -384,7 +384,7 @@ dev = [
|
|
|
384
384
|
|
|
385
385
|
[package.metadata]
|
|
386
386
|
requires-dist = [
|
|
387
|
-
{ name = "codeocean", specifier = ">=0.
|
|
387
|
+
{ name = "codeocean", specifier = ">=0.8.0,<0.9.0" },
|
|
388
388
|
{ name = "fastmcp", specifier = ">=2.9.2" },
|
|
389
389
|
]
|
|
390
390
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/__init__.py
RENAMED
|
File without changes
|
{codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/file_utils.py
RENAMED
|
File without changes
|
{codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/models.py
RENAMED
|
File without changes
|
{codeocean_mcp_server-0.1.0 → codeocean_mcp_server-0.3.0}/src/codeocean_mcp_server/tools/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|