Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,25 @@ Tagged releases are published to npm from GitHub Actions when a **GitHub Release

## [Unreleased]

### Added

- `ServerContextComposition` interface plus `NamespaceCacheSeed` and `SuggestionFlowSeedEntry` types for dependency injection into `ServerContext`.
- `createIsolatedContext(config, composition?)` factory for multi-tenant embedders (no process-global side effects).
- Zod schemas for all nine MCP tool success responses (`queryResponseSchema`, `guidedQueryResponseSchema`, etc.) exported from the package root for client-side validation. Success payloads are runtime-validated before return.
- Stable vs experimental response field taxonomy documented in [docs/TOOLS.md](docs/TOOLS.md) and [docs/deprecation-policy.md](docs/deprecation-policy.md#stable-vs-experimental-mcp-response-fields).
- Formal deprecation policy ([docs/deprecation-policy.md](docs/deprecation-policy.md)) and breaking-change release notes template ([docs/templates/breaking-change-release-notes.md](docs/templates/breaking-change-release-notes.md)).

### Changed

- **Breaking (pre-1.0, core):** `ServerContext` constructor second positional argument is now `composition?: ServerContextComposition` (was `client?: PineconeClient`). Migration: use `ServerContext.fromClient(config, client)` or `new ServerContext(config, { client })`.
- `createServer(config, composition?)` now accepts an optional composition object.
- **Breaking (MCP):** Experimental tool response fields are nested under `experimental` on success payloads. Affected tools: `query`, `query_documents`, `guided_query`. Fields moved: `degraded`, `degradation_reason`, `hybrid_leg_failed`, `rerank_skipped_reason` (query-shaped tools); `decision_trace` (`guided_query`). Stable fields (`status`, `results`, `namespace`, etc.) are unchanged. See [MIGRATION.md](docs/MIGRATION.md#unreleased-stable-vs-experimental-response-fields).
- **Breaking (core):** `resolveConfig` requires a Pinecone index name and no longer applies Alliance index/rerank defaults. Removed exported `DEFAULT_INDEX_NAME` and `DEFAULT_RERANK_MODEL` from the package root. Rerank is opt-in when `PINECONE_RERANK_MODEL` / `rerankModel` is unset.
- **Breaking (core):** `setupCoreServer` MCP `instructions` use `CORE_SERVER_INSTRUCTIONS` (no `guided_query` / `suggest_query_params`). `resolveConfig` defaults `disableSuggestFlow` to `true` so `query` / `count` / `query_documents` work without Alliance tools. Alliance CLI / `resolveAllianceConfig` unchanged: gate on by default, `ALLIANCE_SERVER_INSTRUCTIONS`.
- **Alliance CLI / `resolveAllianceConfig`:** When index or rerank env/CLI values are omitted, defaults remain `rag-hybrid` and `bge-reranker-v2-m3` (API-key-only MCP configs unchanged). See [examples/alliance/.env.example](examples/alliance/.env.example).
### Added

- Zod schemas for all nine MCP tool success responses (`queryResponseSchema`, `guidedQueryResponseSchema`, etc.) exported from the package root for client-side validation. Success payloads are runtime-validated before return.
- Stable vs experimental response field taxonomy documented in [docs/TOOLS.md](docs/TOOLS.md) and [docs/deprecation-policy.md](docs/deprecation-policy.md#stable-vs-experimental-mcp-response-fields).
- Formal deprecation policy ([docs/deprecation-policy.md](docs/deprecation-policy.md)) and breaking-change release notes template ([docs/templates/breaking-change-release-notes.md](docs/templates/breaking-change-release-notes.md)).

## [0.2.0] - 2026-05-29

### Changed

- Package root export is the generic **core** layer (`setupCoreServer`); full CLI parity uses `@will-cppa/pinecone-read-only-mcp/alliance` (`setupAllianceServer`, built-in URL generators). `resolveConfig` uses env when set, else defaults: index **`rag-hybrid`**, rerank **`bge-reranker-v2-m3`** (constants `DEFAULT_INDEX_NAME` / `DEFAULT_RERANK_MODEL` in `src/core/config.ts`).
- When reranking was requested but `PineconeClient` has no rerank model (manual library use): `query` / `query_documents` include `rerank_skipped_reason: no_model`; `guided_query` sets `decision_trace.rerank_status: skipped_no_model`.

Expand Down
74 changes: 69 additions & 5 deletions docs/MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const server = await setupAllianceServer(config);

Module-level helpers (`getPineconeClient`, `registerUrlGenerator`, `requireSuggested`, etc.) continue to work; they delegate to a process-default context.

**New (recommended — phase 4 explicit context at setup):**
**New (recommended — phase 4 explicit context at setup):** For one-shot client injection at construction, see [ServerContext composition API](#unreleased-servercontext-composition-api) (`createServer(config, { client })` or `createIsolatedContext`).

```ts
import { createServer, PineconeClient } from '@will-cppa/pinecone-read-only-mcp';
Expand All @@ -103,6 +103,21 @@ import {
} from '@will-cppa/pinecone-read-only-mcp/alliance';

const config = resolveAllianceConfig({ apiKey: process.env.PINECONE_API_KEY! });
const client = new PineconeClient({
apiKey: config.apiKey,
indexName: config.indexName,
sparseIndexName: config.sparseIndexName,
rerankModel: config.rerankModel,
defaultTopK: config.defaultTopK,
requestTimeoutMs: config.requestTimeoutMs,
});
const ctx = createServer(config, { client }); // equivalent to createServer + setClient
const server = await setupAllianceServer({ context: ctx });
```

Alternatively, inject the client after `createServer`:

```ts
const ctx = createServer(config);
ctx.setClient(
new PineconeClient({
Expand All @@ -117,16 +132,23 @@ ctx.setClient(
const server = await setupAllianceServer({ context: ctx });
```

Pass `config` at setup only when the context is not yet configured; after `createServer` + `setClient`, pass `{ context: ctx }` only.
Pass `config` at setup only when the context is not yet configured; after `createServer` + client injection, pass `{ context: ctx }` only.

**Core-only setup** (seven tools, no Alliance builtins):

```ts
import { createServer, PineconeClient, resolveConfig, setupCoreServer } from '@will-cppa/pinecone-read-only-mcp';
import {
createServer,
PineconeClient,
resolveConfig,
setupCoreServer,
} from '@will-cppa/pinecone-read-only-mcp';

const config = resolveConfig({ apiKey: '...', indexName: 'my-index' });
const ctx = createServer(config);
ctx.setClient(new PineconeClient({ /* ... */ }));
const client = new PineconeClient({
/* ... */
});
const ctx = createServer(config, { client });
const server = await setupCoreServer({ context: ctx });
```

Expand All @@ -145,6 +167,48 @@ See also [deprecation-policy.md § Future instance APIs](./deprecation-policy.md

---

## Unreleased: ServerContext composition API

**Rationale:** Embedders can inject client, URL generators, namespace cache seed, and suggest-flow seed at construction without process-global facades.

**Who is affected:** Library embedders calling `new ServerContext(config, client)` directly or building multi-tenant servers.

**Before:**

```ts
new ServerContext(config, pineconeClient);
```

**After:**

```ts
import {
createIsolatedContext,
createServer,
resolveConfig,
setupCoreServer,
ServerContext,
} from '@will-cppa/pinecone-read-only-mcp';

ServerContext.fromClient(config, pineconeClient);
// or
new ServerContext(config, { client: pineconeClient });

// Multi-tenant (no process default):
const config = resolveConfig({ apiKey: '...', indexName: 'my-index' });
const ctx = createIsolatedContext(config, {
client: myClient,
urlGenerators: [['my-ns', myGenerator]],
});
await setupCoreServer({ context: ctx });
```

Suggest-flow gate settings (`disableSuggestFlow`, `cacheTtlMs`) remain on `ServerConfig`, not on composition.

See also [ServerContext instance APIs (phase 1)](#unreleased-servercontext-instance-apis-phase-1) for legacy vs explicit-context setup.

---

## Unreleased: core vs Alliance config defaults

**Rationale:** Generic npm consumers must not silently connect to Alliance infrastructure or inherit Alliance rerank settings when using `resolveConfig` from the package root.
Expand Down
4 changes: 4 additions & 0 deletions src/alliance/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ export const DEFAULT_ALLIANCE_RERANK_MODEL = ALLIANCE_DEFAULT_RERANK_MODEL;
/**
* Build {@link ServerConfig} for Alliance CLI and `setupAllianceServer`.
* Fills index and rerank from Alliance defaults when unset, then calls core `resolveConfig`.
*
* Output is the `config` half of the embedder pattern `{ config, composition }`.
* Pair with {@link createIsolatedContext} or {@link createServer} and an optional
* {@link ServerContextComposition} for per-instance injectables.
*/
export function resolveAllianceConfig(
overrides: ConfigOverrides = {},
Expand Down
7 changes: 7 additions & 0 deletions src/core/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ export interface ConfigOverrides {
* Build a `ServerConfig` from CLI overrides, environment variables, and defaults.
* CLI > env > default precedence is preserved.
*
* Output is the `config` half of the embedder pattern `{ config, composition }`.
* Suggest-flow gate settings (`disableSuggestFlow`, `cacheTtlMs`) belong on the
* returned config. Per-instance injectables (Pinecone client, URL generators,
* namespace cache seed, suggest-flow seed) belong in {@link ServerContextComposition}
* passed to {@link createIsolatedContext} (multi-tenant) or {@link createServer}
* (singleton CLI path).
*
* @throws Error when no API key or index name is provided.
*/
export function resolveConfig(
Expand Down
12 changes: 11 additions & 1 deletion src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@
*/

export { setPineconeClient } from './server/client-context.js';
export { ServerContext, createServer, getDefaultServerContext } from './server/server-context.js';
export {
ServerContext,
createServer,
createIsolatedContext,
getDefaultServerContext,
} from './server/server-context.js';
export type {
ServerContextComposition,
NamespaceCacheSeed,
SuggestionFlowSeedEntry,
} from './server/server-context.js';
export {
validateMetadataFilter,
validateMetadataFilterDetailed,
Expand Down
Loading
Loading