Pinecone

Lightweight, dependency-free, in-memory Pinecone-compatible REST service for local parlel tests.

Default port: 5081

Quick Start

Start the server in process:

import { PineconeServer } from "./services/pinecone/src/server.js";

const server = new PineconeServer(5081);
await server.start();

Connect with the real @pinecone-database/pinecone client by pointing control-plane and index hosts at the local server. The fake returns local http://127.0.0.1:5081/indexes/<name> hosts from describeIndex.

import { Pinecone } from "@pinecone-database/pinecone";

const pc = new Pinecone({
  apiKey: "parlel",
  controllerHostUrl: "http://127.0.0.1:5081",
});

await pc.createIndex({
  name: "movies",
  dimension: 3,
  metric: "cosine",
  spec: { serverless: { cloud: "aws", region: "us-east-1" } },
});

const description = await pc.describeIndex("movies");
const index = pc.index("movies", description.host);
await index.upsert([{ id: "a", values: [1, 0, 0], metadata: { genre: "sci-fi" } }]);
const results = await index.query({ vector: [1, 0, 0], topK: 1, includeMetadata: true });

Stop it when finished:

await server.stop();

Implemented Operations

Server

OperationEndpoint
Root metadataGET /
HealthcheckGET /health
Project identityGET /actions/whoami
Reset stateserver.reset()

Index Control Plane

OperationEndpoint
Create index / create index for modelPOST /indexes
Create index for model SDK routePOST /indexes/create-for-model
List indexesGET /indexes
Describe indexGET /indexes/:name
Configure indexPATCH /indexes/:name
Delete indexDELETE /indexes/:name

Vector Data Plane

All data-plane routes are available below /indexes/:name. If exactly one index exists, root data-plane paths such as /vectors/upsert also route to it.

OperationEndpoint
Upsert vectorsPOST /indexes/:name/vectors/upsert
Fetch vectorsPOST /indexes/:name/vectors/fetch
Fetch vectors by query stringGET /indexes/:name/vectors/fetch?ids=<id>&namespace=<namespace>
Fetch vectors by metadataPOST /indexes/:name/vectors/fetch_by_metadata
Update vectorPOST /indexes/:name/vectors/update
Delete by ids, filter, or deleteAllPOST /indexes/:name/vectors/delete
Query by vector or idPOST /indexes/:name/query
List vector ids with prefix paginationGET /indexes/:name/vectors/list
Describe index statsPOST /indexes/:name/describe_index_stats

Integrated Records

OperationEndpoint
Upsert recordsPOST /indexes/:name/records/namespaces/:namespace/upsert
Search recordsPOST /indexes/:name/records/namespaces/:namespace/search
Upsert records compatibility routePOST /indexes/:name/vectors/upsert_records

Namespaces

OperationEndpoint
List namespacesGET /indexes/:name/namespaces
Create namespacePOST /indexes/:name/namespaces
Describe namespaceGET /indexes/:name/namespaces/:namespace
Delete namespaceDELETE /indexes/:name/namespaces/:namespace

Collections

OperationEndpoint
Create collectionPOST /collections
List collectionsGET /collections
Describe collectionGET /collections/:name
Delete collectionDELETE /collections/:name

Backups

OperationEndpoint
Create backupPOST /indexes/:name/backups
List backups for indexGET /indexes/:name/backups
List backupsGET /backups
Describe backupGET /backups/:backup_id
Delete backupDELETE /backups/:backup_id
Create index from backupPOST /backups/:backup_id/create-index, POST /indexes/create-index-from-backup
List restore jobsGET /restore-jobs
Describe restore jobGET /restore-jobs/:restore_job_id

Bulk Imports

OperationEndpoint
Start importPOST /indexes/:name/bulk/imports
List importsGET /indexes/:name/bulk/imports
Describe importGET /indexes/:name/bulk/imports/:id
Cancel importDELETE /indexes/:name/bulk/imports/:id

Inference

OperationEndpoint
EmbedPOST /embed, POST /inference/embed
RerankPOST /rerank, POST /inference/rerank
List modelsGET /models
Describe modelGET /models/:model_name

Supported Features

FeatureStatusNotes
Pinecone HTTP REST shapeSupportedJSON responses, Pinecone-style error envelope, local host in index descriptions.
@pinecone-database/pinecone common control-plane callsSupportedCreate, list, describe, configure, delete, whoami.
Dense vectorsSupportedDimension validation is enforced.
Sparse vector score contributionSupportedSparse dot product is added to dense scores.
NamespacesSupportedNamespace state is in memory and ephemeral.
Metadata filtersSupported$eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $exists, $and, $or.
Integrated recordsSupportedText embeddings are deterministic local hashes, not ML embeddings.
CollectionsSupportedMetadata snapshot only; no durable storage.
BackupsSupportedMetadata snapshot and restore configuration only; no durable storage.
Bulk importsSupportedJob lifecycle is faked; no object storage is read.
Inference embed/rerankSupportedDeterministic local fake outputs.
Inference modelsSupportedReturns local fake model metadata.
Authentication and authorizationIntentionally unsupportedAPI keys are accepted but not checked.
Real Pinecone scaling, pods, serverless provisioningIntentionally unsupportedAll state is in-process memory.
DurabilityIntentionally unsupportedUse server.reset() or process restart to clear state.
Real ML embeddings or rerankingIntentionally unsupportedReturned vectors/scores are deterministic fakes for testing.

Error Shapes

Errors use a Pinecone-style JSON envelope:

{
  "error": {
    "code": "INVALID_ARGUMENT",
    "message": "Index name is required"
  },
  "status": 400
}

Common codes:

HTTP statusCodeWhen returned
400INVALID_ARGUMENTMissing names, malformed vector/record payloads, dimension mismatch.
400FAILED_PRECONDITIONDeleting an index with deletion protection enabled.
404NOT_FOUNDMissing index, vector, namespace, collection, backup, or route.
405METHOD_NOT_ALLOWEDKnown resource with unsupported method.
409ALREADY_EXISTSDuplicate index or collection.
500INTERNALUnhandled server error.

State Model

All indexes, namespaces, vectors, collections, backups, and inference outputs are held in memory. State is ephemeral and can be cleared with server.reset().

<!-- 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.

PINECONE_API_KEY=parlel
PINECONE_ENVIRONMENT=local
PINECONE_CONTROLLER_HOST=http://parlel-bridge:5081
<!-- parlel:testenv:end -->