- Home
- Learning paths
- Expert path
- Local development and testing
Local development and testing
Contents
- Running Éclair for local development
- How do you run Éclair's tests?
- Developing the AI assistant with no key and no spending
- Building the distributable archive
- Capturing the rendering and measuring with Lighthouse
- Debug mode and eclair-config.php
- Testing the MCP connector with MCP Inspector
- Key points
- Going further
- Frequently asked questions
Contents
- Running Éclair for local development
- How do you run Éclair's tests?
- Developing the AI assistant with no key and no spending
- Building the distributable archive
- Capturing the rendering and measuring with Lighthouse
- Debug mode and eclair-config.php
- Testing the MCP connector with MCP Inspector
- Key points
- Going further
- Frequently asked questions
Local development on Éclair needs no Composer, no database and no container: PHP 8.1 or later is enough. In this lesson, you run the site on your machine, run the 550 automated checks, build the distributable archive, measure with Lighthouse and test the MCP connector, all before you touch a live site.
What you'll be able to do
Run Éclair locally
PHP's built-in server, with the repository's router.
Test before you ship
Unit and HTTP checks, and a public rendering compared down to the byte.
Debug cleanly
eclair-config.php, the error log and MCP Inspector.
Running Éclair for local development
git clone https://github.com/Jacckisback/eclair-cms.git
cd eclair-cms
PHP_CLI_SERVER_WORKERS=4 php -S localhost:8000 -t eclair tools/router.php
The -t eclair option makes the eclair/ folder the site's root, like a host's public folder. The tools/router.php script reproduces the .htaccess rules: 404 for app/, data/, cache/, hidden files and any .php file other than index.php, and no scripts or pages in media/. It serves existing files as they are and sends everything else to index.php.
Why PHP_CLI_SERVER_WORKERS=4? To verify its address, the site calls itself on /__eclair/ping. With a single process, the built-in server is busy with the current request and can't answer: the check fails, and redirects to the official address stay off. PHP doesn't support multiple workers on Windows: use WSL, or accept an unverified address locally.
Then open http://localhost:8000: the setup wizard starts, with the same 2-hour window as online. Always use the same address (localhost or 127.0.0.1), because it's the one the installation saves. Your local data goes into eclair/data/, which Git ignores, just like the cache, uploaded images and eclair-config.php.
| Repository folder | Contents |
|---|---|
eclair/ | the CMS, as it ships to a host |
i18n/ | human-readable sources of the admin translations |
tests/ | unit and HTTP tests, fake AI providers, reference sites |
tools/ | development router, build, capture, translations |
docs/ | official guide in 7 languages |
dist/ | distributable archives, one per version |
How do you run Éclair's tests?
php tests/run.php # unit + HTTP integration
# ✅ 550 vérifications réussies
php tests/run.php --unit # unit tests only, in a few seconds
# ✅ 241 vérifications réussies
# Same test suite on an unzipped archive
ECLAIR_TEST_ROOT=/tmp/archive/eclair php tests/run.php
The tests don't touch your local development site: unit test data goes into the system's temporary folder. Each HTTP test copies eclair/ into that same folder, empties its data, starts php -S on a random port with four workers and tools/router.php, installs a site, then replays its scenarios with curl. The repository's tools report in French: in the output above, “vérifications réussies” means “checks passed”. If something fails, the list of failed checks is displayed and the command exits with code 1, so it fits as is into a continuous integration pipeline.
| File | What it checks |
|---|---|
tests/run.php | XSS sanitization, slugs, two-factor authentication, blocks; installation, headers, cache and 304, redirects, brute-force protection, FTP recovery; public rendering identical to the reference |
tests/ai.php | the AI assistant end to end, with fake providers |
tests/shop.php | themes, custom CSS, shop, Stripe, PayPal and Revolut links, Merchant Center feed |
tests/mcp.php | MCP connector: OAuth discovery, PKCE, tokens, tools, revocation |
tests/design.php | art directions, contrast, fonts, Design score |
tests/fixtures/ | 4 reference sites and fingerprints of their public rendering |
Developing the AI assistant with no key and no spending
tests/fake-ai.php mimics the Anthropic, OpenAI, FLUX and Ideogram APIs. The tests start it on a local port and write an eclair-config.php file into their copy that defines ECLAIR_AI_ENDPOINTS. You can reproduce this setup to work on the assistant's interface:
# Terminal 1: fake providers (request log in /tmp/fake-ai/log.jsonl)
mkdir -p /tmp/fake-ai
FAKE_AI_DIR=/tmp/fake-ai php -S 127.0.0.1:9999 tests/fake-ai.php
<?php
// eclair/eclair-config.php: the assistant talks to the fake providers
defined('ECLAIR') || exit;
define('ECLAIR_AI_ENDPOINTS', ['anthropic' => 'http://127.0.0.1:9999', 'openai' => 'http://127.0.0.1:9999']);
The fake server only accepts its test keys, such as sk-ant-test-0123456789, and reacts to a keyword placed in your request: ARTICLE (an image, then a draft), EQUIPE (adding a team member) or PIEGE (malicious text), among others.
Building the distributable archive
php tools/build.php
# ✓ Traductions : 6 langues compilées (eclair/app/lang)
# ✓ Empreintes : 126 fichiers (app/manifest.php)
# ✓ Archive : …/dist/eclair-cms-1.8.0.zip (479 Ko, 981 991 octets une fois décompressée)
The version comes from the ECLAIR_VERSION constant in eclair/index.php. The script recompiles the translations, computes each file's SHA-256 fingerprint (its first 128 bits) in app/manifest.php, the basis of the integrity check, then creates dist/eclair-cms-<version>.zip. In the archive, the PHP is compacted with php -w, the admin views are compressed (.php.gz, read through zlib) and the admin JavaScript and CSS are minified. The public rendering stays identical down to the byte. The contents of data/, cache/ and media/ and your eclair-config.php are excluded, while LISEZ-MOI.txt (a read-me in French), LICENSE.txt and THIRD-PARTY-NOTICES.txt are added. Without the zip extension, no archive is created.
Capturing the rendering and measuring with Lighthouse
npm install -g lighthouse # Node.js 22 or later
php tools/capture.php # rendering fingerprints → tests/fixtures/public-<version>.json
php tools/capture.php --lighthouse # mobile Lighthouse → tests/fixtures/lighthouse-<version>.json
tools/capture.php serves the four reference sites in tests/fixtures/sites/ (blog, business, freelance, landing) and records the fingerprint of each page, for a visitor and then with an admin session, the HTML of each block and the public CSS and JS files. tests/run.php compares the current rendering with public-1.6.0.json: a new version must not change a single byte of the public site. The --reinstall option recreates the starter sites, and therefore new fingerprints: the existing references are then no longer valid.
With --lighthouse, the tool measures on mobile the home page and a post of the “business” site, the “landing” page, then the home page dressed in four art directions, keeping the median of three runs. The LIGHTHOUSE and CHROME_PATH variables set the command and the browser. For Éclair 1.8, every measured page scores 100 in all four categories, with an LCP of 779 to 885 ms, a CLS of 0 and a TBT of 0 to 17 ms.
Debug mode and eclair-config.php
Copy eclair/eclair-config.exemple.php as eclair-config.php, next to index.php, and keep only the lines you need. Here is the template, with the ECLAIR_SECRET constant added:
<?php
defined('ECLAIR') || exit;
// Detailed errors and static cache off: only while you fix a problem.
define('ECLAIR_DEBUG', true);
// Data outside the public folder (move the "data" folder first).
// define('ECLAIR_DATA', '/home/moncompte/eclair-data');
// Extra secret for the API key vault, set before saving the keys.
// define('ECLAIR_SECRET', 'une-longue-phrase-secrète');
| Constant | Effect |
|---|---|
ECLAIR_DEBUG | shows errors, turns warnings into exceptions, details the error on the incident page, turns off the static cache |
ECLAIR_DATA | location of the data, eclair/data by default |
ECLAIR_SECRET | added to the site secret to encrypt the API keys |
ECLAIR_AI_ENDPOINTS | replaces the AI providers' URLs: a gateway or fake servers |
Without debug mode, an error displays “Oups, un court-circuit” (always shown in French) with an 8-character reference. The details are logged in data/logs/errors.php and shown on the Security page, under Recent technical errors. That's the right method on a live site, where ECLAIR_DEBUG would show your errors to visitors.
Testing the MCP connector with MCP Inspector
- In the local admin, open Settings › AI assistant, turn on Allow MCP connections and save. A warning reminds you that Claude and ChatGPT require an https address; the Inspector, however, accepts your local address.
- Check OAuth discovery and the refusal without a token with the first two commands below.
- Start the Inspector with the connector URL (third command).
- Connect from the Inspector: it reads the discovery document, registers itself (Éclair accepts return URLs on
http://localhost,127.0.0.1or[::1]), then opens Éclair's consent page. Log in and click Allow. - List the tools:
get_site,search_content,get_contentandfind_mediafor reading;create_draftandupdate_contentfor writing, limited to 60 per hour per connection.
# Discovery: protected resource and authorization server
curl -s http://localhost:8000/.well-known/oauth-protected-resource
# No token: 401 refusal pointing to the discovery document
curl -si -X POST http://localhost:8000/_eclair/mcp | grep -i www-authenticate
# WWW-Authenticate: Bearer resource_metadata="http://localhost:8000/.well-known/oauth-protected-resource"
# MCP Inspector, web interface
npx @modelcontextprotocol/inspector --server-url http://localhost:8000/_eclair/mcp --transport http
The Éclair 1.8 connector announces versions 2025-11-25, 2025-06-18 and 2025-03-26 of the protocol. For a scriptable test, the same command with --cli and --method tools/list lists the tools in the terminal.
Key points
- Local development on Éclair comes down to one command:
PHP_CLI_SERVER_WORKERS=4 php -S localhost:8000 -t eclair tools/router.php. php tests/run.phpreplays 550 checks on copies, without touching your site;--unitsticks to the 241 unit tests.php tools/build.phpproduces the archive and rewritesapp/manifest.php, the basis of the integrity check.eclair-config.phpholds the advanced settings;ECLAIR_DEBUGstays on only while you diagnose a problem.- MCP Inspector tests the connector locally, OAuth included, before Claude or ChatGPT.
Going further
- Éclair's architecture: what your tests exercise, request by request.
- Customize the theme templates: change the rendering, then check it with these tools.
- Understanding the MCP connector: the six tools and what the AI can't do.
- Performance: staying at 100 out of 100: read and interpret a Lighthouse measurement.
- PHP: the built-in web server and its router scripts.
- Model Context Protocol: MCP Inspector documentation.
Frequently asked questions
Do I need Composer, npm or Docker for local development?
No. PHP on the command line is enough for the site, the tests and the archive. Node.js is only used for Lighthouse and MCP Inspector.
Why does the address stay unverified locally?
The built-in server is probably running with a single process: add PHP_CLI_SERVER_WORKERS=4 before the command. On Windows, the check fails without affecting the rest of the site.
Do the tests modify my eclair/ folder?
No. They write to the system's temporary folder and work on copies, which are deleted at the end of each run.
How do I test the archive I just built?
Unzip it, then run ECLAIR_TEST_ROOT=/path/to/eclair php tests/run.php. The checks then cover the compacted files, exactly as they'll ship to your host.