Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Sulu Mcp Server Bundle Laravel Package

alengo/sulu-mcp-server-bundle

Read-only Sulu bundle exposing local template XML via authenticated admin API endpoints for MCP servers. Lists templates by type and returns raw XML. Secured by Sulu admin session plus required Bearer token; disabled if token is empty.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Install the Bundle

    composer require alengo/sulu-mcp-server-bundle
    

    Add to config/bundles.php:

    Alengo\SuluMcpServerBundle\McpServerBundle::class => ['all' => true],
    
  2. Configure Routing Create config/routes/alengo_mcp_server.yaml:

    alengo_mcp_server:
        resource: "@McpServerBundle/Resources/config/routing_admin_api.yaml"
        prefix: /admin/api
    
  3. Set Bearer Token Generate a token (e.g., openssl rand -hex 32) and add to .env.local:

    MCP_SERVER_TOKEN=your_generated_token_here
    
  4. Test the API

    • Authenticate as a Sulu admin (e.g., via /admin/login).
    • Use curl to fetch templates:
      curl -X GET http://your-sulu-app/admin/api/mcp/templates/page \
           -H "Authorization: Bearer your_generated_token_here" \
           -b "SULU_SESSION=your_admin_session_cookie"
      
    • Expected response: JSON list of available page template names.

First Use Case: Syncing Templates for a React Frontend

  1. Expose Templates Fetch all page templates:

    const response = await fetch('http://sulu-admin/admin/api/mcp/templates/page', {
      headers: {
        'Authorization': 'Bearer your_token',
        'Cookie': 'SULU_SESSION=your_cookie'
      }
    });
    const templates = await response.json(); // ["homepage.xml", "blog.xml"]
    
  2. Fetch a Specific Template

    const templateResponse = await fetch('http://sulu-admin/admin/api/mcp/templates/page/homepage.xml', {
      headers: {
        'Authorization': 'Bearer your_token',
        'Cookie': 'SULU_SESSION=your_cookie'
      }
    });
    const xml = await templateResponse.text();
    const parser = new DOMParser();
    const doc = parser.parseFromString(xml, "text/xml");
    // Process XML (e.g., extract content blocks for React components).
    
  3. Cache Templates Locally Store fetched templates in a React context or Redux store for offline use.


Implementation Patterns

Common Workflows

1. Polling for Template Updates (Live Previews)

  • Use Case: A React/Vue app needs to reflect Sulu template changes in real-time.
  • Pattern:
    • Client-side polling:
      async function pollTemplates() {
        const lastUpdated = localStorage.getItem('templateLastUpdated');
        const response = await fetch('http://sulu-admin/admin/api/mcp/templates/page', {
          headers: { /* auth headers */ }
        });
        const templates = await response.json();
        if (JSON.stringify(templates) !== lastUpdated) {
          localStorage.setItem('templateLastUpdated', JSON.stringify(templates));
          // Trigger UI update or refetch all templates.
        }
        setTimeout(pollTemplates, 5000); // Poll every 5s.
      }
      
    • Server-side caching: Add a Last-Modified header to responses (requires custom controller extension):
      # config/packages/alengo_mcp_server.yaml
      alengo_mcp_server:
          template_dirs:
              page: config/templates/pages
          cache_headers: true  # Hypothetical config (not natively supported).
      

2. Static Site Generation (SSG)

  • Use Case: Fetch all templates during a Next.js build.
  • Pattern:
    • Next.js getStaticProps:
      export async function getStaticProps() {
        const templates = await Promise.all([
          fetchTemplate('page', 'homepage'),
          fetchTemplate('block', 'hero')
        ]);
        return { props: { templates } };
      }
      
    • Helper function:
      async function fetchTemplate(type, name) {
        const res = await fetch(`http://sulu-admin/admin/api/mcp/templates/${type}/${name}`, {
          headers: { /* auth headers */ }
        });
        return res.text();
      }
      

3. Multi-Channel Publishing (Mobile Apps)

  • Use Case: Sync templates to a Flutter app via a backend service.
  • Pattern:
    • Backend proxy:
      # Python (FastAPI) example
      @app.get("/mobile/templates/{type}/{name}")
      async def get_template(type: str, name: str):
          sulu_res = requests.get(
              f"http://sulu-admin/admin/api/mcp/templates/{type}/{name}",
              headers={"Authorization": f"Bearer {os.getenv('MCP_TOKEN')}"},
              cookies={"SULU_SESSION": os.getenv("SULU_SESSION_COOKIE")}
          )
          return {"template": sulu_res.text()}
      
    • Mobile app:
      // Flutter example
      Future<String> fetchTemplate(String type, String name) async {
        final response = await http.get(
          Uri.parse('http://your-backend/mobile/templates/$type/$name'),
          headers: {"Authorization": "Bearer mobile_app_token"},
        );
        return response.body;
      }
      

Integration Tips

1. Token Management

  • Rotation:
    • Change MCP_SERVER_TOKEN in .env.local and clear Symfony cache:
      php bin/console cache:clear
      
    • Automate rotation (e.g., via cron):
      #!/bin/bash
      NEW_TOKEN=$(openssl rand -hex 32)
      sed -i "s/MCP_SERVER_TOKEN=.*/MCP_SERVER_TOKEN=$NEW_TOKEN/" .env.local
      php bin/console cache:clear
      
  • Token Storage:
    • Store tokens securely in MCP servers (e.g., AWS Secrets Manager, HashiCorp Vault).

2. Authentication Flow

  • Session Persistence:
    • MCP servers must maintain Sulu admin session cookies (e.g., via httpOnly cookies or secure storage).
    • Avoid hardcoding cookies: Use a short-lived token exchange endpoint (custom development needed).

3. Template Customization

  • Override Default Paths:
    # config/packages/alengo_mcp_server.yaml
    alengo_mcp_server:
        template_dirs:
            page: custom/path/to/pages
            article: vendor/sulu-bundle/config/templates/articles
    
  • Add Custom Template Types:
    alengo_mcp_server:
        template_dirs:
            custom_block: app/Resources/templates/blocks
    
    Now accessible at /admin/api/mcp/templates/custom_block.

4. Extending the Bundle

  • Custom Controller: Override the controller to add features (e.g., JSON formatting):
    // src/Controller/McpTemplateController.php
    namespace App\Controller;
    
    use Alengo\SuluMcpServerBundle\Controller\McpTemplateController as BaseController;
    use Symfony\Component\HttpFoundation\Response;
    
    class McpTemplateController extends BaseController
    {
        public function getTemplate(string $type, string $name): Response
        {
            $xml = parent::getTemplate($type, $name)->getContent();
            $json = json_encode($this->xmlToArray($xml));
            return new Response($json, 200, ['Content-Type' => 'application/json']);
        }
    
        private function xmlToArray(string $xml): array
        {
            // Implement XML-to-array conversion.
        }
    }
    
    Update routing to point to your controller.

Gotchas and Tips

Pitfalls

  1. Missing Authentication Headers

    • Error: 401 Unauthorized or 403 Forbidden.
    • Fix: Ensure both:
      • Sulu admin session cookies are sent.
      • Authorization: Bearer <token> header is included.
    • Debugging:
      curl -v http://sulu-admin/admin/api/mcp/templates/page \
           -H "Authorization: Bearer $TOKEN" \
           -b "SULU_SESSION=..."
      
      Check the -v output for missing headers.
  2. Incorrect Template Paths

    • Error: 404 Not Found for valid template names.
    • Fix: Verify template_dirs in config/packages/alengo_mcp_server.yaml matches your Sulu setup.
    • Debugging:
      find config/templates -type f | grep "homepage.xml"
      
  3. Token Not Configured

    • Error: API returns 403 Forbidden even with valid session.
    • Fix: Ensure MCP_SERVER_TOKEN is set in .env.local and not empty.
  4. XML Parsing Issues

    • Error: MCP server fails to parse raw XML.
    • Fix: Add a ?format=json query parameter (requires custom controller extension):
      // In your custom controller:
      public function getTemplate(string $type, string $
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle