Skip to content

Commit 7507c4d

Browse files
jonathanMLDevzho
andauthored
feat!: explicit Pinecone config, core/alliance split, generic exports (cppalliance#109)
* updated project structure * fixed format check results * updated to use default rerank model * addressed first reviewer's suggestions * update README.md * updated to introduce default index name --------- Co-authored-by: zho <jornathanm910923@gmail.com>
1 parent 56ffc29 commit 7507c4d

81 files changed

Lines changed: 1025 additions & 724 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
# Required: Your Pinecone API key
44
PINECONE_API_KEY=your-pinecone-api-key-here
55

6-
# Optional: Pinecone index name (default: rag-hybrid)
7-
PINECONE_INDEX_NAME=rag-hybrid
6+
# Optional: Dense (hybrid) Pinecone index name (default: rag-hybrid when unset)
7+
# PINECONE_INDEX_NAME=rag-hybrid
88

9-
# Optional: Reranking model (default: bge-reranker-v2-m3)
9+
# Optional: Reranking model (default: bge-reranker-v2-m3 when unset)
1010
PINECONE_RERANK_MODEL=bge-reranker-v2-m3
1111

1212
# Optional: Default number of results to return (default: 10)
@@ -21,7 +21,7 @@ PINECONE_READ_ONLY_MCP_LOG_LEVEL=INFO
2121
PINECONE_READ_ONLY_MCP_LOG_FORMAT=text
2222

2323
# Optional: Sparse index name (default: ${PINECONE_INDEX_NAME}-sparse)
24-
# PINECONE_SPARSE_INDEX_NAME=rag-hybrid-sparse
24+
# PINECONE_SPARSE_INDEX_NAME=my-index-sparse
2525

2626
# Optional: Namespace + suggestion-flow cache TTL in seconds (default: 1800 = 30min)
2727
# PINECONE_CACHE_TTL_SECONDS=1800

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ Tagged releases are published to npm from GitHub Actions when a **GitHub Release
88

99
## [Unreleased]
1010

11+
### Changed
12+
13+
- 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`).
14+
- 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`.
15+
1116
### Added
1217

1318
- `UrlGeneratorFn` type alias (same as `UrlGenerator`) and `RegisterBuiltinUrlGeneratorsOptions` with `reinstallBuiltins` on `registerBuiltinUrlGenerators()` to restore default `mailing` / `slack-Cpplang` generators after overrides; README “Custom URL generators” section and tests for custom registration and built-in override.

README.md

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,24 @@ npm install
8484
npm run build
8585
```
8686

87+
## Architecture
88+
89+
The codebase is split into two layers:
90+
91+
- **`src/core/`** — generic MCP–Pinecone bridge (`PineconeClient`, `resolveConfig`, core MCP tools). Import from `@will-cppa/pinecone-read-only-mcp` (package root).
92+
- **`src/alliance/`** — C++ Alliance app tools (`suggest_query_params`, `guided_query`, Boost/Slack URL builtins). Import from `@will-cppa/pinecone-read-only-mcp/alliance` and call `setupAllianceServer(config)` for the full tool surface (what the CLI uses).
93+
8794
## Configuration
8895

89-
You need a **Pinecone API key** and (by default) a **dense** index plus matching **sparse** index; see [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for every environment variable and CLI flag.
96+
You need a **Pinecone API key**. **Index** uses `PINECONE_INDEX_NAME` when set, else defaults to `rag-hybrid`; sparse index defaults to `{index}-sparse`. **Reranking** uses `PINECONE_RERANK_MODEL` when set, else `bge-reranker-v2-m3`. MCP configs with only `PINECONE_API_KEY` keep prior Alliance defaults. See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for every variable and CLI flag.
9097

9198
Quick reference:
9299

93100
| Variable | Required | Default |
94101
| ----------------------------------- | ----------------------- | --------------------------------- |
95102
| `PINECONE_API_KEY` | Yes (for live Pinecone) ||
96-
| `PINECONE_INDEX_NAME` | No | `rag-hybrid` |
103+
| `PINECONE_INDEX_NAME` | No | `rag-hybrid` when unset |
104+
| `PINECONE_RERANK_MODEL` | No | `bge-reranker-v2-m3` when unset |
97105
| `PINECONE_SPARSE_INDEX_NAME` | No | `{index}-sparse` |
98106
| `PINECONE_READ_ONLY_MCP_LOG_LEVEL` | No | `INFO` (`DEBUG``ERROR`) |
99107
| `PINECONE_READ_ONLY_MCP_LOG_FORMAT` | No | `text` (`json` for log pipelines) |
@@ -102,31 +110,37 @@ Run `pinecone-read-only-mcp --help` for CLI equivalents (`--cache-ttl-seconds`,
102110

103111
### Deployment model
104112

105-
The server uses **process-global** memory for the suggest-flow gate (`suggest_query_params` context), namespaces cache, URL generator registry, and active configuration. **Stdio MCP (one client per Node process)** matches this model. If you embed `setupServer` behind a multi-tenant HTTP transport, isolate those structures per session yourself or treat the suggest-flow guard as best-effort only.
113+
The server uses **process-global** memory for the suggest-flow gate (`suggest_query_params` context), namespaces cache, URL generator registry, and active configuration. **Stdio MCP (one client per Node process)** matches this model. If you embed `setupAllianceServer` behind a multi-tenant HTTP transport, isolate those structures per session yourself or treat the suggest-flow guard as best-effort only.
106114

107-
### Library embedding (`setupServer`)
115+
### Library embedding
108116

109-
Treat **`setupServer()` as one logical server per Node process**: it mutates shared module singletons (suggest-flow map, namespaces cache, URL registry, config context, shared `PineconeClient` slot). A **second** `setupServer()` in the same process **throws** unless you call **`teardownServer()`** first.
117+
Treat **`setupCoreServer()` / `setupAllianceServer()` as one logical server per Node process**: they mutate shared module singletons (suggest-flow map, namespaces cache, URL registry, config context, shared `PineconeClient` slot). A **second** setup call in the same process **throws** unless you call **`teardownServer()`** first.
110118

111-
Recommended pattern: `resolveConfig``setPineconeClient(new PineconeClient(...))``await setupServer(config)` → connect one MCP transport. For tests or re-initialization in the same process, call `teardownServer()` then `setupServer(config)` again. For isolated production tenants, prefer **one server per Node process** (or separate OS processes) rather than sharing one embedder across tenants.
119+
- **Generic bridge only:** `import { setupCoreServer, teardownServer, ... } from '@will-cppa/pinecone-read-only-mcp'`
120+
- **Full Alliance surface (CLI parity):** `import { setupAllianceServer } from '@will-cppa/pinecone-read-only-mcp/alliance'`
112121

113-
Import `setupServer` and `teardownServer` from `@will-cppa/pinecone-read-only-mcp`. See [examples/library-embedding-demo.ts](examples/library-embedding-demo.ts) and [docs/TOOLS.md](docs/TOOLS.md#suggest-flow-gate).
122+
Recommended pattern: `resolveConfig({ apiKey, indexName, ... })``setPineconeClient(new PineconeClient(...))``await setupAllianceServer(config)` → connect one MCP transport. See [examples/library-embedding-demo.ts](examples/library-embedding-demo.ts) and [docs/TOOLS.md](docs/TOOLS.md#suggest-flow-gate).
114123

115124
### Custom URL generators
116125

117126
Namespaces other than `mailing` and `slack-Cpplang` (or different URL rules for any namespace) can use programmatic registration — no fork required.
118127

119-
Import `registerUrlGenerator` and types `UrlGeneratorFn` / `UrlGenerationResult` from `@will-cppa/pinecone-read-only-mcp`. Register **additional** namespaces before tools that emit URLs run (typically right after `setupServer` resolves config). To **replace** the built-in `mailing` or `slack-Cpplang` generators, call `registerUrlGenerator` **after** `setupServer`, because `setupServer` installs the defaults first.
128+
Import `registerUrlGenerator` and types `UrlGeneratorFn` / `UrlGenerationResult` from `@will-cppa/pinecone-read-only-mcp`. Register **additional** namespaces before tools that emit URLs run. Built-in `mailing` / `slack-Cpplang` generators are installed by `setupAllianceServer` (not by `setupCoreServer`).
120129

121130
```ts
122131
import {
132+
PineconeClient,
123133
registerUrlGenerator,
124-
setupServer,
134+
resolveConfig,
135+
setPineconeClient,
125136
type UrlGenerationResult,
126137
type UrlGeneratorFn,
127138
} from '@will-cppa/pinecone-read-only-mcp';
139+
import { setupAllianceServer } from '@will-cppa/pinecone-read-only-mcp/alliance';
128140

129-
const server = await setupServer(config);
141+
const config = resolveConfig({ apiKey: '...', indexName: 'your-index' });
142+
setPineconeClient(new PineconeClient({ apiKey: config.apiKey, indexName: config.indexName }));
143+
const server = await setupAllianceServer(config);
130144

131145
const myDocs: UrlGeneratorFn = (metadata): UrlGenerationResult => {
132146
const id = typeof metadata.doc_id === 'string' ? metadata.doc_id : null;
@@ -146,7 +160,7 @@ A fuller embedding sample lives in [examples/custom-url-generator.ts](examples/c
146160
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
147161
| [examples/suggest-flow-demo.ts](examples/suggest-flow-demo.ts) | Manual **suggest_query_params → query** flow with namespace consistency notes. |
148162
| [examples/guided-query-demo.ts](examples/guided-query-demo.ts) | **guided_query** orchestration and how to read `decision_trace`. |
149-
| [examples/library-embedding-demo.ts](examples/library-embedding-demo.ts) | Programmatic **setupServer** wiring without the CLI binary. |
163+
| [examples/library-embedding-demo.ts](examples/library-embedding-demo.ts) | Programmatic **setupAllianceServer** wiring without the CLI binary. |
150164
| [examples/custom-url-generator.ts](examples/custom-url-generator.ts) | Custom **URL generator** registration for `generate_urls` / row enrichment. |
151165

152166
Run with `npx tsx examples/<file>.ts` from a checkout (requires valid Pinecone env for live paths).
@@ -162,7 +176,9 @@ Add to your `claude_desktop_config.json`:
162176
"command": "npx",
163177
"args": ["-y", "@will-cppa/pinecone-read-only-mcp"],
164178
"env": {
165-
"PINECONE_API_KEY": "your-api-key-here"
179+
"PINECONE_API_KEY": "your-api-key-here",
180+
"PINECONE_INDEX_NAME": "your-index-name"
181+
"PINECONE_RERANK_MODEL": "your-rerank-model"
166182
}
167183
}
168184
}
@@ -230,12 +246,14 @@ node node_modules/@will-cppa/pinecone-read-only-mcp/dist/index.js --api-key YOUR
230246

231247
```
232248
--api-key TEXT Pinecone API key (or set PINECONE_API_KEY env var)
233-
--index-name TEXT Pinecone index name [default: rag-hybrid]
234-
--rerank-model TEXT Reranking model [default: bge-reranker-v2-m3]
249+
--index-name TEXT Dense index (required, or PINECONE_INDEX_NAME)
250+
--rerank-model TEXT Reranker model (defalut: bge-reranker-v2-m3)
235251
--log-level TEXT Logging level [default: INFO]
236252
--help, -h Show help message
237253
```
238254

255+
Run `pinecone-read-only-mcp --help` for the full option list.
256+
239257
## Deployment
240258

241259
### Production Readiness Defaults
@@ -264,7 +282,7 @@ docker build -t pinecone-read-only-mcp:latest .
264282
# run (stdio MCP server)
265283
docker run --rm -i \
266284
-e PINECONE_API_KEY=YOUR_API_KEY \
267-
-e PINECONE_INDEX_NAME=rag-hybrid \
285+
-e PINECONE_INDEX_NAME=your-index-name \
268286
pinecone-read-only-mcp:latest
269287
```
270288

@@ -436,7 +454,7 @@ Returns the **unique document count** matching a metadata filter and semantic qu
436454

437455
### `keyword_search`
438456

439-
Performs **keyword (lexical/sparse-only)** search over the dedicated sparse index (default: `rag-hybrid-sparse`, i.e. `{PINECONE_INDEX_NAME}-sparse`). Use for exact or keyword-style queries. Does not use the dense index or semantic reranking. Call `list_namespaces` first to discover namespaces; `suggest_query_params` is optional.
457+
Performs **keyword (lexical/sparse-only)** search over the sparse index (`{PINECONE_INDEX_NAME}-sparse` by default). Use for exact or keyword-style queries. Does not use the dense index or semantic reranking. Call `list_namespaces` first to discover namespaces; `suggest_query_params` is optional.
440458

441459
**Parameters:**
442460

@@ -457,7 +475,7 @@ Performs **keyword (lexical/sparse-only)** search over the dedicated sparse inde
457475
"status": "success",
458476
"query": "contracts C++",
459477
"namespace": "wg21-papers",
460-
"index": "rag-hybrid-sparse",
478+
"index": "your-index-sparse",
461479
"result_count": 5,
462480
"results": [
463481
{
@@ -624,7 +642,7 @@ The script prints a table of p50, p95, and p99 latencies in milliseconds and wri
624642
PINECONE_API_KEY=your-key npm run test:search
625643
```
626644

627-
If the sparse index (`rag-hybrid-sparse` by default) does not exist or has no data, the keyword search step is skipped with a warning.
645+
If the sparse index (`{PINECONE_INDEX_NAME}-sparse`) does not exist or has no data, the keyword search step is skipped with a warning.
628646

629647
2. **Via MCP client:**
630648
Start the server and call the `keyword_search` tool with `query_text`, `namespace` (from `list_namespaces`), and optional `top_k` or `metadata_filter`. Response shape is the same as the `query` tool (e.g. `results` with ids, metadata, scores; `reranked` is always `false`).

docs/CONFIGURATION.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Configuration is built from **CLI flags** (when using the binary), **environment
66

77
**CLI / `ConfigOverrides` > environment variables > built-in defaults.**
88

9-
`resolveConfig` in `src/config.ts` applies this order for each field.
9+
`resolveConfig` in `src/core/config.ts` applies this order for each field.
1010

1111
---
1212

@@ -15,9 +15,9 @@ Configuration is built from **CLI flags** (when using the binary), **environment
1515
| Field | Source | Default / notes |
1616
| ----- | ------ | --------------- |
1717
| `apiKey` | `apiKey` / `PINECONE_API_KEY` | **Required** (non-empty after trim) |
18-
| `indexName` | `indexName` / `PINECONE_INDEX_NAME` | `rag-hybrid` |
18+
| `indexName` | `indexName` / `PINECONE_INDEX_NAME` | `rag-hybrid` when env and overrides omit it |
1919
| `sparseIndexName` | `sparseIndexName` / `PINECONE_SPARSE_INDEX_NAME` | `{indexName}-sparse` |
20-
| `rerankModel` | `rerankModel` / `PINECONE_RERANK_MODEL` | `bge-reranker-v2-m3` |
20+
| `rerankModel` | `rerankModel` / `PINECONE_RERANK_MODEL` | `bge-reranker-v2-m3` when env and overrides omit it |
2121
| `defaultTopK` | `defaultTopK` / `PINECONE_TOP_K` | `10` (positive int) |
2222
| `logLevel` | `logLevel` / `PINECONE_READ_ONLY_MCP_LOG_LEVEL` | `INFO` (`DEBUG``ERROR`) |
2323
| `logFormat` | `logFormat` / `PINECONE_READ_ONLY_MCP_LOG_FORMAT` | `text` or `json` |
@@ -28,6 +28,12 @@ Configuration is built from **CLI flags** (when using the binary), **environment
2828

2929
**Throws** if `apiKey` is missing after trim.
3030

31+
For the full Alliance tool surface (including `suggest_query_params`, `guided_query`, and built-in URL generators), import from `@will-cppa/pinecone-read-only-mcp/alliance` and call `setupAllianceServer(config)`.
32+
33+
### Rerank model
34+
35+
`resolveConfig` uses `PINECONE_INDEX_NAME` / `PINECONE_RERANK_MODEL` when set; otherwise **`rag-hybrid`** and **`bge-reranker-v2-m3`**. MCP configs that only set `PINECONE_API_KEY` keep the same defaults as before.
36+
3137
---
3238

3339
## CLI flags (`parseCli` / `src/cli.ts`)
@@ -52,9 +58,9 @@ Configuration is built from **CLI flags** (when using the binary), **environment
5258

5359
## Library embedding
5460

55-
1. Build `ServerConfig` with `resolveConfig({ apiKey: '...', ... })` or pass explicit overrides.
56-
2. Construct `PineconeClient` and `setPineconeClient(client)` before `setupServer(config)` (mirrors `src/index.ts`).
57-
3. `await setupServer(config)` then connect an MCP transport.
61+
1. Build `ServerConfig` with `resolveConfig({ apiKey: '...', indexName: '...', ... })` or pass explicit overrides.
62+
2. Construct `PineconeClient` and `setPineconeClient(client)` before `setupAllianceServer(config)` (mirrors `src/index.ts`).
63+
3. `await setupAllianceServer(config)` (or `setupCoreServer` for generic tools only) then connect an MCP transport.
5864

5965
See [README deployment model](../README.md#deployment-model) and [examples/library-embedding-demo.ts](../examples/library-embedding-demo.ts).
6066

examples/README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# Examples
22

3-
| File | Description |
4-
|------|-------------|
5-
| [custom-url-generator.ts](./custom-url-generator.ts) | Embed the MCP server as a library, register a **custom URL generator** for a namespace, and wire `PineconeClient` + `setupServer()`. |
6-
| [suggest-flow-demo.ts](./suggest-flow-demo.ts) | Document the **suggest_query_params → query** gate sequence and trimmed namespace usage. |
7-
| [guided-query-demo.ts](./guided-query-demo.ts) | Document **guided_query** and the **`decision_trace`** payload. |
8-
| [library-embedding-demo.ts](./library-embedding-demo.ts) | Minimal **library embedding** (`resolveConfig`, `setPineconeClient`, `setupServer`). |
3+
| File | Description |
4+
| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
5+
| [custom-url-generator.ts](./custom-url-generator.ts) | Embed the MCP server, register a **custom URL generator**, and call `setupAllianceServer()` (full tool surface). |
6+
| [suggest-flow-demo.ts](./suggest-flow-demo.ts) | Document the **suggest_query_params → query** gate sequence and trimmed namespace usage. |
7+
| [guided-query-demo.ts](./guided-query-demo.ts) | Document **guided_query** and the **`decision_trace`** payload. |
8+
| [library-embedding-demo.ts](./library-embedding-demo.ts) | Minimal **library embedding** (`resolveConfig`, `setPineconeClient`, `setupAllianceServer`). |
99

10-
Run with `npx tsx examples/<file>.ts` after `npm install` (live Pinecone calls need `PINECONE_API_KEY` and related env).
10+
**Required env for live runs:** `PINECONE_API_KEY`. Optional: `PINECONE_INDEX_NAME` (default `rag-hybrid`), `PINECONE_RERANK_MODEL` (default `bge-reranker-v2-m3`).
11+
12+
Run with `npm run build` then `npx tsx examples/<file>.ts` from the repo root (examples resolve the package via `dist/core` and `dist/alliance`).

0 commit comments

Comments
 (0)