@fre4x/grok 1.0.64 → 1.0.65-beta.1

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.
Files changed (3) hide show
  1. package/README.md +2 -0
  2. package/dist/index.js +75 -22
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -18,6 +18,8 @@ xAI's Grok is more than an LLM. It's a real-time sensor for the global conscious
18
18
 
19
19
  Search tools support `limit` and `offset` pagination and return normalized results with citations.
20
20
 
21
+ `grok_search_x` accepts `allowed_x_handles`, `excluded_x_handles`, `from_date`, `to_date`, `enable_image_understanding`, and `enable_video_understanding`. `grok_search_web` accepts `allowed_domains`, `excluded_domains`, and `enable_image_understanding`. Include and exclude filters are mutually exclusive per tool, and web domain filters follow xAI's max-5 constraint.
22
+
21
23
  Image generation responses include direct MCP `image` content blocks when media can be embedded. Video responses include direct MCP embedded `resource` blobs because MCP does not define a dedicated `video` content block.
22
24
 
23
25
  ## Configuration
package/dist/index.js CHANGED
@@ -3498,7 +3498,7 @@ var require_schemes = __commonJS({
3498
3498
  serialize: httpSerialize
3499
3499
  }
3500
3500
  );
3501
- var https2 = (
3501
+ var https3 = (
3502
3502
  /** @type {SchemeHandler} */
3503
3503
  {
3504
3504
  scheme: "https",
@@ -3547,7 +3547,7 @@ var require_schemes = __commonJS({
3547
3547
  /** @type {Record<SchemeName, SchemeHandler>} */
3548
3548
  {
3549
3549
  http: http3,
3550
- https: https2,
3550
+ https: https3,
3551
3551
  ws,
3552
3552
  wss,
3553
3553
  urn,
@@ -16763,7 +16763,7 @@ var require_form_data = __commonJS({
16763
16763
  var util4 = __require("util");
16764
16764
  var path3 = __require("path");
16765
16765
  var http3 = __require("http");
16766
- var https2 = __require("https");
16766
+ var https3 = __require("https");
16767
16767
  var parseUrl = __require("url").parse;
16768
16768
  var fs3 = __require("fs");
16769
16769
  var Stream = __require("stream").Stream;
@@ -17032,7 +17032,7 @@ var require_form_data = __commonJS({
17032
17032
  }
17033
17033
  options.headers = this.getHeaders(params.headers);
17034
17034
  if (options.protocol === "https:") {
17035
- request = https2.request(options);
17035
+ request = https3.request(options);
17036
17036
  } else {
17037
17037
  request = http3.request(options);
17038
17038
  }
@@ -17945,7 +17945,7 @@ var require_follow_redirects = __commonJS({
17945
17945
  var url3 = __require("url");
17946
17946
  var URL2 = url3.URL;
17947
17947
  var http3 = __require("http");
17948
- var https2 = __require("https");
17948
+ var https3 = __require("https");
17949
17949
  var Writable = __require("stream").Writable;
17950
17950
  var assert2 = __require("assert");
17951
17951
  var debug = require_debug();
@@ -18430,7 +18430,7 @@ var require_follow_redirects = __commonJS({
18430
18430
  function isURL(value) {
18431
18431
  return URL2 && value instanceof URL2;
18432
18432
  }
18433
- module.exports = wrap({ http: http3, https: https2 });
18433
+ module.exports = wrap({ http: http3, https: https3 });
18434
18434
  module.exports.wrap = wrap;
18435
18435
  }
18436
18436
  });
@@ -32560,9 +32560,11 @@ import * as crypto from "node:crypto";
32560
32560
  var PersistentCache = class {
32561
32561
  cacheDir;
32562
32562
  memoryCache = /* @__PURE__ */ new Map();
32563
- constructor(namespace) {
32564
- const baseDir = process.env.FRE4X_CACHE_DIR || path.join(os.homedir(), ".fre4x-cache");
32563
+ onDiskWriteError;
32564
+ constructor(namespace, options = {}) {
32565
+ const baseDir = options.dir ?? process.env.FRE4X_CACHE_DIR ?? path.join(os.homedir(), ".fre4x-cache");
32565
32566
  this.cacheDir = path.join(baseDir, namespace);
32567
+ this.onDiskWriteError = options.onDiskWriteError;
32566
32568
  }
32567
32569
  async ensureDir() {
32568
32570
  await fs.mkdir(this.cacheDir, { recursive: true });
@@ -32606,7 +32608,7 @@ var PersistentCache = class {
32606
32608
  const fpath = this.getFilePath(key);
32607
32609
  await fs.writeFile(fpath, JSON.stringify(entry), "utf8");
32608
32610
  } catch (error48) {
32609
- console.error(`[Cache] Failed to save to disk: ${error48}`);
32611
+ this.onDiskWriteError?.(error48);
32610
32612
  }
32611
32613
  }
32612
32614
  async wrap(key, ttlMs, fetchFn) {
@@ -45933,6 +45935,9 @@ var {
45933
45935
  mergeConfig: mergeConfig2
45934
45936
  } = axios_default;
45935
45937
 
45938
+ // src/index.ts
45939
+ import https2 from "node:https";
45940
+
45936
45941
  // src/mock.ts
45937
45942
  var IS_MOCK = process.env.MOCK === "true" || process.env.GROK_MOCK === "true";
45938
45943
  var MOCK_FIXTURES = {
@@ -46071,16 +46076,29 @@ var MOCK_VIDEO_BASE64 = "AAAAHGZ0eXBpc29tAAAAAGlzb21pc28yYXZjMQ==";
46071
46076
  function getErrorMessage(error48) {
46072
46077
  return error48 instanceof Error ? error48.message : String(error48);
46073
46078
  }
46079
+ var isoDatePattern = /^\d{4}-\d{2}-\d{2}$/;
46080
+ var isoDateOrDateTimeSchema = z3.string().refine(
46081
+ (value) => isoDatePattern.test(value) || z3.string().datetime({ offset: true }).safeParse(value).success,
46082
+ "must be an ISO8601 date or datetime with timezone"
46083
+ );
46084
+ function parseSearchDate(value) {
46085
+ return isoDatePattern.test(value) ? Date.parse(`${value}T00:00:00Z`) : Date.parse(value);
46086
+ }
46074
46087
  var xSearchSchema = paginationSchema.extend({
46075
46088
  query: z3.string().min(1).max(500),
46076
- allowed_handles: z3.array(z3.string().min(1).max(50)).max(10).optional(),
46077
- from_date: z3.string().datetime({ offset: true }).optional(),
46078
- to_date: z3.string().datetime({ offset: true }).optional(),
46089
+ allowed_x_handles: z3.array(z3.string().min(1).max(50)).max(10).optional(),
46090
+ excluded_x_handles: z3.array(z3.string().min(1).max(50)).max(10).optional(),
46091
+ from_date: isoDateOrDateTimeSchema.optional(),
46092
+ to_date: isoDateOrDateTimeSchema.optional(),
46093
+ enable_image_understanding: z3.boolean().default(false),
46094
+ enable_video_understanding: z3.boolean().default(false),
46079
46095
  output_dir: z3.string().optional()
46080
46096
  }).strict();
46081
46097
  var webSearchSchema = paginationSchema.extend({
46082
46098
  query: z3.string().min(1).max(500),
46083
- allowed_domains: z3.array(z3.string().min(1).max(255)).max(20).optional(),
46099
+ allowed_domains: z3.array(z3.string().min(1).max(255)).max(5).optional(),
46100
+ excluded_domains: z3.array(z3.string().min(1).max(255)).max(5).optional(),
46101
+ enable_image_understanding: z3.boolean().default(false),
46084
46102
  output_dir: z3.string().optional()
46085
46103
  }).strict();
46086
46104
  var imagineSchema = z3.object({
@@ -46110,6 +46128,8 @@ var cache = new PersistentCache("grok");
46110
46128
  var SEARCH_CACHE_TTL = 30 * 60 * 1e3;
46111
46129
  var xaiClient = axios_default.create({
46112
46130
  baseURL: "https://api.x.ai/v1",
46131
+ // ⚡ Bolt: Use HTTP Keep-Alive connection pooling to reduce expensive TCP/TLS handshakes on repeated calls
46132
+ httpsAgent: new https2.Agent({ keepAlive: true }),
46113
46133
  headers: {
46114
46134
  Authorization: `Bearer ${XAI_API_KEY || "mock-key"}`,
46115
46135
  "Content-Type": "application/json"
@@ -46134,15 +46154,24 @@ function getValidationResult(error48) {
46134
46154
  async function handleGrokSearchX(params, client = xaiClient) {
46135
46155
  const {
46136
46156
  query,
46137
- allowed_handles,
46157
+ allowed_x_handles,
46158
+ excluded_x_handles,
46138
46159
  from_date,
46139
46160
  to_date,
46161
+ enable_image_understanding,
46162
+ enable_video_understanding,
46140
46163
  limit,
46141
46164
  offset,
46142
46165
  output_dir
46143
46166
  } = params;
46144
46167
  try {
46145
- if (from_date && to_date && from_date > to_date) {
46168
+ if (allowed_x_handles && excluded_x_handles) {
46169
+ return createValidationError(
46170
+ "allowed_x_handles",
46171
+ "cannot be used together with excluded_x_handles"
46172
+ );
46173
+ }
46174
+ if (from_date && to_date && parseSearchDate(from_date) > parseSearchDate(to_date)) {
46146
46175
  return createValidationError(
46147
46176
  "from_date",
46148
46177
  "must be earlier than or equal to to_date"
@@ -46151,9 +46180,12 @@ async function handleGrokSearchX(params, client = xaiClient) {
46151
46180
  const cacheKey = JSON.stringify({
46152
46181
  tool: "grok_search_x",
46153
46182
  query,
46154
- allowed_handles,
46183
+ allowed_x_handles,
46184
+ excluded_x_handles,
46155
46185
  from_date,
46156
- to_date
46186
+ to_date,
46187
+ enable_image_understanding,
46188
+ enable_video_understanding
46157
46189
  });
46158
46190
  const rawResponse = await cache.wrap(
46159
46191
  cacheKey,
@@ -46167,9 +46199,12 @@ async function handleGrokSearchX(params, client = xaiClient) {
46167
46199
  {
46168
46200
  type: "x_search",
46169
46201
  query,
46170
- allowed_x_handles: allowed_handles,
46202
+ allowed_x_handles,
46203
+ excluded_x_handles,
46171
46204
  from_date,
46172
- to_date
46205
+ to_date,
46206
+ enable_image_understanding,
46207
+ enable_video_understanding
46173
46208
  }
46174
46209
  ]
46175
46210
  });
@@ -46213,12 +46248,28 @@ async function handleGrokSearchX(params, client = xaiClient) {
46213
46248
  }
46214
46249
  }
46215
46250
  async function handleGrokSearchWeb(params, client = xaiClient) {
46216
- const { query, allowed_domains, limit, offset, output_dir } = params;
46251
+ const {
46252
+ query,
46253
+ allowed_domains,
46254
+ excluded_domains,
46255
+ enable_image_understanding,
46256
+ limit,
46257
+ offset,
46258
+ output_dir
46259
+ } = params;
46217
46260
  try {
46261
+ if (allowed_domains && excluded_domains) {
46262
+ return createValidationError(
46263
+ "allowed_domains",
46264
+ "cannot be used together with excluded_domains"
46265
+ );
46266
+ }
46218
46267
  const cacheKey = JSON.stringify({
46219
46268
  tool: "grok_search_web",
46220
46269
  query,
46221
- allowed_domains
46270
+ allowed_domains,
46271
+ excluded_domains,
46272
+ enable_image_understanding
46222
46273
  });
46223
46274
  const rawResponse = await cache.wrap(
46224
46275
  cacheKey,
@@ -46237,7 +46288,9 @@ async function handleGrokSearchWeb(params, client = xaiClient) {
46237
46288
  {
46238
46289
  type: "web_search",
46239
46290
  query,
46240
- allowed_domains
46291
+ allowed_domains,
46292
+ excluded_domains,
46293
+ enable_image_understanding
46241
46294
  }
46242
46295
  ]
46243
46296
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fre4x/grok",
3
- "version": "1.0.64",
3
+ "version": "1.0.65-beta.1",
4
4
  "description": "An MCP server for xAI (Grok) with search and generation capabilities.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -18,7 +18,7 @@
18
18
  "watch": "tsc -w",
19
19
  "inspector": "npm run build && node ../scripts/run-official-inspector.mjs node dist/index.js",
20
20
  "prepublishOnly": "npm run build && npm run typecheck",
21
- "test": "vitest run --passWithNoTests --exclude dist"
21
+ "test": "node ../scripts/run-vitest.mjs run --passWithNoTests --exclude dist"
22
22
  },
23
23
  "keywords": [
24
24
  "mcp",