@esankhan3/code-search-mcp 1.1.5 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,7 +20,10 @@ const ENV_KEYS = [
20
20
  "CODE_SEARCH_AUTH_MODE",
21
21
  "CODE_SEARCH_AUTH_API_KEYS",
22
22
  "CODE_SEARCH_DATA_DIR",
23
- "CODE_SEARCH_REINDEX_INTERVAL"
23
+ "CODE_SEARCH_REINDEX_INTERVAL",
24
+ "CODE_SEARCH_EMBEDDING_HEADERS",
25
+ "CODE_SEARCH_LLM_HEADERS",
26
+ "ANVIL_LLM_HEADERS"
24
27
  ];
25
28
  let tmp = "";
26
29
  const STASH = {};
@@ -105,6 +108,35 @@ describe("toKnowledgeConfig (P3 adapter)", () => {
105
108
  assert.equal(r.provider, cfg.reranker.provider);
106
109
  });
107
110
  });
111
+ describe("gateway request headers", () => {
112
+ const RAW = "CF-Access-Client-Id=id.access,CF-Access-Client-Secret=s3cret";
113
+ const PARSED = { "CF-Access-Client-Id": "id.access", "CF-Access-Client-Secret": "s3cret" };
114
+ it("CODE_SEARCH_EMBEDDING_HEADERS reach the embedder config", () => {
115
+ process.env.CODE_SEARCH_EMBEDDING_HEADERS = RAW;
116
+ const cfg = resolveCodeSearchConfig({ configPath: join(tmp, "missing.yaml") });
117
+ assert.deepEqual(cfg.embedding.headers, PARSED);
118
+ assert.deepEqual(toKnowledgeConfig(cfg).embedding.headers, PARSED);
119
+ });
120
+ it("CODE_SEARCH_LLM_HEADERS reach agent-core as ANVIL_LLM_HEADERS", () => {
121
+ process.env.CODE_SEARCH_LLM_HEADERS = RAW;
122
+ const cfg = resolveCodeSearchConfig({ configPath: join(tmp, "missing.yaml") });
123
+ assert.deepEqual(cfg.llm.headers, PARSED);
124
+ assert.equal(process.env.ANVIL_LLM_HEADERS, RAW);
125
+ });
126
+ it("llm.headers from YAML reach agent-core too", () => {
127
+ const file = join(tmp, "config.yaml");
128
+ writeFileSync(file, "llm:\n headers:\n CF-Access-Client-Id: id.access\n CF-Access-Client-Secret: s3cret\n");
129
+ resolveCodeSearchConfig({ configPath: file });
130
+ assert.equal(process.env.ANVIL_LLM_HEADERS, RAW);
131
+ });
132
+ it("--print-config redacts every header value", () => {
133
+ const out = redactSecrets({ embedding: { headers: PARSED }, llm: { headers: PARSED } });
134
+ for (const h of [out.embedding.headers, out.llm.headers]) {
135
+ assert.match(h["CF-Access-Client-Id"], /redacted/);
136
+ assert.match(h["CF-Access-Client-Secret"], /redacted/);
137
+ }
138
+ });
139
+ });
108
140
  describe("redactSecrets (P3 --print-config)", () => {
109
141
  it("redacts apiKey/jwtSecret/token fields, preserves shape", () => {
110
142
  const input = {
@@ -241,6 +241,7 @@ function envLayer() {
241
241
  dimensions: embedDims ? parseInt(embedDims, 10) : void 0,
242
242
  apiKey: env("EMBEDDING_API_KEY"),
243
243
  baseUrl: env("EMBEDDING_BASE_URL"),
244
+ headers: parseHeaders(env("EMBEDDING_HEADERS")),
244
245
  ollamaHost: env("OLLAMA_HOST") ?? process.env.OLLAMA_HOST
245
246
  },
246
247
  reranker: {
@@ -268,6 +269,7 @@ function envLayer() {
268
269
  model: env("LLM_MODEL"),
269
270
  apiKey: env("LLM_API_KEY") ?? process.env.ANTHROPIC_API_KEY ?? process.env.OPENAI_API_KEY,
270
271
  baseUrl: env("LLM_BASE_URL"),
272
+ headers: parseHeaders(env("LLM_HEADERS")),
271
273
  claudeBin: env("CLAUDE_BIN") ?? process.env.CLAUDE_BIN
272
274
  },
273
275
  github: {
@@ -420,6 +422,9 @@ function bridgeLegacyEnvVars(cfg) {
420
422
  process.env.ANVIL_LLM_MODEL ??= process.env.CODE_SEARCH_LLM_MODEL ?? cfg.llm.model;
421
423
  if (cfg.llm.apiKey) process.env.ANVIL_LLM_API_KEY ??= cfg.llm.apiKey;
422
424
  if (cfg.llm.baseUrl) process.env.ANVIL_LLM_BASE_URL ??= cfg.llm.baseUrl;
425
+ if (cfg.llm.headers) {
426
+ process.env.ANVIL_LLM_HEADERS ??= Object.entries(cfg.llm.headers).map(([k, v]) => `${k}=${v}`).join(",");
427
+ }
423
428
  if (cfg.llm.claudeBin) process.env.ANVIL_CLAUDE_BIN ??= cfg.llm.claudeBin;
424
429
  }
425
430
  function toKnowledgeConfig(c) {
@@ -454,7 +459,7 @@ function redactSecrets(value, parentKey = "") {
454
459
  if (isPlainObject(value)) {
455
460
  const out = {};
456
461
  for (const [k, v] of Object.entries(value)) {
457
- const secret = SECRET_KEY.test(k) || parentKey === "otelHeaders";
462
+ const secret = SECRET_KEY.test(k) || parentKey === "otelHeaders" || parentKey === "headers";
458
463
  if (secret && typeof v === "string" && v.length > 0) {
459
464
  out[k] = redactString(v);
460
465
  } else if (secret && Array.isArray(v)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esankhan3/code-search-mcp",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "description": "MCP server for multi-repo code search \u2014 GitHub org or local path, zero config",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -23,8 +23,8 @@
23
23
  "smoke": "bash scripts/smoke/run-smoke.sh"
24
24
  },
25
25
  "dependencies": {
26
- "@esankhan3/anvil-agent-core": "^0.5.3",
27
- "@esankhan3/anvil-knowledge-core": "^0.4.11",
26
+ "@esankhan3/anvil-agent-core": "^0.5.4",
27
+ "@esankhan3/anvil-knowledge-core": "^0.4.12",
28
28
  "@modelcontextprotocol/node": "^2.0.0",
29
29
  "@modelcontextprotocol/server": "^2.0.0"
30
30
  },