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
4 changes: 2 additions & 2 deletions .github/workflows/code_quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ jobs:
os: ${{ matrix.os }}
python-version: ${{ matrix.python-version }}
ref: ${{inputs.tag}}
# The incremental output download feature doesn't run on Python 3.8, so test coverage is lower
cov-fail-under: "75"
# The incremental output download and mcp feature doesn't run on Python 3.8, so test coverage is lower
cov-fail-under: "74"
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Notable features include:
* A library of functions that implement AWS Deadline Cloud's Job Attachments functionality.
* A library of functions for creating a job submission UI within any content creation tool that supports Python 3.8+ based plugins and
the Qt GUI framework.
* A Model Context Protocol (MCP) server for AI assistant integration, enabling natural language interaction with AWS Deadline Cloud resources.

[cas]: https://en.wikipedia.org/wiki/Content-addressable_storage
[deadline-cloud]: https://docs.aws.amazon.com/deadline-cloud/latest/userguide/what-is-deadline-cloud.html
Expand Down Expand Up @@ -62,6 +63,11 @@ or if you want the optional gui dependencies:
$ pip install "deadline[gui]"
```

if you want the optional mcp dependencies:
```sh
$ pip install "deadline[mcp]"
```

## Usage

After installation it can then be used as a command line tool:
Expand Down Expand Up @@ -116,8 +122,6 @@ deadline config gui
```


Shared storage is possible with customer-managed fleets (CMF) but not service-managed fleets (SMF). See [shared storage][shared-storage] for more information.

## Job Bundles

A job bundle is one of the tools that you can use to define jobs for AWS Deadline Cloud. They group an [Open Job Description (OpenJD)][openjd] template with
Expand Down Expand Up @@ -308,6 +312,12 @@ Available modes:
- `USER`: Credentials with full queue-role permissions.
- `READ`: Credentials with read-only permissions for queue logs

## Model Context Protocol (MCP) Server

The AWS Deadline Cloud client includes an MCP server that enables AI assistants to interact with AWS Deadline Cloud resources through natural language. The MCP server uses the [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) for simplified tool registration while maintaining full protocol compliance.

See [MCP Guide](https://github.com/aws-deadline/deadline-cloud/blob/release/docs/mcp_guide.md) for more information.


## Code of Conduct

Expand Down
131 changes: 131 additions & 0 deletions docs/mcp_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# AWS Deadline Cloud MCP Server Guide

**MCP ([Model Context Protocol](https://modelcontextprotocol.io/docs/getting-started/intro))** is an open standard that enables AI assistants to securely connect to external data sources and tools. It acts a bridge that allows Large Language Models (LLMs) like Claude, GPT, or other AI assistants to interact with applications and services through natural language.

With the AWS Deadline Cloud MCP Server, you can use natural language for various Deadline Cloud workflows such as submitting a job, reading job/farm/queue information etc.

## User Guide

1. **Install the server**
```bash
pip install 'deadline[mcp]'
```
2. **Verify the MCP server command is available:**
```bash
deadline mcp-server --help
```
You should see:
```
Usage: deadline mcp-server [OPTIONS]

Start the AWS Deadline Cloud MCP (Model Context Protocol) server.

The MCP server provides LLM tools with access to AWS Deadline Cloud
operations through the Model Context Protocol. This allows AI assistants to
interact with Deadline Cloud services on your behalf.

The server will run until interrupted with Ctrl+C or Ctrl+D.
```
3. **Configure AWS credentials:**
- Standard AWS credentials (AWS Profiles, environment variables)
- Or Deadline Cloud monitor credentials:
```bash
deadline auth login
```
- Verify authentication status:
```bash
deadline auth status
```
4. **Configure your MCP client** to connect to the server
Add to your MCP configuration (e.g., `./settings/mcp.json`):
```json
{
"mcpServers": {
"deadline-cloud": {
"command": "deadline",
"args": ["mcp-server"],
"disabled": false,
"autoApprove": []
}
}
}
```
5. **Start having conversations** with your AI assistant about your rendering workflows

## Example prompts

```
- "List all my AWS Deadline Cloud farms"
- "Show me the queues in my farm"
- "List the jobs in my queue"
- "Submit the render job in /path/to/my-job-bundle"
- "Submit a job with priority 80 to my render queue"
- "Show me the status of job job-3a907bac684841f69fc344867ee166de"
- "Download output from job job-3a907bac684841f69fc344867ee166de"
- "Download output from step step-render in job job-3a907bac684841f69fc344867ee166de"
```

## Available Tools

The MCP server provides access to all allowlisted/configured Deadline Cloud API functions through automatic registration:

- `deadline_list_farms()`: List available farms
- `deadline_list_queues()`: List queues in a farm
- `deadline_list_jobs()`: List jobs in a queue
- `deadline_list_fleets()`: List fleets in a farm
- `deadline_list_storage_profiles_for_queue()`: List storage profiles for a queue

- `deadline_check_authentication_status()`: Check current authentication status

- `deadline_submit_job()`: Submit an Open Job Description job bundle to AWS Deadline Cloud
- `deadline_download_job_output()`: Download job output files from AWS Deadline Cloud


## Developer Guide

The MCP server exposes public Deadline Cloud operations as tools that AI assistants can call directly. Tools are defined in `config.py` where each entry maps a tool name to its corresponding function and parameters.

## Project Structure

```
src/deadline/mcp/
├── server.py # Main server with FastMCP setup and auto-registration
├── config.py # Tool configuration definitions
├── utils.py # Auto-registration utilities
└── tools/ # Tool modules
└── job.py # Job management tools (submit, download)
```

### Adding New MCP Tools

#### Step 1: Use public api operations

Prefer consistency with existing CLI patterns by using functions from the public API module `deadline.client.api.*` when available. Use direct boto3 calls when no wrapper exists or when the wrapper doesn't provide the needed functionality. Tools like `submit_job` and `download_job_output` are exceptions because they require job attachment functionality that are not available in the public API.

```python
# ✅ Good: Use existing public API
from deadline.client.api import list_farms, list_queues

# ❌ Bad: Don't use internal modules
from deadline.client._internal.some_module import internal_function
```

#### Step 2: Configure the MCP Tool

Add your new tool to the `API_TOOLS_CONFIG` in `src/deadline/mcp/config.py`:

```python
API_TOOLS_CONFIG: dict[str, ToolConfig] = {
# ... existing tools ...
"your_new_tool": {
"func": api.your_new_function, # Must be from deadline.client.api
"params": ["param1", "param2", "optional_param"], # List all parameters, or None if no params
},
}
```

#### Step 3: Test the Integration

1. **Unit Tests**: Add tests to `test/unit/deadline_mcp/test_mcp.py`
2. **Integration Tests**: Add tests to `test/integ/deadline_mcp/test_mcp_server_integration.py`
3. **Manual Testing**: Test with real MCP clients
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ gui = [
# If the version changes, update the version in deadline/client/ui/__init__.py
"PySide6-essentials >= 6.6,< 6.10",
]
mcp = [
"mcp >= 1.13.0",
]

[project.scripts]
deadline = "deadline.client.cli:main"
Expand Down Expand Up @@ -132,6 +135,7 @@ known-first-party = ["deadline"]
# XML, HTML, and terminal reports.
[tool.pytest.ini_options]
xfail_strict = true

addopts = [
"--durations=5",
"--cov=src/deadline",
Expand All @@ -147,6 +151,7 @@ markers = [
"integ: tests that run against AWS resources",
"docker: marks tests to be run only in a Docker environment",
"cross_account: tests that run against other aws accounts",
"asyncio: mark test as async",
]
# looponfailroots is deprecated, this removes the deprecation from the test output
filterwarnings = ["ignore::DeprecationWarning"]
Expand Down
3 changes: 3 additions & 0 deletions requirements-integ-testing.txt
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
deadline-cloud-test-fixtures == 0.18.*
# MCP (Model Context Protocol) library for MCP server integration tests
mcp >= 1.13.0
pytest-asyncio == 0.*
2 changes: 2 additions & 0 deletions requirements-testing.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ ruff == 0.13.*
moto == 5.*
jsondiff == 2.*
pyinstrument == 5.*
# MCP (Model Context Protocol) library for MCP unit tests
mcp >= 1.13.0; python_version >= '3.10'
1 change: 1 addition & 0 deletions src/deadline/_mcp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
70 changes: 70 additions & 0 deletions src/deadline/_mcp/registry.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

"""Tool registry and mapping definitions for MCP tools in Deadline Cloud."""

from typing import Any, Callable, List, Optional, TypedDict, Dict

from ..client import api
from .tools import job


class ToolDefinition(TypedDict):
"""Definition of a single MCP tool including its function and parameters."""

func: Callable[..., Any]
param_names: Optional[List[str]]


def get_tool_definition(tool_name: str) -> ToolDefinition:
"""Get the definition for a specific tool."""
if tool_name not in TOOL_REGISTRY:
raise ValueError(f"Tool '{tool_name}' not found in registry")
return TOOL_REGISTRY[tool_name]


def get_all_tool_names() -> List[str]:
"""Get all registered tool names."""
return list(TOOL_REGISTRY.keys())


TOOL_REGISTRY: Dict[str, ToolDefinition] = {
"list_farms": {
"func": api.list_farms,
"param_names": ["nextToken", "principalId", "maxResults"],
},
"list_queues": {
"func": api.list_queues,
"param_names": ["farmId", "principalId", "status", "nextToken", "maxResults"],
},
"list_jobs": {
"func": api.list_jobs,
"param_names": ["farmId", "queueId", "principalId", "nextToken", "maxResults"],
},
"list_fleets": {
"func": api.list_fleets,
"param_names": [
"farmId",
"principalId",
"displayName",
"status",
"nextToken",
"maxResults",
],
},
"list_storage_profiles_for_queue": {
"func": api.list_storage_profiles_for_queue,
"param_names": ["farmId", "queueId", "nextToken", "maxResults"],
},
"check_authentication_status": {
"func": api.check_authentication_status,
"param_names": None,
},
"submit_job": {
"func": job.submit_job,
"param_names": None,
},
"download_job_output": {
"func": job.download_job_output,
"param_names": None,
},
}
13 changes: 13 additions & 0 deletions src/deadline/_mcp/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

from mcp.server.fastmcp import FastMCP

from .utils import register_api_tools

app = FastMCP("deadline-cloud")

register_api_tools(app, prefix="deadline_")


def main():
app.run()
1 change: 1 addition & 0 deletions src/deadline/_mcp/tools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Loading
Loading