feat: add MCP server with resources, tools, auth, and Traefik routing

- Add backend/app/mcp_server.py with FastMCP server (hms-cms)
- Resources: design-rules, page-structure, sync-status
- Tools: trigger_sync, get_sync_log, set_rentman_token, read_file,
  write_file, create_page, deploy, git_commit, git_status
- Bearer token auth via MCP_AUTH_TOKEN env var
- Mount MCP at /mcp with streamable HTTP transport
- Integrate session manager in FastAPI lifespan
- Add Traefik labels for external /mcp route on hms.media-on.de
- Add git, docker.io, curl to backend Dockerfile
- Mount repo root + docker socket in backend container
- Add mcp>=1.0.0 to requirements.txt
This commit is contained in:
Agent Zero
2026-07-12 15:58:22 +02:00
parent 00c23bc066
commit cd465e0564
124 changed files with 3309 additions and 225 deletions
@@ -0,0 +1,84 @@
import { describe, it, expect } from "vitest";
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
describe("Kontakt Page (prototype port)", () => {
const pagePath = resolve(__dirname, "../../pages/kontakt.vue");
const content = readFileSync(pagePath, "utf-8");
it("should have page title Kontakt", () => {
expect(content).toContain("Kontakt");
});
it("should have office address card with Leipheim", () => {
expect(content).toContain("Grockelhofen 10");
expect(content).toContain("89340 Leipheim");
});
it("should have warehouse address with Ellzee", () => {
expect(content).toContain("Zur Schönhalde 8");
expect(content).toContain("89352 Ellzee");
});
it("should have opening hours", () => {
expect(content).toContain("Öffnungszeiten");
expect(content).toContain("10:00 18:00");
});
it("should have 2 contact persons", () => {
expect(content).toContain("Leopold Hammerschmidt");
expect(content).toContain("Andreas Mössle");
});
it("should have form with name field (required)", () => {
expect(content).toContain('id="name"');
expect(content).toContain("Name");
});
it("should have form with email field (required)", () => {
expect(content).toContain('id="email"');
expect(content).toContain("E-Mail");
});
it("should have form with phone field", () => {
expect(content).toContain('id="phone"');
expect(content).toContain("Telefon");
});
it("should have form with subject select", () => {
expect(content).toContain('id="subject"');
expect(content).toContain("Anliegen");
});
it("should have form with message textarea (required)", () => {
expect(content).toContain('id="message"');
expect(content).toContain("Nachricht");
});
it("should have privacy consent checkbox", () => {
expect(content).toContain('type="checkbox"');
expect(content).toContain("Datenschutzerklärung");
});
it("should have submit button", () => {
expect(content).toContain("Nachricht senden");
expect(content).toContain("hms-btn-primary");
});
it("should have email validation", () => {
expect(content).toContain("validate");
});
it("should have success state", () => {
expect(content).toContain("Nachricht übermittelt");
expect(content).toContain("Vielen Dank");
});
it("should have hms-input class", () => {
expect(content).toContain("hms-input");
});
it("should use TypeScript with lang=ts", () => {
expect(content).toContain('<script setup lang="ts">');
});
});