Meilisearch

Lightweight, dependency-free, in-memory Meilisearch-compatible HTTP service for parlel-pool tests.

Default port: 7700

Quick Start

import { MeiliSearch } from "meilisearch";
import { MeilisearchServer } from "../services/meilisearch/src/server.js";

const server = new MeilisearchServer(7700);
await server.start();

const client = new MeiliSearch({ host: "http://127.0.0.1:7700", apiKey: "masterKey" });
await client.createIndex("movies", { primaryKey: "id" });
await client.index("movies").addDocuments([{ id: 1, title: "Interstellar" }]);
const results = await client.index("movies").search("interstellar");

await server.stop();

All state is in-memory and ephemeral. Call server.reset() to clear indexes, tasks, dumps, snapshots, and keys back to the default admin key.

Implemented Operations

Discovery

OperationEndpoint
Root metadataGET /
HealthGET /health
VersionGET /version
Global statsGET /stats

Indexes

OperationEndpoint
List indexesGET /indexes
Create indexPOST /indexes
Get indexGET /indexes/:uid
Update index primary keyPATCH /indexes/:uid
Delete indexDELETE /indexes/:uid
Swap indexesPOST /swap-indexes
Index statsGET /indexes/:uid/stats

Documents

OperationEndpoint
Add or replace documentsPOST /indexes/:uid/documents
Add or partially update documentsPUT /indexes/:uid/documents
List documentsGET /indexes/:uid/documents
Fetch documentsPOST /indexes/:uid/documents/fetch
Get documentGET /indexes/:uid/documents/:id
Delete documentDELETE /indexes/:uid/documents/:id
Delete documents by idsPOST /indexes/:uid/documents/delete-batch
Delete documents by filterPOST /indexes/:uid/documents/delete
Edit documents by functionPOST /indexes/:uid/documents/edit
Delete all documentsDELETE /indexes/:uid/documents
JSON payloadsapplication/json
NDJSON payloadsapplication/x-ndjson
CSV payloadstext/csv

Search

OperationEndpoint
Search by POSTPOST /indexes/:uid/search
Search by GETGET /indexes/:uid/search
Multi-searchPOST /multi-search
Facet searchPOST /indexes/:uid/facet-search
Similar documentsPOST /indexes/:uid/similar

Search supports q, offset, limit, filter, sort, attributesToRetrieve, facets, and simple facet distributions. Filters support simple =, !=, >, >=, <, <= clauses joined with AND.

Settings

OperationEndpoint
Get all settingsGET /indexes/:uid/settings
Update all settingsPATCH /indexes/:uid/settings or PUT /indexes/:uid/settings
Reset all settingsDELETE /indexes/:uid/settings
Displayed attributes/indexes/:uid/settings/displayed-attributes
Searchable attributes/indexes/:uid/settings/searchable-attributes
Filterable attributes/indexes/:uid/settings/filterable-attributes
Sortable attributes/indexes/:uid/settings/sortable-attributes
Ranking rules/indexes/:uid/settings/ranking-rules
Stop words/indexes/:uid/settings/stop-words
Synonyms/indexes/:uid/settings/synonyms
Distinct attribute/indexes/:uid/settings/distinct-attribute
Typo tolerance/indexes/:uid/settings/typo-tolerance
Faceting/indexes/:uid/settings/faceting
Pagination/indexes/:uid/settings/pagination
Proximity precision/indexes/:uid/settings/proximity-precision
Separator tokens/indexes/:uid/settings/separator-tokens
Non-separator tokens/indexes/:uid/settings/non-separator-tokens
Dictionary/indexes/:uid/settings/dictionary
Embedders/indexes/:uid/settings/embedders
Search cutoff/indexes/:uid/settings/search-cutoff-ms
Localized attributes/indexes/:uid/settings/localized-attributes
Facet search/indexes/:uid/settings/facet-search
Prefix search/indexes/:uid/settings/prefix-search
Chat/indexes/:uid/settings/chat

Each individual setting supports GET, PATCH or PUT, and DELETE reset.

Tasks And Batches

OperationEndpoint
List tasksGET /tasks
Get taskGET /tasks/:uid
Cancel tasksPOST /tasks/cancel
Delete tasksDELETE /tasks
List batchesGET /batches
Get batchGET /batches/:uid

Mutating operations complete immediately and return succeeded task summaries. POST /dumps also includes dumpUid; POST /snapshots also includes snapshotUid.

Keys

OperationEndpoint
List API keysGET /keys
Create API keyPOST /keys
Get API key by key or uidGET /keys/:keyOrUid
Update API key by key or uidPATCH /keys/:keyOrUid
Delete API key by key or uidDELETE /keys/:keyOrUid

The reset state includes a default admin key with key: "masterKey".

Maintenance

OperationEndpoint
Create dumpPOST /dumps
Get dump statusGET /dumps/:uid/status
Create snapshotPOST /snapshots
Get experimental featuresGET /experimental-features
Update experimental featuresPATCH /experimental-features

Newer Client Surfaces

OperationEndpoint
List dynamic search rulesPOST /dynamic-search-rules
Get dynamic search ruleGET /dynamic-search-rules/:uid
Update dynamic search rulePATCH /dynamic-search-rules/:uid
Delete dynamic search ruleDELETE /dynamic-search-rules/:uid
List webhooksGET /webhooks
Create webhookPOST /webhooks
Get webhookGET /webhooks/:uuid
Update webhookPATCH /webhooks/:uuid
Delete webhookDELETE /webhooks/:uuid
Get networkGET /network
Update networkPATCH /network
List chat workspacesGET /chats
Get chat workspace settingsGET /chats/:workspace/settings
Update chat workspace settingsPATCH /chats/:workspace/settings
Reset chat workspace settingsDELETE /chats/:workspace/settings
Stream chat completionPOST /chats/:workspace/chat/completions
List index fieldsPOST /indexes/:uid/fields

Supported Features

FeatureStatusNotes
Real Meilisearch HTTP paths used by the meilisearch clientSupportedCovers discovery, indexes, documents, search, settings, tasks, batches, keys, dumps, snapshots, and experimental features.
In-memory indexes and documentsSupportedEphemeral state, reset with server.reset().
Immediate async task responsesSupportedMutations return 202 task summaries and completed task records.
JSON, NDJSON, and CSV document ingestionSupportedCSV parser is intentionally minimal and handles comma-separated headers and values.
Simple search, filtering, sorting, projection, and facetsSupportedDesigned for deterministic app tests, not relevance parity.
Dynamic search rules, webhooks, network, chatsSupportedStored in memory with no external side effects.
Authentication and permissionsIntentionally unsupportedAPI keys are stored and returned, but requests are not authorized.
Persistent storage, LMDB, snapshots on disk, dumps on diskIntentionally unsupportedThis fake is side-effect free.
Typo ranking, semantic/vector search, hybrid search, real tokenizer behaviorIntentionally unsupportedSettings are accepted and returned, but advanced relevance behavior is not simulated.
Network/webhook/task queue timingIntentionally unsupportedAll tasks complete synchronously.

Error Shapes

Errors use Meilisearch-style JSON:

{
  "message": "Index movies not found.",
  "code": "index_not_found",
  "type": "invalid_request",
  "link": "https://docs.meilisearch.com/errors#index_not_found"
}

Common codes returned by this fake:

StatusCode
400missing_index_uid
400index_already_exists
400index_primary_key_no_candidate_found
400missing_document_id
400invalid_document
400missing_facet_name
400invalid_swap_indexes
400missing_api_key_name
404not_found
404index_not_found
404document_not_found
404task_not_found
404batch_not_found
404api_key_not_found
404dump_not_found
500internal
<!-- parlel:testenv:start -->

Configuration — test.env

Copy these into your test.env (used by the bridge sidecar flow). Tokens are Parlel's seeded test credentials — any non-empty value is accepted by the emulator, so you rarely need to change them. Swap in real credentials only when pointing at the live service in prod.env.

MEILI_MASTER_KEY=parlel
MEILI_ENV=development
MEILI_NO_ANALYTICS=true
<!-- parlel:testenv:end -->