mirror of
https://github.com/HolgerHatGarKeineNode/einundzwanzig-app.git
synced 2026-06-11 02:50:29 +00:00
8c68b19138
- 🛠️ Introduced generic Super-Admin MCP tools, including `list-models`, `describe-model`, `list-records`, `show-record`, `create-record`, and `update-record`. - 🛡️ Restricted modification of critical fields (e.g., passwords, roles, tokens) to enhance security. - ✅ Added extensive feature tests for Super-Admin functionality and access control. - 📜 Increased pagination length to accommodate new tools on a single page. - 🔗 Registered Super-Admin tools in `EinundzwanzigServer`.
166 lines
7.0 KiB
PHP
166 lines
7.0 KiB
PHP
<?php
|
||
|
||
namespace App\Mcp\Servers;
|
||
|
||
use App\Mcp\Tools\City\CreateCityTool;
|
||
use App\Mcp\Tools\City\ListMyCitiesTool;
|
||
use App\Mcp\Tools\City\ShowMyCityTool;
|
||
use App\Mcp\Tools\City\UpdateCityTool;
|
||
use App\Mcp\Tools\Course\CreateCourseTool;
|
||
use App\Mcp\Tools\Course\UpdateCourseTool;
|
||
use App\Mcp\Tools\CourseEvent\CreateCourseEventTool;
|
||
use App\Mcp\Tools\CourseEvent\ListMyCourseEventsTool;
|
||
use App\Mcp\Tools\CourseEvent\UpdateCourseEventTool;
|
||
use App\Mcp\Tools\Lecturer\CreateLecturerTool;
|
||
use App\Mcp\Tools\Lecturer\ListMyLecturersTool;
|
||
use App\Mcp\Tools\Lecturer\ShowMyLecturerTool;
|
||
use App\Mcp\Tools\Lecturer\UpdateLecturerTool;
|
||
use App\Mcp\Tools\Meetup\AddMeetupToMineTool;
|
||
use App\Mcp\Tools\Meetup\CreateMeetupTool;
|
||
use App\Mcp\Tools\Meetup\ListMyMeetupsTool;
|
||
use App\Mcp\Tools\Meetup\ShowMyMeetupTool;
|
||
use App\Mcp\Tools\Meetup\UpdateMeetupTool;
|
||
use App\Mcp\Tools\MeetupEvent\CreateMeetupEventTool;
|
||
use App\Mcp\Tools\MeetupEvent\ListMyMeetupEventsTool;
|
||
use App\Mcp\Tools\MeetupEvent\ShowMyMeetupEventTool;
|
||
use App\Mcp\Tools\MeetupEvent\UpdateMeetupEventTool;
|
||
use App\Mcp\Tools\Search\ListCountriesTool;
|
||
use App\Mcp\Tools\Search\SearchCitiesTool;
|
||
use App\Mcp\Tools\Search\SearchCoursesTool;
|
||
use App\Mcp\Tools\Search\SearchLecturersTool;
|
||
use App\Mcp\Tools\Search\SearchMeetupsTool;
|
||
use App\Mcp\Tools\Search\SearchVenuesTool;
|
||
use App\Mcp\Tools\SuperAdmin\SuperAdminCreateRecordTool;
|
||
use App\Mcp\Tools\SuperAdmin\SuperAdminDescribeModelTool;
|
||
use App\Mcp\Tools\SuperAdmin\SuperAdminListModelsTool;
|
||
use App\Mcp\Tools\SuperAdmin\SuperAdminListRecordsTool;
|
||
use App\Mcp\Tools\SuperAdmin\SuperAdminShowRecordTool;
|
||
use App\Mcp\Tools\SuperAdmin\SuperAdminUpdateRecordTool;
|
||
use App\Mcp\Tools\Venue\CreateVenueTool;
|
||
use App\Mcp\Tools\Venue\ListMyVenuesTool;
|
||
use App\Mcp\Tools\Venue\ShowMyVenueTool;
|
||
use App\Mcp\Tools\Venue\UpdateVenueTool;
|
||
use Laravel\Mcp\Server;
|
||
use Laravel\Mcp\Server\Attributes\Instructions;
|
||
use Laravel\Mcp\Server\Attributes\Name;
|
||
use Laravel\Mcp\Server\Attributes\Version;
|
||
use Laravel\Mcp\Server\Tool;
|
||
|
||
#[Name('Einundzwanzig API')]
|
||
#[Version('1.0.0')]
|
||
#[Instructions(<<<'TXT'
|
||
Dieser Server spiegelt die authentifizierte Einundzwanzig-API. Jeder Aufruf läuft im Kontext
|
||
des angemeldeten Nutzers; beim Anlegen wird der Ersteller (created_by) automatisch gesetzt.
|
||
Schreib- und Eigentums-Operationen (update, show-my-*) sind nur für den Ersteller oder einen
|
||
Super-Admin erlaubt.
|
||
|
||
WICHTIG – niemals nach numerischen IDs fragen: Nutzer kennen keine internen IDs. Referenziere
|
||
Entitäten immer über ihren NAMEN:
|
||
- Eigene Datensätze ändern/anzeigen: zuerst das passende list-my-* Tool aufrufen
|
||
(list-my-meetups, list-my-cities, list-my-venues, list-my-lecturers, list-my-course-events),
|
||
dem Nutzer die Namen als Auswahlliste präsentieren und ihn wählen lassen. Dann das update-/
|
||
show-my-* Tool mit dem gewählten Namen aufrufen (Parameter z. B. "meetup", "city", "venue",
|
||
"lecturer", "course").
|
||
- Fremdschlüssel beim Anlegen (Stadt, Land, Referent, Kurs, Veranstaltungsort): den Namen
|
||
übergeben (Parameter z. B. "city", "country", "lecturer", "course", "venue"); bei Unsicherheit
|
||
vorher mit search-cities / search-venues / search-lecturers / search-courses / list-countries
|
||
den genauen Namen ermitteln.
|
||
Bevor ein NEUES Meetup angelegt wird (create-meetup): IMMER zuerst mit search-meetups nach
|
||
einem bestehenden Meetup suchen – sowohl nach dem Namen als auch nach dem Stadtnamen. Existiert
|
||
bereits ein passendes Meetup, KEIN Duplikat anlegen, sondern dem Nutzer das gefundene Meetup
|
||
nennen. Nur wenn die Suche kein passendes Meetup liefert, den Nutzer fragen, ob ein neues
|
||
Meetup erstellt werden soll – und erst nach Bestätigung create-meetup aufrufen.
|
||
|
||
Termine/Events (Meetup-Termine, Kurs-Events) haben keinen Namen. Hier zuerst list-my-meetup-
|
||
events bzw. list-my-course-events aufrufen, dem Nutzer die Einträge zur Auswahl anbieten und
|
||
die ID des gewählten Eintrags übergeben – ebenfalls ohne den Nutzer nach der ID zu fragen.
|
||
|
||
Die Tools lösen Namen serverseitig auf. Bei Mehrdeutigkeit oder fehlendem Treffer liefern sie
|
||
eine Liste der passenden Einträge zurück – diese dem Nutzer zur Auswahl anbieten. Die *_id-
|
||
Parameter sind nur ein optionaler Fallback, falls die ID bereits bekannt ist.
|
||
|
||
Super-Admins sehen zusätzlich generische super-admin-* Tools, mit denen JEDES Model bearbeitet
|
||
werden kann (ohne Ownership-Beschränkung). Vorgehen: erst super-admin-list-models, dann
|
||
super-admin-describe-model (für die Felder), dann super-admin-list-records / -show-record zum
|
||
Finden und schließlich super-admin-create-record / -update-record zum Bearbeiten.
|
||
Sicherheitskritische Felder (Passwörter, Auth-Tokens, Rollen) lassen sich über diese Tools
|
||
NICHT setzen – Rollen und Passwörter werden ausschließlich über die dafür vorgesehenen Wege
|
||
verwaltet.
|
||
TXT)]
|
||
class EinundzwanzigServer extends Server
|
||
{
|
||
/**
|
||
* tools/list wird vom Paket cursor-paginiert (Default 15/Seite). Manche Clients
|
||
* (z. B. der Claude.ai-Web-Connector) laden nur die erste Seite und folgen dem
|
||
* nextCursor nicht – dann fehlt die Hälfte der Tools. Wir heben die Seitengröße an,
|
||
* sodass alle Tools auf eine Seite passen.
|
||
*/
|
||
public int $maxPaginationLength = 1000;
|
||
|
||
public int $defaultPaginationLength = 1000;
|
||
|
||
/**
|
||
* The tools registered with this MCP server.
|
||
*
|
||
* @var array<int, class-string<Tool>>
|
||
*/
|
||
protected array $tools = [
|
||
// Meetups
|
||
CreateMeetupTool::class,
|
||
UpdateMeetupTool::class,
|
||
AddMeetupToMineTool::class,
|
||
ListMyMeetupsTool::class,
|
||
ShowMyMeetupTool::class,
|
||
|
||
// Meetup-Events
|
||
CreateMeetupEventTool::class,
|
||
UpdateMeetupEventTool::class,
|
||
ListMyMeetupEventsTool::class,
|
||
ShowMyMeetupEventTool::class,
|
||
|
||
// Städte
|
||
CreateCityTool::class,
|
||
UpdateCityTool::class,
|
||
ListMyCitiesTool::class,
|
||
ShowMyCityTool::class,
|
||
|
||
// Veranstaltungsorte
|
||
CreateVenueTool::class,
|
||
UpdateVenueTool::class,
|
||
ListMyVenuesTool::class,
|
||
ShowMyVenueTool::class,
|
||
|
||
// Referenten
|
||
CreateLecturerTool::class,
|
||
UpdateLecturerTool::class,
|
||
ListMyLecturersTool::class,
|
||
ShowMyLecturerTool::class,
|
||
|
||
// Kurse
|
||
CreateCourseTool::class,
|
||
UpdateCourseTool::class,
|
||
|
||
// Kurs-Events
|
||
ListMyCourseEventsTool::class,
|
||
CreateCourseEventTool::class,
|
||
UpdateCourseEventTool::class,
|
||
|
||
// Suche / Stammdaten-Lookups
|
||
SearchMeetupsTool::class,
|
||
SearchCitiesTool::class,
|
||
SearchVenuesTool::class,
|
||
SearchLecturersTool::class,
|
||
SearchCoursesTool::class,
|
||
ListCountriesTool::class,
|
||
|
||
// Super-Admin: generische Tools für ALLE Models (nur für Super-Admins sichtbar,
|
||
// via shouldRegister; created_by/Ownership-Beschränkungen entfallen hier bewusst).
|
||
SuperAdminListModelsTool::class,
|
||
SuperAdminDescribeModelTool::class,
|
||
SuperAdminListRecordsTool::class,
|
||
SuperAdminShowRecordTool::class,
|
||
SuperAdminCreateRecordTool::class,
|
||
SuperAdminUpdateRecordTool::class,
|
||
];
|
||
}
|