Sync Licensing MCP Server
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
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.
requestswird nur benötigt, um echte Metadaten von Jamendo zu ziehen, undpytestnur zum Ausführen der Testsuite. Beide sind inrequirements.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.txtDas 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 800Deterministisch: 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 800Die 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 |
|
| Quelle der Track-Metadaten |
|
| Wie viele Tracks geschrieben werden |
|
| Seed für die simulierte Geschäftsebene |
|
| 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 --demoDie 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 --quiet6.2 Interaktive Sitzung (die Hauptnutzungsweise)
Ein REPL, um den Server von Hand zu steuern, ein Tool nach dem anderen:
python client/mcp_cli.py --interactiveBefehl | Beschreibung |
| Vom Server veröffentlichte Tools |
| JSON-Schema eines Tools |
| Ein Tool mit JSON-Argumenten aufrufen |
| Aus früheren Antworten gemerkte IDs |
| Einen JSON-RPC-Ping senden |
| Beliebige JSON-RPC-Methode von Hand senden |
| 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_mcpEr 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_mcp7. Tool-Referenz
Tool | Erforderliche Argumente | Rückgabe |
| (keine – jeder Filter ist optional) | Kandidaten-Tracks mit ID, Titel, Künstler, Dauer und Grundgebühr |
|
| Rechtlicher Status: freigegeben, Samples ausstehend oder blockiert |
|
| Vollständige Gebührenaufschlüsselung, Gesamtsumme in USD und eine |
|
| Vertrag mit Umfang, Laufzeit, Betrag, Einschränkungen und einer |
|
| 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,oscurogenero: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 |
| ja | Keine Belastung |
| ja | +15 % Treuhandaufschlag und eine Zurückbehaltungsklausel |
| nein | Urheberrechtsstreit; Angebot und Vertrag werden verweigert |
7.3 calcular_costo_licencia
Argument | Zulässige Werte |
|
|
|
|
|
|
|
|
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_usogenerar_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 | × |
| 1.0 |
| 1.0 |
| 1.0 | ≤ 3 Monate | 0.8 |
| 1.1 |
| 1.8 |
| 2.0 | ≤ 6 Monate | 1.0 |
| 1.3 |
| 2.2 |
| 4.5 | ≤ 12 Monate | 1.5 |
| 1.6 |
| 2.4 | ≤ 24 Monate | 2.2 | ||
| 2.5 |
| 3.2 | ≤ 36 Monate | 2.8 | ||
| 4.0 | > 36 Monate | 3.2 | ||||
| 6.0 | unbefristet | 3.5 | ||||
| 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 |
| Ausgehandelte Version, Fähigkeiten, Serverinformationen, Anweisungen |
| (Benachrichtigung – keine Antwort) |
|
|
| Die fünf Tool-Beschreibungen mit ihren JSON-Schemas |
|
|
Fehlercodes.
Code | Bedeutung |
| Parserfehler — die Zeile ist kein gültiges JSON |
| Ungültige Anfrage — fehlerhafter Umschlag |
| Methode nicht gefunden |
| Ungültige Parameter — fehlendes, falsch typisiertes oder außerhalb der Aufzählung liegendes Argument, oder unbekanntes Werkzeug |
| Interner Fehler |
| 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/ -vDie 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 specification13. 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
This server cannot be installed
Maintenance
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
- AlicenseNot gradedqualityCmaintenanceAn 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.1293Apache 2.0
- AlicenseNot gradedqualityCmaintenanceA comprehensive MCP server for querying the MusicBrainz database, providing tools to search for artists, releases, recordings, and browse music metadata.4MIT
- FlicenseNot gradedqualityCmaintenanceA remote MCP server for the Arxpot processing core, enabling music search, metadata retrieval, and download management with remote storage delivery.
- AlicenseAqualityAmaintenanceAn MCP server that enables searching tracks and fetching lyrics, including time-synced LRC lyrics, from LRCLIB without requiring an API key.2398MIT
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
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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