Deluge MCP Server# Deluge MCP Server# Deluge MCP Server
A Model Context Protocol (MCP) server for managing Deluge torrent client. Built with FastMCP v2 for production-ready performance.
FeaturesA Model Context Protocol (MCP) server for managing Deluge BitTorrent client via command-line interface.A Model Context Protocol (MCP) server that provides AI assistants with tools to
-
🚀 Two MCP Tools:interact with and control the Deluge BitTorrent client. This server enables AI
-
get_running_torrents- Get information about all running torrents -
add_torrent_magnet- Add new torrents via magnet URLs## Featuresagents to manage torrents through a standardized interface.
-
-
🔄 Async Operations - Non-blocking deluge-console commands
-
🌐 HTTP Transport - Remote access via Server-Sent Events (SSE)
-
🔧 System Service - Auto-starting systemd daemon
-
📊 Comprehensive Logging - All logs available via
journalctl- Get Running Torrents: List all active torrents with detailed information## Features
Requirements- Add Torrent via Magnet: Add new torrents using magnet URLs
-
OS: Ubuntu/Debian Linux- Async Operations: All commands run asynchronously via subprocess- Get Running Torrents: Query information about all active torrents
-
Python: 3.12+
-
Deluge:
deluge-consolemust be installed- HTTP Streamable Transport: Supports both stdio and SSE (Server-Sent Events)- Add Torrents: Add new torrents using magnet URLs -
Permissions: sudo access for service installation
-
CLI Management: Easy installation and management via command-line interface- Async Operations: All operations run asynchronously using asyncio
Quick Start
- Systemd Service: Can be installed as a persistent system service (Ubuntu/Debian)- HTTP Streamable Transport: Run as an HTTP server for easy integration
1. Install Deluge Console
sudo apt-get install deluge-console
```- **Root Service**: Runs as systemd service with root privileges for reliability- **Systemd Service**: Install as a persistent system service (Ubuntu)
### 2. Install Deluge MCP
```bash
pip install deluge-mcp## Prerequisites## Prerequisites
3. Install as System Service
deluge-mcp install
```- Deluge BitTorrent client with `deluge-console` installed
The service will be available at `http://localhost:58880/mcp` and will auto-start on boot.- For service installation: - Python 3.10 or higher
## Usage - Ubuntu/Debian system with systemd- Deluge BitTorrent client with `deluge-console` installed
### Service Management - Root/sudo access- For service installation:
```bash
# Install daemon service - Running deluged service (recommended) - Ubuntu/Debian system with systemd
deluge-mcp install --verbose
- Root/sudo access
# Check service status
deluge-mcp status --logs### Install Deluge - Running deluged service (recommended)
# Uninstall service
deluge-mcp uninstall
```bash### Install Deluge
# View logs
sudo journalctl -u deluge-mcp -f# Ubuntu/Debian
sudo apt-get update```bash
Direct Execution
# Run with stdio transport (for MCP clients)
deluge-mcp runsudo apt-get update
# Run with HTTP transport (for remote access)# Start deluged servicesudo apt-get install deluged deluge-console
deluge-mcp run --transport http --port 8080 --host 0.0.0.0
```sudo systemctl enable deluged
### MCP Client Usagesudo systemctl start deluged# Start deluged service
```python
import asyncio```sudo systemctl enable deluged
from fastmcp import Client
sudo systemctl start deluged
async def demo():
async with Client("http://localhost:58880/mcp") as client:## Installation```
# Get running torrents
torrents = await client.call_tool("get_running_torrents")
print(torrents)
### Development Installation## Installation
# Add a torrent
result = await client.call_tool(
"add_torrent_magnet",
{"magnet_url": "magnet:?xt=urn:btih:..."}```bash1. Clone the repository:
)
print(result)# Clone the repository```bash
asyncio.run(demo())git clone https://github.com/abi-jey/deluge-mcp.gitgit clone https://github.com/abi-jey/deluge-mcp.git
cd deluge-mcpcd deluge-mcp
Architecture
### Service Configuration
- **Service Location**: `/opt/deluge-mcp/venv` (dedicated Python environment)# Create and activate virtual environment
- **Transport**: HTTP with Server-Sent Events (SSE)
- **Port**: 58880 (configurable)python3 -m venv .venv2. Install dependencies using Poetry:
- **Logging**: systemd journal (`journalctl -u deluge-mcp`)
- **Auto-restart**: Yes, with 10-second delaysource .venv/bin/activate```bash
- **Security**: Hardened with `ProtectSystem`, `ProtectHome`, `NoNewPrivileges`
poetry install
### FastMCP v2 Benefits
- **Clean API**: Simple `@mcp.tool()` decorators# Install in development mode```
- **Automatic Transport**: Handles stdio/HTTP seamlessly
- **Type Safety**: Full Python type hintspip install -e .
- **Error Handling**: Exceptions automatically converted to MCP errors
- **Production Ready**: Built-in security and reliability features```3. Activate the virtual environment:
## CLI Reference```bash
```bash### Production Installation as System Servicepoetry shell
deluge-mcp --help # Show help
deluge-mcp --version # Show version```
deluge-mcp install [--verbose] # Install systemd service
deluge-mcp uninstall [--verbose] # Remove systemd service To install as a systemd service that survives restarts:
deluge-mcp status [--logs] # Check service status
deluge-mcp run [OPTIONS] # Run server directly## Usage
# Run command options:```bash
# --transport {stdio,http} # Transport mode (default: stdio)
# --port INTEGER # HTTP port (default: 58880)# Install the package first (in user environment)### Running the MCP Server
# --host TEXT # Bind address (default: 0.0.0.0)
# --verbose # Enable debug loggingpip install .
Run the server directly in HTTP streamable mode:
System Integration
Install as system service (MUST use sudo)
Systemd Service
The installed service includes:sudo deluge-mcp install```bash
-
Dependencies: Waits for network and deluge daemon
-
Logging: All output captured in systemd journal```deluge-mcp run
-
Security: Minimal privileges with filesystem protection
-
Reliability: Auto-restart on failures```
-
Root Access: Required for system-wide torrent management
What the installation does:
Network Access
-
Local:
http://localhost:58880/mcp1. Verifies root privileges and Ubuntu/Debian systemOr with a custom port: -
Remote:
http://YOUR_IP:58880/mcp(if firewall allows) -
Protocols: HTTP with SSE, stdio for local clients2. Checks for
deluge-consoleavailability
Troubleshooting3. Creates a dedicated virtual environment at `/opt/deluge-mcp/venv````bash
Service Issues4. Installs deluge-mcp and all dependencies in the service venvdeluge-mcp run --port 8080
# Check service status5. Creates log directory at `/var/log/deluge-mcp````
sudo systemctl status deluge-mcp
6. Creates systemd service file configured for:
# View recent logs
sudo journalctl -u deluge-mcp -n 50 - Running as rootThe server will start and listen for MCP connections over HTTP.
# Follow logs in real-time - Using the dedicated venv
sudo journalctl -u deluge-mcp -f
- SSE transport on port 58880### Available MCP Tools
# Restart service
sudo systemctl restart deluge-mcp - Comprehensive logging to files and systemd journal
- Auto-restart on failureOnce the server is running, AI assistants can use the following tools:
Common Problems
- Enables and starts the service
Service fails to start:
-
Ensure deluge-console is installed:
which deluge-console#### 1.get_running_torrents -
Check Python version:
python3 --version(needs 3.12+) -
Verify installation:
deluge-mcp status --verbose## Usage
Permission denied:Get information about all torrents currently in Deluge.
-
Service runs as root for system access
-
Installation requires sudo for system directories### Running the Server
-
Use
deluge-mcp install(notsudo deluge-mcp install)
Returns: Detailed information including torrent names, states, progress,
Port conflicts:
-
Default port 58880 may be in use#### Stdio Mode (default)download/upload speeds, seeds, peers, and ETA.
-
Change with:
deluge-mcp run --port 8080 -
Service port configured in systemd file```bash
Developmentpython -m deluge_mcp.mainExample output:
Local Development```
git clone https://github.com/abi-jey/deluge-mcp# Or using the CLIName: Ubuntu 22.04 LTS
cd deluge-mcp
pip install -e .deluge-mcp runID: abc123...
deluge-mcp run --verbose
``````State: Downloading
### Testing ToolsDown Speed: 5.2 MB/s
```bash
# Test individual tools#### HTTP Streamable Mode (SSE)Up Speed: 1.1 MB/s
fastmcp run src/deluge_mcp/main.py:mcp --transport http --port 8080
```bashProgress: 45.3%
# Verify MCP compatibility
fastmcp validate src/deluge_mcp/main.py:mcp# Development with default port (58880)Seeds: 124 (200)
python -m deluge_mcp.main --transport sse --port 58880Peers: 45 (100)
License
ETA: 00:15:23
MIT License - see LICENSE file for details.
Or using the CLI```
Contributing
deluge-mcp run --transport sse --port 58880
-
Fork the repository
-
Create a feature branch#### 2.
add_torrent_magnet -
Make your changes
-
Add tests if applicable # Custom port
-
Submit a pull request
deluge-mcp run --transport sse --port 8080Add a new torrent to Deluge using a magnet URL.
Links
- **Repository**: https://github.com/abi-jey/deluge-mcp
- **FastMCP Framework**: https://gofastmcp.com/**Parameters**:
- **Model Context Protocol**: https://modelcontextprotocol.io/
- **Deluge BitTorrent Client**: https://deluge-torrent.org/### Managing the Service- `magnet_url` (string): The magnet URL starting with "magnet:"
```bash**Returns**: Confirmation message with the result of the operation.
# Start the service
sudo systemctl start deluge-mcp**Example**:
```python
# Stop the serviceadd_torrent_magnet("magnet:?xt=urn:btih:...")
sudo systemctl stop deluge-mcp# Returns: "Torrent added successfully. Output: ..."
Check service status
sudo systemctl status deluge-mcp### CLI Commands
Restart the serviceThe deluge-mcp command provides several subcommands for managing the server:
sudo systemctl restart deluge-mcp
Install as Daemon Service
Disable auto-start on boot
sudo systemctl disable deluge-mcpInstall deluge-mcp as a systemd service that starts automatically on boot:
Enable auto-start on boot```bash
sudo systemctl enable deluge-mcpdeluge-mcp install
### Viewing LogsOptions:
- `--port`, `-p`: Specify the HTTP server port (default: 8080)
The service provides multiple logging options:- `--force`, `-f`: Force installation on non-Ubuntu systems
```bash**System Requirements Check**:
# Application logs (stdout)- Verifies the system is running Ubuntu
sudo tail -f /var/log/deluge-mcp/deluge-mcp.log- Checks that `deluge-console` is installed and accessible
- Creates a systemd service file
# Error logs (stderr)- Enables and starts the service
sudo tail -f /var/log/deluge-mcp/deluge-mcp-error.log
**Example**:
# Systemd journal```bash
sudo journalctl -u deluge-mcp -f# Install with default settings
deluge-mcp install
# All logs since last boot
sudo journalctl -u deluge-mcp -b# Install on custom port
deluge-mcp install --port 9090
# Last 100 lines
sudo journalctl -u deluge-mcp -n 100# Force install on non-Ubuntu system (not recommended)
```deluge-mcp install --force
```
## Available Tools
#### Check Service Status
### 1. `get_running_torrents`
Check if the daemon service is running:
Get information about all torrents currently running in Deluge.
```bash
**No parameters required.**deluge-mcp status
```
**Returns**: Detailed information including:
- Torrent namesThis shows whether the service is active and displays detailed status information.
- States (downloading, seeding, paused, etc.)
- Download/upload speeds#### Uninstall Daemon Service
- Progress percentage
- Seeds and peersRemove the systemd service:
- ETA (estimated time remaining)
```bash
**Example output**:deluge-mcp uninstall
Name: Ubuntu 22.04 LTS Desktop
ID: abc123def456...This will:
State: Downloading- Stop the running service
Down Speed: 5.2 MB/s- Disable automatic startup
Up Speed: 1.1 MB/s- Remove the service file
Progress: 45.3%- Reload systemd configuration
Seeds: 124 (200)
Peers: 45 (100)#### Managing the Service
ETA: 00:15:23
Size: 3.6 GB / 8.0 GBAfter installation, you can manage the service using standard systemd commands:
Ratio: 0.25
# Check status
### 2. `add_torrent_magnet`sudo systemctl status deluge-mcp
Add a new torrent to Deluge using a magnet URL.# Stop the service
sudo systemctl stop deluge-mcp
**Parameters**:
- `magnet_url` (string, required): The magnet URL starting with "magnet:"# Start the service
sudo systemctl start deluge-mcp
**Returns**: Confirmation message with the result of the operation.
# Restart the service
**Example**:sudo systemctl restart deluge-mcp
```
Tool: add_torrent_magnet# View logs
Input: {sudo journalctl -u deluge-mcp -f
"magnet_url": "magnet:?xt=urn:btih:..."```
}
Output: "Torrent added successfully!## Architecture
Output: Torrent added to download list."### Async Subprocess Execution
```
All Deluge operations run asynchronously using Python's `asyncio` module:
## Architecture
```python
### Componentsasync def run_deluge_command(command: str) -> str:
process = await asyncio.create_subprocess_shell(
1. **MCP Server (`main.py`)**: f'deluge-console "{command}"',
- Handles MCP protocol communication stdout=asyncio.subprocess.PIPE,
- Supports stdio and SSE transports stderr=asyncio.subprocess.PIPE,
- Registers and executes tools )
- Comprehensive logging for debugging stdout, stderr = await process.communicate()
# ...
2. **Deluge Integration**:```
- Uses `deluge-console` command-line interface
- Runs commands asynchronously via `asyncio.create_subprocess_exec`This ensures the MCP server remains responsive even during long-running operations.
- Parses command output and returns structured data
- Example commands:### Transport Mode
- Get torrents: `deluge-console "info"`
- Add magnet: `deluge-console "add <magnet_url>"`The server uses FastMCP's HTTP streamable transport:
3. **CLI (`cli.py`)**:```python
- Built with Typer frameworkapp.run(transport="streamable-http")
- Handles service installation with full venv setup```
- Validates system requirements (root, Ubuntu, deluge-console)
- Configures logging and service parametersThis allows AI assistants to connect to the server over HTTP and stream responses
efficiently.
### Service Architecture
### Command Execution
**Production Service Setup:**
- **Location**: `/opt/deluge-mcp/`The server executes commands by invoking `deluge-console` as a subprocess:
- **Virtual Environment**: `/opt/deluge-mcp/venv/`
- **Logs**: `/var/log/deluge-mcp/`- **Get torrents**: `deluge-console "info"`
- `deluge-mcp.log`: Standard output- **Add magnet**: `deluge-console "add <magnet_url>"`
- `deluge-mcp-error.log`: Error output
- **Port**: 58880 (SSE transport)This approach ensures compatibility with existing Deluge installations and
- **User**: rootdoesn't require direct API integration.
- **Transport**: SSE (Server-Sent Events)
## Development
**Why Root?**
### Project Structure
The service runs as root to:
- Ensure reliable access to Deluge daemon```
- Manage system-wide service dependenciesdeluge-mcp/
- Write to system log directories├── src/
- Survive system restarts with proper permissions│ └── deluge_mcp/
│ ├── main.py # MCP server and tools
**Security Hardening:**│ └── cli.py # CLI interface
├── pyproject.toml # Dependencies and config
The systemd service includes:├── README.md # This file
- `NoNewPrivileges=true`: Prevents privilege escalation└── LICENSE # License information
- `PrivateTmp=true`: Isolated /tmp directory```
- Automatic restart on failure
- Proper working directory isolation### Adding New Tools
### Async Command ExecutionTo add a new MCP tool, define an async function in `main.py` and decorate it
with `@app.tool()`:
All Deluge operations run asynchronously using Python's `asyncio`:
```python
```python@app.tool()
async def run_deluge_command(command: str) -> dict[str, Any]:async def my_new_tool(param: str) -> str:
process = await asyncio.create_subprocess_exec( """
"deluge-console", Description of what the tool does.
command,
stdout=asyncio.subprocess.PIPE, Args:
stderr=asyncio.subprocess.PIPE, param: Description of the parameter
)
stdout, stderr = await process.communicate() Returns:
# Process results... Description of the return value
``` """
output = await run_deluge_command(f"some-command {param}")
This ensures the MCP server remains responsive during long-running operations. return output
```
## Troubleshooting
### Running Tests
### Service Not Starting
```bash
1. Check service status:poetry run pytest
```bash```
sudo systemctl status deluge-mcp
```## Security Considerations
2. View recent logs:- The daemon service runs with user-level permissions (not root)
```bash- `deluge-console` commands are executed through subprocess with proper escaping
# Check application logs- Magnet URLs are validated before processing
sudo tail -n 100 /var/log/deluge-mcp/deluge-mcp.log- Service installation requires sudo privileges only for systemd operations
# Check error logs## Troubleshooting
sudo tail -n 100 /var/log/deluge-mcp/deluge-mcp-error.log
### deluge-console not found
# Check systemd journal
sudo journalctl -u deluge-mcp -n 100Ensure Deluge is installed:
``````bash
sudo apt-get install deluge-console
3. Verify deluge-console is accessible:which deluge-console # Should return a path
```bash```
which deluge-console
deluge-console info### Permission errors during daemon installation
```
The installation requires sudo access to create systemd service files. Make sure
4. Test the service venv:your user has sudo privileges.
```bash
sudo /opt/deluge-mcp/venv/bin/python -c "import deluge_mcp; print('OK')"### Service fails to start
```
Check the service logs:
### Installation Issues```bash
sudo journalctl -u deluge-mcp -n 50
**"Must be run as root" error:**```
```bash
# Use sudoCommon issues:
sudo deluge-mcp install- Deluge daemon not running
```- Python environment not properly configured
- Port conflicts
**"deluge-console not found" error:**
```bash### Ubuntu check fails
# Install deluge
sudo apt-get updateThe daemon installation is designed for Ubuntu systems with systemd. If you're
sudo apt-get install deluge-consoleon a different Linux distribution, you can use `--force` flag, but you may need
to manually adapt the service configuration.
# Verify installation
which deluge-console## Contributing
```
Contributions are welcome! Please feel free to submit a Pull Request.
**"Not supported on this system" error:**
- Only Ubuntu/Debian systems are supported## License
- Check your OS: `cat /etc/os-release`
See the [LICENSE](LICENSE) file for details.
### Permission Issues
## Authors
The service runs as root, but if you have permission issues:
- abi_jey (git@public.abja.dev)
```bash
# Verify service venv ownership## Links
sudo ls -la /opt/deluge-mcp/
- [Model Context Protocol](https://modelcontextprotocol.io/)
# Verify log directory ownership- [FastMCP](https://github.com/jlowin/fastmcp)
sudo ls -la /var/log/deluge-mcp/- [Deluge BitTorrent Client](https://deluge-torrent.org/)
- [Typer CLI Framework](https://typer.tiangolo.com/)
# Recreate if neededMCP server to automate deluge
sudo rm -rf /opt/deluge-mcp /var/log/deluge-mcp
sudo deluge-mcp install
```
### Connection Issues
Make sure Deluge daemon is running:
```bash
# Check if deluged is running
ps aux | grep deluged
sudo systemctl status deluged
# Start deluged if needed
sudo systemctl start deluged
# Enable auto-start
sudo systemctl enable deluged
```
### Port Conflicts
If port 58880 is already in use:
```bash
# Check what's using the port
sudo lsof -i :58880
sudo netstat -tulpn | grep 58880
# Edit service file to use different port
sudo nano /etc/systemd/system/deluge-mcp.service
# Change: --port 58880 to your desired port
# Reload and restart
sudo systemctl daemon-reload
sudo systemctl restart deluge-mcp
```
### Debug Logging
To enable DEBUG level logging:
1. Edit the source files to change logging level:
```python
# In main.py or cli.py
logging.basicConfig(level=logging.DEBUG, ...)
```
2. Reinstall the service:
```bash
sudo deluge-mcp uninstall
sudo deluge-mcp install
```
3. Or modify the systemd service temporarily:
```bash
sudo systemctl edit deluge-mcp
# Add: Environment="PYTHONUNBUFFERED=1"
sudo systemctl restart deluge-mcp
```
## Configuration
### Service Configuration
Key configuration values are defined in `cli.py`:
```python
SERVICE_PORT = 58880 # Default port for SSE transport
SERVICE_VENV_PATH = Path("/opt/deluge-mcp/venv") # Service venv
SERVICE_LOG_PATH = Path("/var/log/deluge-mcp") # Log directory
```
To change these, edit `src/deluge_mcp/cli.py` before installation.
### Deluge Configuration
The server uses default deluge-console behavior. Configure Deluge connection:
**System-wide (for root service):**
```bash
# Configuration file
/var/lib/deluged/.config/deluge/console.conf
```
**User-specific (for development):**
```bash
# Configuration file
~/.config/deluge/console.conf
```
### Transport Modes
**Stdio (Standard Input/Output):**
- Default mode
- Suitable for local testing
- Direct communication via stdin/stdout
**SSE (Server-Sent Events):**
- HTTP-based communication
- Runs on port 58880 by default
- Suitable for production deployment
- Allows remote MCP client connections
## Development
### Project Structure
```
deluge-mcp/
├── src/
│ └── deluge_mcp/
│ ├── __init__.py
│ ├── main.py # MCP server and tools
│ └── cli.py # CLI interface
├── pyproject.toml # Dependencies and config
├── README.md # This file
└── LICENSE # License information
```
### Adding New Tools
To add a new MCP tool:
1. Add the tool to the `list_tools()` function:
```python
Tool(
name="my_new_tool",
description="Description of what the tool does",
inputSchema={
"type": "object",
"properties": {
"param": {
"type": "string",
"description": "Parameter description",
}
},
"required": ["param"],
},
)
```
2. Handle the tool in `call_tool()`:
```python
elif name == "my_new_tool":
param = arguments.get("param", "")
result = await run_deluge_command(f"some-command {param}")
# Return TextContent with result
```
### Testing Locally
```bash
# Activate venv
source .venv/bin/activate
# Run in stdio mode for testing
python -m deluge_mcp.main
# Or run in SSE mode
python -m deluge_mcp.main --transport sse --port 58880
# Test with curl
curl http://localhost:58880/sse
```
## Uninstalling
To completely remove the service:
```bash
# Uninstall the service (requires sudo)
sudo deluge-mcp uninstall
# Optionally remove venv and logs
sudo rm -rf /opt/deluge-mcp /var/log/deluge-mcp
```
## Contributing
Contributions are welcome! Please:
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Submit a pull request
## License
See the [LICENSE](LICENSE) file for details.
## Authors
- abi_jey (git@public.abja.dev)
## Links
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)
- [Deluge BitTorrent Client](https://deluge-torrent.org/)
- [Typer CLI Framework](https://typer.tiangolo.com/)
- [Repository](https://github.com/abi-jey/deluge-mcp)
Metadata
Release files for deluge-mcp 0.2.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| deluge_mcp-0.2.4.tar.gz | 24.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| deluge_mcp-0.2.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.4 kB
Release files / deluge_mcp-0.2.4.tar.gz
| Download URL | deluge_mcp-0.2.4.tar.gz |
|---|---|
| Size | 24.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
85852b310a1ba034b9bda393073fb74ece8aa951e9f54630af2e2d13fdbf44aa
|
|
BLAKE2b-256 checksum How to use checksums |
9e584c969ece36a5718f0cac7f55c12d55a5b1bac237cd83421cd076d0800b09
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.2 CPython/3.12.3 Linux/6.14.0-33-generic
|
Release files / deluge_mcp-0.2.4-py3-none-any.whl
| Download URL | deluge_mcp-0.2.4-py3-none-any.whl |
|---|---|
| Size | 19.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
788b0863d995ca5510accc378f2492e0b4bd48347d822d27b001c47b970ccaaa
|
|
BLAKE2b-256 checksum How to use checksums |
302c16d980b487a6b662756e41663c5dfa14749befc74ab20cf7d2d6672377b7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/2.1.2 CPython/3.12.3 Linux/6.14.0-33-generic
|