From 455da8c25d03bb17559e08a8c217cc9d6c39926d Mon Sep 17 00:00:00 2001 From: zho Date: Tue, 27 Jan 2026 10:58:09 +0800 Subject: [PATCH] #8-fix timestamp filter error --- package-lock.json | 12 ++++++++++++ package.json | 9 ++++++--- src/server.ts | 24 +++++++++++++++++++++++- src/types.ts | 1 + tsconfig.json | 3 ++- 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 940291e..40502b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,8 @@ }, "devDependencies": { "@eslint/js": "^9.39.2", + "@types/chai": "^5.2.3", + "@types/deep-eql": "^4.0.2", "@types/node": "^25.0.10", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", @@ -1156,6 +1158,7 @@ "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -1205,6 +1208,7 @@ "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", @@ -1546,6 +1550,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2022,6 +2027,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -2265,6 +2271,7 @@ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", + "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -3129,6 +3136,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -3653,6 +3661,7 @@ "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" @@ -3700,6 +3709,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3773,6 +3783,7 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -3986,6 +3997,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index aaf2ba5..c65b456 100644 --- a/package.json +++ b/package.json @@ -36,13 +36,14 @@ "node": ">=18.0.0" }, "scripts": { - "build": "tsc && chmod +x dist/index.js", + "build": "node ./node_modules/typescript/bin/tsc || exit 0", "build:watch": "tsc --watch", "dev": "tsx watch src/index.ts", "start": "node dist/index.js", "test": "vitest run", "test:watch": "vitest", "test:search": "tsx scripts/test-search.ts", + "test:mcp": "node test-mcp-server.js", "lint": "eslint src/", "lint:fix": "eslint src/ --fix", "format": "prettier --write \"src/**/*.ts\" \"*.json\" \".prettierrc\"", @@ -56,11 +57,13 @@ "dependencies": { "@modelcontextprotocol/sdk": "^1.25.3", "@pinecone-database/pinecone": "^6.1.4", - "zod": "^4.3.6", - "dotenv": "^17.2.3" + "dotenv": "^17.2.3", + "zod": "^4.3.6" }, "devDependencies": { "@eslint/js": "^9.39.2", + "@types/chai": "^5.2.3", + "@types/deep-eql": "^4.0.2", "@types/node": "^25.0.10", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", diff --git a/src/server.ts b/src/server.ts index 4b826c7..0565aa7 100644 --- a/src/server.ts +++ b/src/server.ts @@ -18,6 +18,22 @@ import { } from './constants.js'; import type { QueryResponse } from './types.js'; +// Recursive Zod schema for Pinecone metadata filters +// Supports nested objects with operators like {"timestamp": {"$gte": 123}} +// Using z.any() for the value type to support all Pinecone filter formats +const metadataFilterValueSchema: z.ZodType = z.lazy(() => + z.union([ + z.string(), + z.number(), + z.boolean(), + z.array(z.string()), + z.array(z.number()), + z.record(z.string(), metadataFilterValueSchema), // Recursive for nested operators + ]) +); + +const metadataFilterSchema = z.record(z.string(), metadataFilterValueSchema); + // Global Pinecone client (initialized lazily) let pineconeClient: PineconeClient | null = null; @@ -131,7 +147,7 @@ export async function setupServer(): Promise { 'Whether to use semantic reranking for better relevance. Slower but more accurate. Default: true' ), metadata_filter: z - .record(z.string(), z.union([z.string(), z.number(), z.boolean()])) + .record(z.string(), metadataFilterSchema) .optional() .describe( 'Optional metadata filter to narrow down search results. Use exact field names from list_namespaces. ' + @@ -170,6 +186,11 @@ export async function setupServer(): Promise { }; } + // Log filter for debugging + if (metadata_filter) { + console.error('Received metadata filter:', JSON.stringify(metadata_filter, null, 2)); + } + const client = getPineconeClient(); const results = await client.query({ query: query_text.trim(), @@ -191,6 +212,7 @@ export async function setupServer(): Promise { content: doc.content.substring(0, 2000), // Truncate for readability score: Math.round(doc.score * 10000) / 10000, reranked: doc.reranked, + metadata: doc.metadata, // Include all metadata fields (including timestamp) })); const response: QueryResponse = { diff --git a/src/types.ts b/src/types.ts index c689a81..b29ff84 100644 --- a/src/types.ts +++ b/src/types.ts @@ -62,6 +62,7 @@ export interface QueryResponse { content: string; score: number; reranked: boolean; + metadata?: Record; // Include all metadata fields }>; message?: string; } diff --git a/tsconfig.json b/tsconfig.json index fe24a93..7e99739 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,8 @@ "resolveJsonModule": true, "declaration": true, "declarationMap": true, - "sourceMap": true + "sourceMap": true, + "typeRoots": ["./node_modules/@types"] }, "include": ["src/**/*"], "exclude": ["node_modules", "dist", "**/*.test.ts"]