Skip to content

Commit dd8c5f1

Browse files
committed
cocalc-api/mcp: dynamic tool and resource registration based on api key type
1 parent f5b4f33 commit dd8c5f1

File tree

8 files changed

+557
-411
lines changed

8 files changed

+557
-411
lines changed

src/python/cocalc-api/src/cocalc_api/mcp/DEVELOPMENT.md

Lines changed: 143 additions & 251 deletions
Large diffs are not rendered by default.
Lines changed: 46 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
# CoCalc API MCP Server
22

3-
A Model Context Protocol (MCP) server that allows LLMs to interact with CoCalc projects.
3+
A Model Context Protocol (MCP) server that provides LLMs (Claude, etc.) with direct access to CoCalc accounts and projects.
44

55
## Quick Start
66

7-
### 1. Configuration
8-
9-
Set environment variables:
7+
### 1. Set Environment Variables
108

119
```bash
12-
export COCALC_API_KEY="sk-your-api-key"
13-
export COCALC_PROJECT_ID="your-project-uuid"
14-
export COCALC_HOST="https://cocalc.com" # optional, defaults to https://cocalc.com
10+
export COCALC_API_KEY="sk-your-api-key" # Account or project-scoped
11+
export COCALC_HOST="http://localhost:5000" # Optional, defaults to https://cocalc.com
1512
```
1613

1714
### 2. Run the Server
@@ -20,46 +17,31 @@ export COCALC_HOST="https://cocalc.com" # optional, defaults to https://cocalc.
2017
uv run cocalc-mcp-server
2118
```
2219

23-
### 3. Setup with Claude Code CLI
20+
The server will detect your API key type and automatically register the appropriate tools/resources.
21+
22+
## Setup with Claude Code
23+
24+
### Quick Registration
2425

2526
```bash
26-
# Set your credentials
27-
export COCALC_API_KEY="sk-your-api-key-here"
28-
export COCALC_PROJECT_ID="[UUID]"
29-
export COCALC_API_PATH="/path/to/cocalc/src/python/cocalc-api"
30-
# OPTIONAL: set the host, defaults to cocalc.com. for development use localhost:5000
31-
export COCALC_HOST="http://localhost:5000"
32-
33-
# Add the MCP server to Claude Code
3427
claude mcp add \
3528
--transport stdio \
3629
cocalc \
37-
--env COCALC_API_KEY="$COCALC_API_KEY" \
38-
--env COCALC_PROJECT_ID="$COCALC_PROJECT_ID" \
39-
--env COCALC_HOST="$COCALC_HOST" \
40-
-- uv --directory "$COCALC_API_PATH" run cocalc-mcp-server
30+
--env COCALC_API_KEY="sk-your-api-key" \
31+
-- uv --directory /path/to/cocalc-api run cocalc-mcp-server
4132
```
4233

43-
Alternatively, using JSON configuration:
34+
### Via JSON Config
4435

4536
```bash
4637
claude mcp add-json cocalc '{
4738
"command": "uv",
48-
"args": ["--directory", "/path/to/cocalc/src/python/cocalc-api", "run", "cocalc-mcp-server"],
49-
"env": {
50-
"COCALC_API_KEY": "sk-your-api-key-here",
51-
"COCALC_PROJECT_ID": "[UUID]",
52-
"COCALC_HOST": "http://localhost:5000"
53-
}
39+
"args": ["--directory", "/path/to/cocalc-api", "run", "cocalc-mcp-server"],
40+
"env": {"COCALC_API_KEY": "sk-your-api-key"}
5441
}'
5542
```
5643

57-
**Important:**
58-
59-
- Replace `/path/to/cocalc/src/python/cocalc-api` with the absolute path to your cocalc-api directory.
60-
- Replace `http://localhost:5000` with your CoCalc instance URL (defaults to `https://cocalc.com` if not set).
61-
62-
### 4. Setup with Claude Desktop
44+
## Setup with Claude Desktop
6345

6446
Add to `~/.config/Claude/claude_desktop_config.json`:
6547

@@ -68,111 +50,62 @@ Add to `~/.config/Claude/claude_desktop_config.json`:
6850
"mcpServers": {
6951
"cocalc": {
7052
"command": "uv",
71-
"args": [
72-
"--directory",
73-
"/path/to/cocalc/src/python/cocalc-api",
74-
"run",
75-
"cocalc-mcp-server"
76-
],
77-
"env": {
78-
"COCALC_API_KEY": "sk-your-api-key-here",
79-
"COCALC_PROJECT_ID": "[UUID]",
80-
"COCALC_HOST": "http://localhost:5000"
81-
}
53+
"args": ["--directory", "/path/to/cocalc-api", "run", "cocalc-mcp-server"],
54+
"env": {"COCALC_API_KEY": "sk-your-api-key"}
8255
}
8356
}
8457
}
8558
```
8659

87-
**Important:**
88-
89-
- Replace `/path/to/cocalc/src/python/cocalc-api` with the absolute path to your cocalc-api directory.
90-
- Replace `http://localhost:5000` with your CoCalc instance URL (defaults to `https://cocalc.com` if not set).
91-
92-
### 5. Allow MCP Tools in Claude Code Settings
60+
## Allow Tools in Claude Code Settings
9361

94-
To automatically allow all CoCalc MCP tools without prompts, add this to `.claude/settings.json`:
62+
Add to `.claude/settings.json`:
9563

9664
```json
9765
{
9866
"allowedTools": ["mcp__cocalc__*"]
9967
}
10068
```
10169

102-
This wildcard pattern (`mcp__cocalc__*`) automatically allows:
70+
## Available Tools & Resources
10371

104-
- `mcp__cocalc__exec` - Execute shell commands
105-
- `mcp__cocalc__project_files` - Browse project files
106-
- Any future tools added to the MCP server
72+
The server automatically provides different tools based on your API key type:
10773

108-
## Features
74+
### Account-Scoped API Keys
10975

110-
### Tools
76+
**Tools:**
77+
- `projects_search(query="")` - Search and list your projects with collaborator info
11178

112-
- **`exec`** - Execute shell commands in the project
79+
**Resources:**
80+
- `cocalc://account-profile` - View your account info, settings, and preferences
11381

114-
```
115-
Tool: exec
116-
Params: command (required), args, bash, timeout, cwd
117-
Returns: {stdout, stderr, exit_code}
118-
```
82+
### Project-Scoped API Keys
11983

120-
- **`jupyter_execute`** - Execute code using Jupyter kernels
121-
```
122-
Tool: jupyter_execute
123-
Params: input (required), kernel (default: "python3"), history
124-
Returns: Formatted execution output (text, plots, errors, etc.)
125-
```
84+
**Tools:**
85+
- `exec(command)` - Execute shell commands in the project
86+
- `jupyter_execute(input, kernel="python3")` - Run code using Jupyter kernels
12687

127-
### Resources
88+
**Resources:**
89+
- `cocalc://project-files` - Browse the project directory structure
12890

129-
- **`project-files`** - Browse project files with filtering and pagination
130-
```
131-
URI: cocalc://project-files/{path}?glob=*.py&limit=100&recurse=true
132-
Returns: File listing with metadata
133-
```
91+
## API Keys
13492

135-
## Documentation
93+
Create API keys at:
94+
- **Account-scoped**: CoCalc Settings → API keys → Create API key
95+
- **Project-scoped**: Project Settings → API keys → Create API key
13696

137-
See [DEVELOPMENT.md](./DEVELOPMENT.md) for:
138-
139-
- Architecture and design principles
140-
- Detailed API specifications
141-
- Configuration options
142-
- Testing strategy
143-
- Future roadmap
144-
145-
## Directory Structure
146-
147-
```
148-
src/cocalc_api/mcp/
149-
├── README.md # This file
150-
├── DEVELOPMENT.md # Architecture & design documentation
151-
├── server.py # Main MCP server
152-
├── mcp_server.py # MCP instance and project client coordination
153-
├── __main__.py # Module entry point
154-
├── tools/
155-
│ ├── exec.py # Shell command execution tool
156-
│ └── __init__.py
157-
└── resources/
158-
├── file_listing.py # File listing resource
159-
└── __init__.py
160-
```
161-
162-
## Requirements
97+
## Security
16398

164-
- Python 3.10+
165-
- mcp>=1.0
166-
- httpx
167-
- pydantic (via mcp)
99+
- Never commit API keys to version control
100+
- Use restricted file permissions (600) on config files with API keys
101+
- Each server instance is isolated to its scope (account or project)
102+
- Commands execute with the permissions of your API key
168103

169-
## Security
104+
## Development
170105

171-
- API keys should never be committed to version control
172-
- Use restricted file permissions (600) on config files containing API keys
173-
- Each server instance is scoped to a single project
174-
- Commands execute with the permissions of the CoCalc project user
106+
See [DEVELOPMENT.md](./DEVELOPMENT.md) for architecture, design patterns, and adding new tools.
175107

176-
## Next Steps
108+
## References
177109

178-
See [DEVELOPMENT.md](./DEVELOPMENT.md#next-steps) for implementation roadmap and upcoming features.
110+
- [MCP Specification](https://modelcontextprotocol.io/)
111+
- [CoCalc API Documentation](https://github.com/sagemathinc/cocalc)

src/python/cocalc-api/src/cocalc_api/mcp/mcp_server.py

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,39 @@
22
CoCalc MCP (Model Context Protocol) Server - Central Coordination Module
33
44
This MCP server gives you direct access to a CoCalc project or account environment.
5+
The available tools and resources depend on your API key type (account-scoped or project-scoped).
56
6-
AVAILABLE TOOLS (actions you can perform):
7+
AVAILABLE TOOLS - PROJECT-SCOPED KEYS:
78
- exec: Run shell commands, scripts, and programs in the project
89
Use for: running code, data processing, build/test commands, git operations, etc.
910
- jupyter_execute: Execute code using Jupyter kernels (Python, R, Julia, etc.)
1011
Use for: interactive code execution, data analysis, visualization, scientific computing
1112
12-
AVAILABLE RESOURCES (information you can read):
13+
AVAILABLE TOOLS - ACCOUNT-SCOPED KEYS:
14+
- projects_search: Search for and list projects you have access to
15+
Use for: discovering projects, seeing collaborators, checking project states
16+
17+
AVAILABLE RESOURCES - PROJECT-SCOPED KEYS:
1318
- project-files: Browse the project file structure
1419
Use for: exploring what files exist, understanding project layout, locating files to work with
1520
16-
HOW IT WORKS:
17-
- You can use these tools and resources to understand, modify, and manage files in the project
18-
- The project runs in an Ubuntu Linux container with common development tools pre-installed
19-
- Commands execute with the permissions of the CoCalc project user
20-
- All operations are scoped to this single project
21+
AVAILABLE RESOURCES - ACCOUNT-SCOPED KEYS:
22+
- account-profile: View your account profile and settings
23+
Use for: checking personal info, account settings, preferences
2124
22-
WHEN TO USE WHICH:
23-
1. First, use project-files to explore and understand the project structure
24-
2. Then, use exec to run commands, edit files, run tests, etc.
25-
3. Use project-files again if you need to navigate to new directories
26-
4. Use exec for anything the project-files resource can't show (recursive listings, complex queries, etc.)
25+
HOW IT WORKS:
26+
- Account-scoped keys: Access your account information, manage projects, view profile
27+
- Project-scoped keys: Execute code, run commands, and manage files in a specific project
28+
- All operations are secure and scoped to what your API key authorizes
2729
2830
AUTHENTICATION & CONFIGURATION:
2931
Required environment variables (already set when this server is running):
3032
- COCALC_API_KEY: Your CoCalc API authentication token (account-scoped or project-scoped)
3133
- COCALC_HOST: (optional) Your CoCalc instance URL (defaults to https://cocalc.com)
34+
- COCALC_PROJECT_ID: (optional) Project ID for project-scoped keys
3235
33-
The server will validate your API key on startup and report whether it's account-scoped or project-scoped.
36+
The server will validate your API key on startup and automatically register the appropriate
37+
tools and resources based on whether it's account-scoped or project-scoped.
3438
"""
3539

3640
import os
@@ -279,13 +283,33 @@ def get_project_client(project_id: Optional[str] = None) -> Project:
279283
return client
280284

281285

282-
# Register tools and resources
283-
# This happens at module import time, auto-registering with the mcp instance
284-
from . import tools as tools_module # noqa: E402
285-
from . import resources as resources_module # noqa: E402
286+
def _register_tools_and_resources() -> None:
287+
"""Register tools and resources based on API key scope."""
288+
global _api_key_scope
289+
290+
_initialize_config()
291+
292+
# Determine which tools/resources to register based on API key scope
293+
if _api_key_scope and "account_id" in _api_key_scope:
294+
# Account-scoped key: register account-scoped tools/resources
295+
print("Registering account-scoped tools and resources...", file=sys.stderr)
296+
from .tools.projects_search import register_projects_search_tool
297+
from .resources.account_profile import register_account_profile_resource
298+
299+
register_projects_search_tool(mcp)
300+
register_account_profile_resource(mcp)
301+
302+
elif _api_key_scope and "project_id" in _api_key_scope:
303+
# Project-scoped key: register project-scoped tools/resources
304+
print("Registering project-scoped tools and resources...", file=sys.stderr)
305+
from .tools.exec import register_exec_tool
306+
from .tools.jupyter import register_jupyter_tool
307+
from .resources.file_listing import register_file_listing_resource
308+
309+
register_exec_tool(mcp)
310+
register_jupyter_tool(mcp)
311+
register_file_listing_resource(mcp)
286312

287-
tools_module.register_tools(mcp)
288-
resources_module.register_resources(mcp)
289313

290-
# Initialize configuration and validate API key at startup
291-
_initialize_config()
314+
# Initialize configuration and validate API key at startup, then register tools/resources
315+
_register_tools_and_resources()
Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
"""
22
CoCalc MCP Resources - Available Information
33
4-
Resources are read-only information you can access about the CoCalc project.
4+
Resources are read-only information you can access about the CoCalc project or account.
55
6-
Available Resources:
7-
- project-files: Browse and list files in the project directory structure
6+
Resources are dynamically registered based on API key scope:
87
9-
See mcp_server.py for overview of all available tools and resources, and guidance
10-
on when to use each one.
11-
"""
8+
PROJECT-SCOPED KEYS:
9+
- project-files: Browse and list files in the project directory structure
1210
11+
ACCOUNT-SCOPED KEYS:
12+
- account-profile: View account profile information
1313
14-
def register_resources(mcp) -> None:
15-
"""Register all resources with the given FastMCP instance."""
16-
from .file_listing import register_file_listing_resource
14+
See mcp_server.py for overview of all available tools and resources.
1715
18-
register_file_listing_resource(mcp)
16+
Note: Individual resource registration functions are imported directly by mcp_server.py.
17+
"""

0 commit comments

Comments
 (0)