<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>N8n API - MCP Server</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container">
<a class="navbar-brand" href="/">MCP n8n Server</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/">Accueil</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/validator">Validateur</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/templates">Templates</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/docs">Documentation</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/nextjs-integration">NextJS Integration</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/workflow-manager">Gestionnaire de Workflows</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="/n8n-api">API n8n</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container mt-4">
<h1 class="mb-4">API n8n</h1>
<p class="lead">Interagissez directement avec l'API n8n depuis cette interface.</p>
<div class="row">
<div class="col-md-6">
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title mb-0">Requête API n8n</h5>
</div>
<div class="card-body">
<form id="apiForm">
<div class="mb-3">
<label for="endpoint" class="form-label">Endpoint</label>
<div class="input-group">
<span class="input-group-text" id="api-base-url"></span>
<input type="text" class="form-control" id="endpoint" placeholder="/workflows" required>
</div>
<div class="form-text">Exemple: /workflows, /executions, /credentials</div>
</div>
<div class="mb-3">
<label for="method" class="form-label">Méthode HTTP</label>
<select class="form-select" id="method" required>
<option value="GET">GET</option>
<option value="POST">POST</option>
<option value="PUT">PUT</option>
<option value="DELETE">DELETE</option>
</select>
</div>
<div class="mb-3">
<label for="params" class="form-label">Paramètres (JSON)</label>
<textarea class="form-control" id="params" rows="2" placeholder='{"key": "value"}'></textarea>
</div>
<div class="mb-3" id="dataContainer">
<label for="data" class="form-label">Corps de la requête (JSON)</label>
<textarea class="form-control" id="data" rows="5" placeholder='{"key": "value"}'></textarea>
</div>
<button type="submit" class="btn btn-primary">Envoyer la requête</button>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title mb-0">Résultat</h5>
</div>
<div class="card-body">
<pre id="result" class="bg-light p-3 rounded" style="max-height: 400px; overflow-y: auto;">Aucun résultat pour le moment</pre>
</div>
</div>
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title mb-0">Endpoints courants</h5>
</div>
<div class="card-body">
<ul class="list-group" id="endpoints-list">
<li class="list-group-item d-flex justify-content-between align-items-center">
Chargement des endpoints...
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<footer class="bg-light py-3 mt-5">
<div class="container text-center">
<p class="mb-0">MCP n8n Server © 2023</p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Afficher/masquer le champ data en fonction de la méthode HTTP
const methodSelect = document.getElementById('method');
const dataContainer = document.getElementById('dataContainer');
methodSelect.addEventListener('change', function() {
if (this.value === 'GET' || this.value === 'DELETE') {
dataContainer.style.display = 'none';
} else {
dataContainer.style.display = 'block';
}
});
// Déclencher l'événement change pour initialiser l'affichage
methodSelect.dispatchEvent(new Event('change'));
// Récupérer les informations de l'API
fetch('/api/n8n-api/info')
.then(response => response.json())
.then(data => {
if (data.success) {
// Afficher l'URL de base de l'API
document.getElementById('api-base-url').textContent = data.apiUrl;
// Afficher les endpoints courants
const endpointsList = document.getElementById('endpoints-list');
endpointsList.innerHTML = '';
data.endpoints.forEach(endpoint => {
const li = document.createElement('li');
li.className = 'list-group-item d-flex justify-content-between align-items-center endpoint-item';
li.innerHTML = `
<span>${endpoint.path}</span>
<span class="text-muted">${endpoint.description}</span>
<button class="btn btn-sm btn-outline-primary use-endpoint" data-endpoint="${endpoint.path}">Utiliser</button>
`;
endpointsList.appendChild(li);
});
// Ajouter des écouteurs d'événements pour les boutons "Utiliser"
document.querySelectorAll('.use-endpoint').forEach(button => {
button.addEventListener('click', function() {
document.getElementById('endpoint').value = this.dataset.endpoint;
});
});
}
})
.catch(error => {
console.error('Erreur lors de la récupération des informations de l\'API:', error);
});
// Gérer la soumission du formulaire
document.getElementById('apiForm').addEventListener('submit', function(e) {
e.preventDefault();
const endpoint = document.getElementById('endpoint').value;
const method = document.getElementById('method').value;
let params = document.getElementById('params').value;
let data = document.getElementById('data').value;
// Convertir les paramètres en objet JSON si non vide
if (params.trim() === '') {
params = null;
} else {
try {
params = JSON.parse(params);
} catch (error) {
alert('Les paramètres doivent être au format JSON valide');
return;
}
}
// Convertir les données en objet JSON si non vide et si la méthode n'est pas GET ou DELETE
if (method !== 'GET' && method !== 'DELETE' && data.trim() !== '') {
try {
data = JSON.parse(data);
} catch (error) {
alert('Les données doivent être au format JSON valide');
return;
}
} else {
data = null;
}
// Envoyer la requête à l'API
fetch('/api/n8n-api', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
endpoint,
method,
params,
data
})
})
.then(response => response.json())
.then(result => {
document.getElementById('result').textContent = JSON.stringify(result, null, 2);
})
.catch(error => {
console.error('Erreur lors de l\'envoi de la requête:', error);
document.getElementById('result').textContent = `Erreur: ${error.message}`;
});
});
});
</script>
</body>
</html>