Skip to main content
Glama
ecarcamo

Sync Licensing MCP Server

by ecarcamo

Sync-Licensing-MCP-Server

Ein lokaler Model Context Protocol-Server, der den Katalog und die Geschäftslogik einer Musik-Sync-Licensing-Plattform bereitstellt: Suche nach Tracks anhand eines kreativen Briefings, Prüfung der Rechteklärung, Angebot einer Lizenz unter konditionalen Preisregeln, Ausstellung des Vertrags und Registrierung der Nutzung.

Entwickelt für CC3067 Redes (Universidad del Valle de Guatemala), Projekt 1. Der MCP-Nachrichtenfluss ist direkt auf JSON-RPC 2.0 implementiert – ohne MCP-SDK, ohne FastMCP, ohne Framework. Das Serverpaket hängt nur von der Python-Standardbibliothek ab.


Inhaltsverzeichnis

  1. Der Geschäftsfall

  2. Architektur

  3. Anforderungen

  4. Installation

  5. Aufbau des Katalogs

  6. Verwendung

  7. Tool-Referenz

  8. Preisregeln

  9. Protokolldetails

  10. Woher die Daten stammen

  11. Testen

  12. Projektstruktur

  13. Projektstatus


Related MCP server: MusicBrainz MCP Server

1. Der Geschäftsfall

Sync-Licensing ist das Geschäftsmodell von Plattformen wie Epidemic Sound, Artlist und Musicbed: Ein Kreativer oder eine Werbeagentur muss eine Lizenz kaufen, bevor ein Track in audiovisuellen Inhalten verwendet werden darf. Der Prozess hat drei Reibungspunkte:

  • Einen Track zu finden, der zum kreativen Briefing und zum Budget passt, dauert lange.

  • Der rechtliche Status eines Tracks ist nicht offensichtlich – er kann Samples enthalten, die nie freigegeben wurden, oder durch einen Urheberrechtsstreit eingefroren sein.

  • Der Preis ist nicht fest. Derselbe Track kostet für einen Instagram-Beitrag etwas anderes als für eine nationale TV-Kampagne.

Dieser Server verwandelt diesen Workflow in fünf Tools, die ein Assistent verketten kann. Es ist keine Suchmaschine mit angehängter Preisliste: Die Gebühr wird aus konditionalen Regeln berechnet, und die Tools verweigern Operationen, die den Kunden einem rechtlichen Risiko aussetzen würden.

2. Architektur

        ┌────────────────────────┐
        │  Host (chatbot / CLI)  │
        └───────────┬────────────┘
                    │  spawns as a subprocess
        ┌───────────▼────────────┐
        │   MCP client           │   client/mcp_cli.py
        └───────────┬────────────┘
                    │  JSON-RPC 2.0 over stdio
                    │  (one JSON object per line)
        ┌───────────▼────────────┐
        │   MCP server           │   synclicense_mcp/
        │                        │
        │   jsonrpc.py  framing  │
        │   server.py   dispatch │
        │   tools.py    5 tools  │
        │   pricing.py  rate card│
        │   contracts.py contracts
        │   catalog.py  catalog  │
        └───────────┬────────────┘
                    │
        ┌───────────▼────────────┐
        │  data/catalog.json     │  built by scripts/seed_catalog.py
        │  data/usage_log.jsonl  │  append-only audit log
        └────────────────────────┘

stdout transportiert ausschließlich Protokollverkehr; jede Diagnose, die der Server ausgibt, geht an stderr, sodass das Piping der Serverausgabe den Stream nie beschädigt.

3. Anforderungen

  • Python 3.10 oder neuer (entwickelt unter 3.11).

  • Keine weitere Abhängigkeit zum Ausführen des Servers.

  • requests wird nur benötigt, um echte Metadaten von Jamendo zu ziehen, und pytest nur zum Ausführen der Testsuite. Beide sind in requirements.txt.

4. Installation

git clone https://github.com/ecarcamo/MCP-Local-Redes.git
cd MCP-Local-Redes

python3 -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate

pip install -r requirements.txt

Das Paket wird nicht installiert: Es wird aus dem Repository-Stamm importiert, daher wird jeder Befehl unten aus dem Projektverzeichnis ausgeführt.

5. Aufbau des Katalogs

Das Repository enthält bereits einen Katalog unter data/catalog.json mit 800 echten Tracks von der Jamendo-API, sodass Sie diesen Abschnitt überspringen und direkt zu Verwendung gehen können. Bauen Sie ihn nur neu auf, wenn Sie eine andere Größe, einen anderen Seed oder einen Katalog ohne Anmeldedaten wünschen.

Offline-Modus (Standard, keine Anmeldedaten, kein Netzwerk)

python scripts/seed_catalog.py --offline --count 800

Deterministisch: Derselbe --seed erzeugt immer denselben Katalog. Außerdem werden drei bekannte Tracks oben fixiert (TRK-00001 freigegeben, TRK-00002 mit ausstehenden Samples, TRK-00003 blockiert), wodurch die Fehlerszenarien leicht demonstriert werden können.

Jamendo-Modus (echte Creative-Commons-Metadaten)

Registrieren Sie sich unter https://devportal.jamendo.com, um eine client_id zu erhalten, dann:

cp .env.example .env
# edit .env and set JAMENDO_CLIENT_ID=your_client_id

python scripts/seed_catalog.py --jamendo --count 800

Die Track-Metadaten stammen von der API; die Grundgebühr und der Rechtsstatus werden weiterhin lokal generiert (siehe Abschnitt 10). Die Beliebtheit wird aus der eigenen popularity_total-Sortierung der API übernommen. Der kostenlose Jamendo-Plan drosselt Bursts von Anfragen und antwortet auf eine gedrosselte Seite mit einer leeren Ergebnisliste statt mit einem Fehler, daher pausiert das Skript zwischen den Seiten und versucht eine leere Seite erneut, bevor es daraus schließt, dass der Katalog erschöpft ist.

Option

Standard

Beschreibung

--offline / --jamendo

--offline

Quelle der Track-Metadaten

--count N

800

Wie viele Tracks geschrieben werden

--seed N

23016

Seed für die simulierte Geschäftsebene

--output PATH

data/catalog.json

Wohin der Katalog geschrieben wird

6. Verwendung

6.1 Geführte Demo ausführen

Ein skriptierter End-to-End-Lauf, nützlich als Smoke-Test. Er startet den Server, spielt die vollständige Lizenzierungskonversation durch und gibt jede JSON-RPC-Nachricht aus, die über die Leitung geht (--> gesendet, <-- empfangen):

python client/mcp_cli.py --demo

Die Demo durchläuft: Handshake → tools/list → Track suchen → Freigabe prüfen → Angebot erstellen → Vertrag ausstellen → Nutzung registrieren → und drei Fehlerfälle (ein blockierter Track, ein Angebot, das zu einem anderen Track gehört, und ein ungültiges Argument).

Fügen Sie --quiet hinzu, um die rohe Protokollspur zu verbergen und nur die Antworten zu sehen:

python client/mcp_cli.py --demo --quiet

6.2 Interaktive Sitzung (die Hauptnutzungsweise)

Ein REPL, um den Server von Hand zu steuern, ein Tool nach dem anderen:

python client/mcp_cli.py --interactive

Befehl

Beschreibung

list

Vom Server veröffentlichte Tools

schema <tool>

JSON-Schema eines Tools

call <tool> <json>

Ein Tool mit JSON-Argumenten aufrufen

vars

Aus früheren Antworten gemerkte IDs

ping

Einen JSON-RPC-Ping senden

raw <method> [json]

Beliebige JSON-RPC-Methode von Hand senden

quit

Sitzung schließen

IDs werden gemerkt. Jede *_id, die ein Tool zurückgibt, wird gespeichert und kann im nächsten Aufruf als $name wiederverwendet werden, sodass eine ganze Lizenzierungsverhandlung getippt werden kann, ohne eine einzige ID von Hand zu kopieren:

mcp> call buscar_pista {"mood": "epico", "instrumental": true, "presupuesto_max": 100, "limite": 3}
   ...
   remembered: $pista_id=TRK-00312

mcp> call verificar_clearance {"pista_id": "$pista_id"}

mcp> call calcular_costo_licencia {"pista_id": "$pista_id", "tipo_uso": "publicidad_online", "territorio": "latam", "exclusividad": "sectorial", "duracion_meses": 12}
   ...
   remembered: $cotizacion_id=COT-719E615733

mcp> call generar_contrato {"pista_id": "$pista_id", "cliente": "Agencia Lumen S.A.", "cotizacion_id": "$cotizacion_id"}
   ...
   remembered: $contrato_id=CTR-F9D1D72B0D

mcp> call registrar_uso {"contrato_id": "$contrato_id", "plataforma": "YouTube", "url_proyecto": "https://youtube.com/watch?v=demo"}

mcp> vars
mcp> quit

$pista_id standardmäßig auf den besten Kandidaten der letzten Suche. Verwenden Sie vars, um jederzeit zu sehen, was aktuell gemerkt ist.

6.3 Den Server eigenständig ausführen

python -m synclicense_mcp

Er wartet dann auf JSON-RPC-Nachrichten auf stdin. Verwenden Sie --catalog PATH, um auf eine andere Katalogdatei zu verweisen.

6.4 Ohne Client mit ihm sprechen

Da der Transport nur zeilengetrenntes JSON ist, können Sie den Server direkt aus der Shell steuern:

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"shell","version":"0"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"verificar_clearance","arguments":{"pista_id":"TRK-00001"}}}' \
  | python -m synclicense_mcp

7. Tool-Referenz

Tool

Erforderliche Argumente

Rückgabe

buscar_pista

(keine – jeder Filter ist optional)

Kandidaten-Tracks mit ID, Titel, Künstler, Dauer und Grundgebühr

verificar_clearance

pista_id

Rechtlicher Status: freigegeben, Samples ausstehend oder blockiert

calcular_costo_licencia

pista_id, tipo_uso, territorio, exclusividad, duracion_meses

Vollständige Gebührenaufschlüsselung, Gesamtsumme in USD und eine cotizacion_id

generar_contrato

pista_id, cliente, cotizacion_id

Vertrag mit Umfang, Laufzeit, Betrag, Einschränkungen und einer contrato_id

registrar_uso

contrato_id, plataforma, url_proyecto

Nutzungsdatensatz für Tantiemen und Audit

7.1 buscar_pista

Optionale Filter: mood, genero, instrumental, duracion_seg_min, duracion_seg_max, presupuesto_max, limite (1–20, Standard 5).

  • mood: alegre, epico, melancolico, relajado, tenso, energetico, inspirador, oscuro

  • genero: pop, rock, electronica, hip_hop, jazz, clasica, folk, ambient, cinematica, latina

Tracks, die durch einen Urheberrechtsstreit blockiert sind, werden ausgeschlossen: Sie können nicht lizenziert werden, daher wäre ihr Angebot ein Fehlalarm.

7.2 verificar_clearance

Status

Lizenzierbar

Wirkung

libre

ja

Keine Belastung

samples_pendientes

ja

+15 % Treuhandaufschlag und eine Zurückbehaltungsklausel

bloqueada

nein

Urheberrechtsstreit; Angebot und Vertrag werden verweigert

7.3 calcular_costo_licencia

Argument

Zulässige Werte

tipo_uso

redes_sociales, evento_interno, podcast, web_corporativo, publicidad_online, videojuego, tv_nacional, cine

territorio

local, latam, europa, norteamerica, mundial

exclusividad

no, sectorial, total

duracion_meses

0 (unbefristet) oder 1–120

Beispielanfrage und -antwort:

--> {"jsonrpc":"2.0","id":5,"method":"tools/call","params":{
      "name":"calcular_costo_licencia",
      "arguments":{"pista_id":"TRK-00312","tipo_uso":"redes_sociales",
                   "territorio":"local","exclusividad":"no","duracion_meses":6}}}

<-- {"jsonrpc":"2.0","id":5,"result":{
      "content":[{"type":"text","text":"Quote for TRK-00312 \"Stop!\" ... TOTAL USD 94.50"}],
      "structuredContent":{
        "ok":true,
        "cotizacion_id":"COT-3D18B1547D",
        "pista_id":"TRK-00312",
        "alcance":{"tipo_uso":"redes_sociales","territorio":"local",
                   "exclusividad":"no","duracion_meses":6},
        "desglose":{"tarifa_base_usd":94.5,
                    "multiplicadores":{"tipo_uso":1.0,"territorio":1.0,
                                       "exclusividad":1.0,"vigencia":1.0},
                    "subtotal_usd":94.5,"recargo_escrow_usd":0.0,
                    "total_usd":94.5,"moneda":"USD"},
        "valida_hasta":"2026-09-19T18:15:54+00:00"},
      "isError":false}}

7.4 Tool-Verkettung

Die Tools sind innerhalb einer Sitzung zustandsbehaftet, was der Sinn des Anwendungsfalls ist:

buscar_pista ──► pista_id
                    ├──► verificar_clearance      (can stop the whole flow)
                    └──► calcular_costo_licencia ──► cotizacion_id
                                                        └──► generar_contrato ──► contrato_id
                                                                                     └──► registrar_uso

generar_contrato lehnt ein Angebot ab, das nicht existiert, abgelaufen ist (30 Tage) oder für einen anderen Track ausgestellt wurde. registrar_uso lehnt einen unbekannten oder inaktiven Vertrag ab. Angebote und Verträge gehören zu einer Verbindung und werden nicht zwischen Sitzungen geteilt.

8. Preisregeln

subtotal = tarifa_base × mult_use × mult_territory × mult_exclusivity × mult_term
total    = subtotal + escrow surcharge (15% when the track has pending samples)

Nutzungsart

×

Gebiet

×

Exklusivität

×

Laufzeit

×

redes_sociales

1.0

local

1.0

no

1.0

≤ 3 Monate

0.8

evento_interno

1.1

latam

1.8

sectorial

2.0

≤ 6 Monate

1.0

podcast

1.3

europa

2.2

total

4.5

≤ 12 Monate

1.5

web_corporativo

1.6

norteamerica

2.4

≤ 24 Monate

2.2

publicidad_online

2.5

mundial

3.2

≤ 36 Monate

2.8

videojuego

4.0

> 36 Monate

3.2

tv_nacional

6.0

unbefristet

3.5

cine

8.0

Sechs Monate sind die Referenzlaufzeit, weshalb sie bei 1.0 liegt. Ein Angebot hält seinen Preis 30 Tage lang.

9. Protokolldetails

Transport. stdio, eine JSON-RPC-2.0-Nachricht pro Zeile, UTF-8, keine eingebetteten Zeilenumbrüche. Der Server beendet sich sauber bei EOF.

Protokollversionen. 2025-11-25 (bevorzugt) und 2025-06-18. Wenn der Client etwas anderes anfordert, antwortet der Server mit seiner bevorzugten Version, anstatt den Handshake fehlschlagen zu lassen.

Methoden.

Methode

Ergebnis

initialize

Ausgehandelte Version, Fähigkeiten, Serverinformationen, Anweisungen

notifications/initialized

(Benachrichtigung – keine Antwort)

ping

{}

tools/list

Die fünf Tool-Beschreibungen mit ihren JSON-Schemas

tools/call

content, structuredContent, isError

Fehlercodes.

Code

Bedeutung

-32700

Parserfehler — die Zeile ist kein gültiges JSON

-32600

Ungültige Anfrage — fehlerhafter Umschlag

-32601

Methode nicht gefunden

-32602

Ungültige Parameter — fehlendes, falsch typisiertes oder außerhalb der Aufzählung liegendes Argument, oder unbekanntes Werkzeug

-32603

Interner Fehler

-32002

Server nicht initialisiert — eine Anfrage kam vor dem Handshake an

Protokollfehler vs. Geschäftsfehler. Ein fehlerhafter Aufruf wird als JSON-RPC-error zurückgegeben. Ein wohlgeformter Aufruf, den die Lizenzregeln ablehnen — ein gesperrter Titel, eine abgelaufene Lizenz, ein unbekannter Vertrag — wird als erfolgreiche Antwort mit isError: true und einer lesbaren Erklärung zurückgegeben, sodass ein Modell den Grund lesen und den Kurs korrigieren kann, anstatt einen Transportfehler zu sehen.

Eine vollständige Spezifikation finden Sie in docs/SERVER_SPEC.md.

10. Woher die Daten stammen

Titelmetadaten (Titel, Interpret, Dauer, Genre, Stimmung, Lizenz, Beliebtheits- Rang) stammen aus der öffentlichen Jamendo-API, die einen Creative-Commons-Katalog bereitstellt. Der in diesem Repository enthaltene Katalog wurde auf diese Weise erstellt. Der Offline-Generator erzeugt lokal dieselbe Struktur, sodass das Projekt auch ohne Anmeldedaten und ohne Netzwerkzugriff läuft.

Die Geschäftsebene ist bewusst simuliert. Keine Plattform veröffentlicht ihre Preisliste oder den internen Rechtsstatus jedes Titels, daher werden tarifa_usd_base und estado_derechos aus einem festen Startwert mit einer realistischen Verteilung erzeugt (82 % freigegeben, 13 % Muster ausstehend, 5 % gesperrt). Die Preislisten-Multiplikatoren wurden auf Grundlage der öffentlichen lizenzfreien Preislisten von Plattformen wie Jamendo Licensing entworfen. Dieser Umfang wurde vom Kursleiter geprüft und genehmigt.

11. Tests

python -m pytest tests/ -v

Die Suite umfasst die Preislisten-Regeln, den JSON-RPC-Rahmen, den Handshake, die Fehlercodes, die Werkzeugkette und ihre Ablehnungen, den Seed-Generator sowie einen End-to-End-Test, der den echten Serverprozess startet und über stdio mit ihm spricht. Die Tests suchen Titel anhand des Rechtestatus und nicht anhand einer festen ID, sodass sie gegen jeden Katalog bestehen: offline, Jamendo oder neu mit einem anderen Startwert erzeugt.

12. Projektstruktur

MCP-Local-Redes/
├── synclicense_mcp/          MCP server package (standard library only)
│   ├── __main__.py           entry point: python -m synclicense_mcp
│   ├── jsonrpc.py            JSON-RPC 2.0 framing over stdio
│   ├── server.py             MCP method dispatch
│   ├── tools.py              the five tools: schemas, validation, handlers
│   ├── pricing.py            conditional rate card
│   ├── contracts.py          contracts and usage registration
│   ├── catalog.py            catalog loading and search
│   └── errors.py             business-rule failures
├── client/mcp_cli.py         manual JSON-RPC client (demo + REPL)
├── scripts/seed_catalog.py   catalog builder (offline / Jamendo)
├── data/catalog.json         generated catalog
├── tests/                    pytest suite
└── docs/                     proposal, assignment brief, server specification

13. Projektstatus

In dieser Phase geliefert:

  • Lokaler MCP-Server über stdio mit den fünf Werkzeugen des genehmigten Anwendungsfalls.

  • JSON-RPC 2.0 und der MCP-Handshake von Hand implementiert.

  • Befehlszeilenclient mit einem skriptgesteuerten Demoablauf und einer interaktiven REPL.

  • Katalogerzeugung, sowohl offline als auch im Jamendo-Modus.

  • Testsuite.

Für den Rest des Projekts geplant:

  • Chatbot-Host auf der Anthropic-API, mit Sitzungskontext und einem sichtbaren Protokoll jeder MCP-Interaktion.

  • Integration mit den offiziellen Filesystem- und Git-MCP-Servern.

  • Derselbe Server, remote über HTTP bereitgestellt.

  • Wireshark-Erfassung und schichtweise Analyse des Remote-Datenverkehrs.


Autor: Esteban Cárcamo (23016) — CC3067 Redes, Abschnitt 20

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    An MCP server for Spotify control and synchronized lyrics retrieval that enables playback management, queue navigation, and music search capabilities. It also features perception tools for real-time track analysis, including BPM, key detection, and timestamped lyrics.
    129
    3
    Apache 2.0
  • F
    license
    Not graded
    quality
    C
    maintenance
    A remote MCP server for the Arxpot processing core, enabling music search, metadata retrieval, and download management with remote storage delivery.

View all related MCP servers

Related MCP Connectors

  • Personal MCP server for humans who create. Proof of authorship, license control.

  • A paid remote MCP for CLI tool MCP, built to return verdicts, receipts, usage logs, and audit-ready

  • A paid remote MCP for hosted MCP server, built to return verdicts, receipts, usage logs, and audit-r

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ecarcamo/MCP-Local-Redes'

If you have feedback or need assistance with the MCP directory API, please join our Discord server