Journalia

1 entry · exploration

· # exploration

Projet : Mon Journal (journal personnel MCP)

Journal personnel construit autour d'un serveur MCP Laravel + plugin Claude Code, accessible depuis les 3 runtimes Claude.

Architecture

  • Backend : Laravel 13 + PHP 8.4 + MySQL en prod (déployé sur Ploi → https://j.pham.fr)
  • Plugin Claude Code : marketplace personnel (spham/plugin-marketplace) avec skill journal:j (extraction collection X, anti-typo, ton FR court)
  • Auth dual côté MCP :
    • Bearer statique (JOURNAL_MCP_TOKEN) pour Claude Code
    • OAuth 2.0 + Dynamic Client Registration (Passport 13 + Mcp::oauthRoutes()) pour claude.ai web/desktop/mobile

Modèle de données

  • JournalEntry : content, collection_id?, tags (legacy, non utilisé)
  • Collection : name, slug (slug figé pour matching, name renommable)
  • Notes orphelines = pas rattachées à une collection
  • Slug normalisé via Collection::makeSlug() : trim → lowercase → ASCII → spaces collapse → dash

UX

  • Home publique en lecture seule (sans login) avec sidebar collections + recherche full-text
  • Auth Fortify (Livewire Flux) avec SESSION_LIFETIME=1 an pour rester loggé partout
  • Page /collections (auth) pour rename/delete
  • Kebab par entrée pour réassigner / détacher / supprimer (auth)
  • Vue OAuth de consentement custom à resources/views/oauth/authorize.blade.php

Outils MCP exposés

  • write-entry : écrit une note, accepte collection (find-or-create par slug)
  • read-entries : N dernières entrées, filtrable par collection ou none (orphelines)
  • search-entries : recherche par mot-clé, combinable avec collection
  • list-collections : liste triée par entries_count desc (utilisé en anti-typo avant write)

Tests

  • Pest 4 + RefreshDatabase
  • 57+ tests passants, dont 8 OAuth (metadata, DCR, dual-token middleware) et 11 MCP fonctionnels

Validé end-to-end

  • Note écrite depuis claude.ai web via OAuth-issued Bearer → prod MySQL → visible sur https://j.pham.fr
  • Note écrite depuis Claude Code via static Bearer → idem ✓
  • Plugin marketplace installable via /plugin marketplace add

À faire potentiellement

  • Désactiver Features::registration() dans Fortify (mono-utilisateur)
  • Multi-utilisateur si besoin (scope JournalEntry par user_id)
  • Lecture des notes sans login via URL secrète (capability URL) — option B initialement écartée au profit du long session, mais reste sur la table