Skip to content

Commit 435dcdd

Browse files
jonathanMLDevzho
andauthored
ServerContext Accepts Context Param (cppalliance#162)
* ServerContext Accepts Context Param * addressed ai reviews --------- Co-authored-by: zho <jornathanm910923@gmail.com>
1 parent ba5429f commit 435dcdd

9 files changed

Lines changed: 497 additions & 27 deletions

File tree

CHANGELOG.md

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,25 @@ Tagged releases are published to npm from GitHub Actions when a **GitHub Release
88

99
## [Unreleased]
1010

11+
### Added
12+
13+
- `ServerContextComposition` interface plus `NamespaceCacheSeed` and `SuggestionFlowSeedEntry` types for dependency injection into `ServerContext`.
14+
- `createIsolatedContext(config, composition?)` factory for multi-tenant embedders (no process-global side effects).
15+
- 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.
16+
- 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).
17+
- 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)).
18+
1119
### Changed
1220

21+
- **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 })`.
22+
- `createServer(config, composition?)` now accepts an optional composition object.
1323
- **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).
1424
- **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.
1525
- **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`.
1626
- **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).
17-
### Added
18-
19-
- 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.
20-
- 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).
21-
- 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)).
2227

2328
## [0.2.0] - 2026-05-29
2429

25-
### Changed
26-
2730
- 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`).
2831
- 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`.
2932

docs/MIGRATION.md

Lines changed: 69 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ const server = await setupAllianceServer(config);
9393

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

96-
**New (recommended — phase 4 explicit context at setup):**
96+
**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`).
9797

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

105105
const config = resolveAllianceConfig({ apiKey: process.env.PINECONE_API_KEY! });
106+
const client = new PineconeClient({
107+
apiKey: config.apiKey,
108+
indexName: config.indexName,
109+
sparseIndexName: config.sparseIndexName,
110+
rerankModel: config.rerankModel,
111+
defaultTopK: config.defaultTopK,
112+
requestTimeoutMs: config.requestTimeoutMs,
113+
});
114+
const ctx = createServer(config, { client }); // equivalent to createServer + setClient
115+
const server = await setupAllianceServer({ context: ctx });
116+
```
117+
118+
Alternatively, inject the client after `createServer`:
119+
120+
```ts
106121
const ctx = createServer(config);
107122
ctx.setClient(
108123
new PineconeClient({
@@ -117,16 +132,23 @@ ctx.setClient(
117132
const server = await setupAllianceServer({ context: ctx });
118133
```
119134

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

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

124139
```ts
125-
import { createServer, PineconeClient, resolveConfig, setupCoreServer } from '@will-cppa/pinecone-read-only-mcp';
140+
import {
141+
createServer,
142+
PineconeClient,
143+
resolveConfig,
144+
setupCoreServer,
145+
} from '@will-cppa/pinecone-read-only-mcp';
126146

127147
const config = resolveConfig({ apiKey: '...', indexName: 'my-index' });
128-
const ctx = createServer(config);
129-
ctx.setClient(new PineconeClient({ /* ... */ }));
148+
const client = new PineconeClient({
149+
/* ... */
150+
});
151+
const ctx = createServer(config, { client });
130152
const server = await setupCoreServer({ context: ctx });
131153
```
132154

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

146168
---
147169

170+
## Unreleased: ServerContext composition API
171+
172+
**Rationale:** Embedders can inject client, URL generators, namespace cache seed, and suggest-flow seed at construction without process-global facades.
173+
174+
**Who is affected:** Library embedders calling `new ServerContext(config, client)` directly or building multi-tenant servers.
175+
176+
**Before:**
177+
178+
```ts
179+
new ServerContext(config, pineconeClient);
180+
```
181+
182+
**After:**
183+
184+
```ts
185+
import {
186+
createIsolatedContext,
187+
createServer,
188+
resolveConfig,
189+
setupCoreServer,
190+
ServerContext,
191+
} from '@will-cppa/pinecone-read-only-mcp';
192+
193+
ServerContext.fromClient(config, pineconeClient);
194+
// or
195+
new ServerContext(config, { client: pineconeClient });
196+
197+
// Multi-tenant (no process default):
198+
const config = resolveConfig({ apiKey: '...', indexName: 'my-index' });
199+
const ctx = createIsolatedContext(config, {
200+
client: myClient,
201+
urlGenerators: [['my-ns', myGenerator]],
202+
});
203+
await setupCoreServer({ context: ctx });
204+
```
205+
206+
Suggest-flow gate settings (`disableSuggestFlow`, `cacheTtlMs`) remain on `ServerConfig`, not on composition.
207+
208+
See also [ServerContext instance APIs (phase 1)](#unreleased-servercontext-instance-apis-phase-1) for legacy vs explicit-context setup.
209+
210+
---
211+
148212
## Unreleased: core vs Alliance config defaults
149213

150214
**Rationale:** Generic npm consumers must not silently connect to Alliance infrastructure or inherit Alliance rerank settings when using `resolveConfig` from the package root.

src/alliance/config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ export const DEFAULT_ALLIANCE_RERANK_MODEL = ALLIANCE_DEFAULT_RERANK_MODEL;
2222
/**
2323
* Build {@link ServerConfig} for Alliance CLI and `setupAllianceServer`.
2424
* Fills index and rerank from Alliance defaults when unset, then calls core `resolveConfig`.
25+
*
26+
* Output is the `config` half of the embedder pattern `{ config, composition }`.
27+
* Pair with {@link createIsolatedContext} or {@link createServer} and an optional
28+
* {@link ServerContextComposition} for per-instance injectables.
2529
*/
2630
export function resolveAllianceConfig(
2731
overrides: ConfigOverrides = {},

src/core/config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ export interface ConfigOverrides {
101101
* Build a `ServerConfig` from CLI overrides, environment variables, and defaults.
102102
* CLI > env > default precedence is preserved.
103103
*
104+
* Output is the `config` half of the embedder pattern `{ config, composition }`.
105+
* Suggest-flow gate settings (`disableSuggestFlow`, `cacheTtlMs`) belong on the
106+
* returned config. Per-instance injectables (Pinecone client, URL generators,
107+
* namespace cache seed, suggest-flow seed) belong in {@link ServerContextComposition}
108+
* passed to {@link createIsolatedContext} (multi-tenant) or {@link createServer}
109+
* (singleton CLI path).
110+
*
104111
* @throws Error when no API key or index name is provided.
105112
*/
106113
export function resolveConfig(

src/core/index.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,17 @@
77
*/
88

99
export { setPineconeClient } from './server/client-context.js';
10-
export { ServerContext, createServer, getDefaultServerContext } from './server/server-context.js';
10+
export {
11+
ServerContext,
12+
createServer,
13+
createIsolatedContext,
14+
getDefaultServerContext,
15+
} from './server/server-context.js';
16+
export type {
17+
ServerContextComposition,
18+
NamespaceCacheSeed,
19+
SuggestionFlowSeedEntry,
20+
} from './server/server-context.js';
1121
export {
1222
validateMetadataFilter,
1323
validateMetadataFilterDetailed,

0 commit comments

Comments
 (0)