Skip to main content
Glama
jgalluzzi
by jgalluzzi

slskd MCP

A small, dependency-light Model Context Protocol (MCP) server for controlling an existing slskd instance.

It gives an MCP-compatible agent three tools:

  • search_music — run a Soulseek search and return peer/file metadata.

  • queue_download — queue one exact result after an explicit rights confirmation.

  • list_downloads — inspect current and completed transfers.

This project does not implement the Soulseek protocol. It communicates with the HTTP API exposed by your own slskd server.

IMPORTANT

Use this software only to obtain files you own, public-domain or freely licensed material, or files you otherwise have permission to download. You are responsible for complying with copyright law and the rules that apply where you live.

Requirements

  • A working slskd instance connected to the Soulseek network.

  • A slskd API key with the readwrite role.

  • Node.js 18 or newer, or PowerShell 7 or newer.

  • An MCP-compatible client such as Codex.

Related MCP server: Soulseek MCP

Repository contents

File

Purpose

server.mjs

Portable Node.js MCP server.

server.ps1

Dependency-free PowerShell MCP server.

package.json

Node.js scripts and package metadata.

queue_existing_flac.ps1

Experimental helper that evaluates stored searches.

queue_new_flac.ps1

Experimental helper for throttled searches and FLAC selection.

bulk_flac.ps1

Early bulk-search prototype; use conservative settings.

The batch helpers are operational examples, not generic MCP tools. Review their matching rules, limits, and local state before using them with your own tracklist.

1. Configure slskd

Add a dedicated API key to slskd.yml. API keys must be between 16 and 255 characters.

web:
  port: 5030
  ip_address: "0.0.0.0"
  authentication:
    disabled: false
    username: "change-this-dashboard-username"
    password: "change-this-dashboard-password"
    api_keys:
      mcp:
        key: "replace-with-a-long-random-secret"
        role: readwrite
        cidr: "127.0.0.1/32,::1/128"

Generate a 32-byte secret with PowerShell:

[Convert]::ToHexString(
  [Security.Cryptography.RandomNumberGenerator]::GetBytes(32)
)

Restart slskd after changing its configuration.

CIDR considerations

The loopback-only CIDR above is appropriate when the MCP server runs on the same host as slskd or connects through an SSH tunnel.

With Docker, requests forwarded from the host may appear to originate from the Docker bridge gateway, such as 172.17.0.1. Obtain the actual gateway with:

docker inspect slskd --format '{{range .NetworkSettings.Networks}}{{.Gateway}}{{end}}'

If required, add that exact address as a /32 entry. Avoid unrestricted API keys, especially when slskd is exposed over plain HTTP.

2. Set environment variables

Variable

Required

Default

Description

SLSKD_API_KEY

Yes

Dedicated slskd readwrite API key.

SLSKD_URL

No

http://localhost:5030

Base URL of the slskd web/API service.

PowerShell:

$env:SLSKD_URL = "http://localhost:5030"
$env:SLSKD_API_KEY = "your-api-key"

POSIX shell:

export SLSKD_URL="http://localhost:5030"
export SLSKD_API_KEY="your-api-key"

Do not commit API keys, passwords, .env files, or populated slskd configuration files.

3. Configure the MCP client

Clone this repository and use an absolute path in your MCP configuration.

Node.js

[mcp_servers.slskd]
command = "node"
args = ["/absolute/path/to/slskd-mcp/server.mjs"]
env_vars = ["SLSKD_URL", "SLSKD_API_KEY"]

Windows example:

[mcp_servers.slskd]
command = "node"
args = ["C:\\path\\to\\slskd-mcp\\server.mjs"]
env_vars = ["SLSKD_URL", "SLSKD_API_KEY"]

PowerShell 7

[mcp_servers.slskd]
command = "pwsh"
args = ["-NoProfile", "-File", "/absolute/path/to/slskd-mcp/server.ps1"]
env_vars = ["SLSKD_URL", "SLSKD_API_KEY"]

Restart the MCP client after changing its configuration or persistent environment variables.

Remote slskd over SSH

For a slskd instance on another machine, an SSH tunnel keeps the API off the public internet:

ssh `
  -N `
  -o ServerAliveInterval=20 `
  -o ServerAliveCountMax=3 `
  -o TCPKeepAlive=yes `
  -o Compression=no `
  -o MACs=hmac-sha2-256-etm@openssh.com `
  -L 5030:127.0.0.1:5030 `
  root@208.68.38.142

Run this in a dedicated PowerShell window and keep it open. No output after login is normal: -N tells SSH to create the tunnel without opening a remote shell. Configure SLSKD_URL=http://localhost:5030.

If the host address or SSH account changes, replace root@208.68.38.142.

Usage

Example agent prompts:

Search Soulseek for an authorized Creative Commons release by Artist Name.
Do not download anything yet.
Show the best unlocked FLAC matches with free upload slots and short queues.
I confirm I own this release. Queue the exact selected result.

Search and download are intentionally separate. queue_download requires rights_confirmed: true.

Search and load guidance

Soulseek searches are live network operations, not catalog lookups. Results vary with peer availability and may take several seconds.

For small servers, particularly instances with around 1 GB of memory:

  • Keep concurrent searches low.

  • Process one batch completely before starting another.

  • Start with batches of 5–10 searches.

  • Avoid printing entire raw response collections through the MCP client.

  • Prefer compact result limits and exact local filtering.

  • Reuse completed searches instead of immediately repeating them.

A green/completed search in the slskd dashboard means the search ended; it does not mean a file was downloaded.

Development

No third-party Node packages are required.

npm run check
npm start

The server communicates over newline-delimited JSON-RPC on standard input/output. Application logs and diagnostic text must not be written to standard output because that would corrupt the MCP transport.

Troubleshooting

401 Unauthorized

  • Confirm SLSKD_API_KEY contains the current key.

  • Confirm the key has the readwrite role.

  • Verify its CIDR includes the address slskd sees, including a Docker bridge gateway when applicable.

  • Restart the MCP client after changing persistent environment variables.

Connection refused on localhost:5030

  • Confirm slskd is running and listening on port 5030.

  • If using SSH, confirm the tunnel process is still running.

  • Check docker ps, docker logs slskd, and ss -lntp | grep ':5030' on the server.

First check slskd locally on the VPS:

docker ps --filter name=slskd
curl -I --max-time 10 http://127.0.0.1:5030
docker logs --tail 30 slskd

Then, from Windows, verify the forwarded endpoint:

Invoke-WebRequest http://localhost:5030 -UseBasicParsing

If the VPS check succeeds but the Windows check fails, stop the old tunnel with Ctrl+C in its PowerShell window and start it again using the command in the Remote slskd over SSH section. Do not start new search batches until the tunnel works and slskd reports Connected, LoggedIn.

SSH tunnel reports message authentication code incorrect

This means the SSH connection was corrupted or interrupted; it is not an slskd API authentication error. Close the failed SSH session and reconnect. The tunnel command above disables compression, selects a modern encrypt-then-MAC algorithm, and enables keepalives to detect broken connections promptly.

If it continues:

  • Check the VPS console for network pressure, reboots, or SSH daemon errors.

  • Try the connection from a different network to rule out a faulty middlebox.

  • Update the OpenSSH client and server.

  • Run ssh -vvv root@208.68.38.142 for diagnostic output, taking care not to share private keys, credentials, or other sensitive output.

address already in use for [::]:5030

Some Linux environments treat an IPv6 listener as dual-stack, causing it to conflict with an IPv4 listener. Configure only one address:

web:
  port: 5030
  ip_address: "0.0.0.0"

Downloads fail while searches still appear

Check GET /api/v0/server or the slskd dashboard. slskd must report Connected, LoggedIn before it can resolve a peer and enqueue a download. Connected, LoggingIn is not sufficient.

slskd repeatedly disconnects or times out

  • Stop submitting new searches.

  • Allow queued searches to complete or cancel them.

  • Wait for slskd to reconnect and reach Connected, LoggedIn.

  • Resume with a smaller batch size.

Security notes

  • Treat the API key like a password.

  • Prefer loopback access plus SSH tunneling for remote instances.

  • Do not expose port 5030 publicly without HTTPS, authentication, firewalling, and a carefully restricted CIDR.

  • Use a dedicated API key rather than reusing dashboard or Soulseek credentials.

  • Keep Soulseek credentials in slskd; this MCP server does not need them.

License

This project is dedicated to the public domain under CC0 1.0 Universal. You may copy, modify, distribute, and use it for any purpose, including commercially, without asking permission.

CC0 applies only to material owned by this project's contributors. slskd, Soulseek, and other third-party software or content retain their respective licenses and rights.

Available Tools

3 tools
list_downloadsA

List current and completed slskd downloads.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description conveys that this is a read-only enumeration and scopes it to 'current and completed' downloads, which covers the core behavior. However, with no annotations and no output schema, it does not disclose ordering, whether failed or queued items are excluded, or what fields the returned list contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. Every word contributes to defining the tool's operation and scope.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read-only list tool, the description is mostly sufficient to invoke it correctly. The main gaps are the absence of an output schema and the lack of explicit detail about which download statuses are included, but the simplicity of the tool keeps these gaps minor.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters and the input schema is an empty object, so the schema already covers all invocation needs. The description correctly adds no parameter-specific detail, and the zero-parameter baseline of 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb ('List') and a concrete resource ('current and completed slskd downloads'). It also distinguishes itself from sibling tools search_music and queue_download, which handle searching and enqueueing rather than enumerating existing downloads.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no explicit guidance about when to use this tool versus search_music or queue_download. No prerequisites, exclusion conditions, or alternative routing are mentioned; the appropriate use is only implied by the verb 'List'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

queue_downloadB

Queue one exact Soulseek result in slskd. Requires explicit confirmation that the user is authorized to download it.

ParametersJSON Schema
NameRequiredDescriptionDefault
sizeYes
filenameYes
usernameYes
rights_confirmedYesTrue only after the user confirms they own or have permission to obtain this file.

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the behavioral burden, but it mostly restates the rights_confirmed parameter requirement already present in the schema. It does not disclose side effects, what happens after queuing, failure conditions, or output behavior, so it adds little beyond the structured data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler, making it easy to scan. It loses a point because part of the second clause duplicates the rights_confirmed parameter description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a mutating queue/download operation with no annotations, no output schema, and four required parameters, yet the description gives almost no operational context such as what happens after queuing or how to verify the exact result. An agent would need to infer too much to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The phrase 'one exact Soulseek result' hints that username, filename, and size form an exact identifier, but only 25% of parameters have schema descriptions and the tool description does not explain size units, filename expectations, or how these fields uniquely identify a result. It does not compensate for the low schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific action ('Queue'), a specific resource ('one exact Soulseek result'), and the system ('slskd'), so an agent immediately knows what the tool does. The action is clearly distinct from the sibling tools 'search_music' and 'list_downloads' without needing their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The wording implies this tool should be used when a specific Soulseek result has already been found and is ready to queue, but it never explicitly states when to use it versus the siblings or what conditions would make it inappropriate. The authorization requirement is a prerequisite, not guidance on choosing this tool among alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_musicA

Search Soulseek through the user's local slskd instance. Use only for music the user is authorized to obtain.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
wait_msNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It adds useful context that the search hits an external P2P network via a local slskd instance and is restricted to authorized content. However, it does not disclose whether the search is blocking, what the results contain, or any rate/usage limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no wasted words. The core action is front-loaded, and the authorization restriction earns its place as meaningful guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a network-search tool with no output schema and no annotations, this is under-specified. It omits parameter semantics, result-return behavior, and any connection to the sibling download/list workflow. The authorization note is helpful but does not make the definition complete enough for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. 'Search Soulseek' weakly implies what query means, but limit and especially wait_ms are entirely unexplained. An agent cannot confidently know how long to wait or how many results to expect from the description alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb 'Search' and a specific resource 'Soulseek through the user's local slskd instance,' and limits scope to music. This clearly distinguishes it from the sibling tools queue_download and list_downloads, which handle different stages of the workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an authorization constraint ('Use only for music the user is authorized to obtain') but does not explicitly say when to prefer this over queue_download or list_downloads. The intended usage is only implied by the word 'Search' and the music scope.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.1.0
    • First observedlist_downloads
    • First observedqueue_download
    • First observedsearch_music

TDQS

A3.8/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a clear, non-overlapping purpose: searching, queueing a specific result, and listing downloads. An agent would not struggle to select the correct tool for a given step.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern: search_music, queue_download, list_downloads. The naming is predictable and immediately conveys the action and target.

Tool Count5/5

Three tools is a tight, well-scoped set for the core search-and-download workflow. Each tool earns its place without unnecessary bulk or overlap.

Completeness4/5

The surface covers the primary workflow of searching, queueing downloads, and checking progress. Missing management actions like canceling, pausing, or retrying downloads are minor gaps for the stated scope.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables interaction with the Soulseek peer-to-peer file sharing network for searching files, browsing user shares, and managing downloads. Supports chat functionality including public rooms, private messages, and user monitoring.
    -
  • F
    license
    A
    quality
    D
    maintenance
    MCP server for searching and downloading music from the Soulseek peer-to-peer network via slskd. Enables AI assistants to discover and download music directly.
    5
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that gives AI agents full control over slskd, a modern Soulseek client, enabling search, download, browse peers, monitor transfers, and manage the slskd instance.
    1
    MIT