grok-it-mcp 0.1.0

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 (43) hide show
  1. package/README.md +106 -0
  2. package/dist/auth/credentials.d.ts +28 -0
  3. package/dist/auth/credentials.js +67 -0
  4. package/dist/auth/credentials.js.map +1 -0
  5. package/dist/auth/oauth.d.ts +101 -0
  6. package/dist/auth/oauth.js +284 -0
  7. package/dist/auth/oauth.js.map +1 -0
  8. package/dist/cache/artifacts.d.ts +16 -0
  9. package/dist/cache/artifacts.js +62 -0
  10. package/dist/cache/artifacts.js.map +1 -0
  11. package/dist/cli.d.ts +19 -0
  12. package/dist/cli.js +278 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/config/constants.d.ts +18 -0
  15. package/dist/config/constants.js +19 -0
  16. package/dist/config/constants.js.map +1 -0
  17. package/dist/config/env.d.ts +11 -0
  18. package/dist/config/env.js +17 -0
  19. package/dist/config/env.js.map +1 -0
  20. package/dist/index.d.ts +2 -0
  21. package/dist/index.js +15 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/mcp/server.d.ts +2 -0
  24. package/dist/mcp/server.js +67 -0
  25. package/dist/mcp/server.js.map +1 -0
  26. package/dist/tools/image-generate.d.ts +41 -0
  27. package/dist/tools/image-generate.js +45 -0
  28. package/dist/tools/image-generate.js.map +1 -0
  29. package/dist/tools/video-generate.d.ts +66 -0
  30. package/dist/tools/video-generate.js +89 -0
  31. package/dist/tools/video-generate.js.map +1 -0
  32. package/dist/tools/x-search.d.ts +27 -0
  33. package/dist/tools/x-search.js +48 -0
  34. package/dist/tools/x-search.js.map +1 -0
  35. package/dist/xai/client.d.ts +25 -0
  36. package/dist/xai/client.js +77 -0
  37. package/dist/xai/client.js.map +1 -0
  38. package/package.json +36 -0
  39. package/plugins/grok-it/.claude-plugin/plugin.json +12 -0
  40. package/plugins/grok-it/.codex-plugin/plugin.json +37 -0
  41. package/plugins/grok-it/.mcp.json +15 -0
  42. package/plugins/grok-it/skills/grok-tools/SKILL.md +16 -0
  43. package/plugins/grok-it/skills/grok-tools/agents/openai.yaml +13 -0
@@ -0,0 +1,45 @@
1
+ import { z } from 'zod';
2
+ import { DEFAULT_IMAGE_MODEL } from '../config/constants.js';
3
+ import { getConfig } from '../config/env.js';
4
+ import { cacheBase64Artifact, cacheUrlArtifact } from '../cache/artifacts.js';
5
+ import { XaiClient } from '../xai/client.js';
6
+ export const imageGenerateSchema = {
7
+ prompt: z.string().min(1),
8
+ model: z.string().default(DEFAULT_IMAGE_MODEL).optional(),
9
+ aspect_ratio: z.string().optional(),
10
+ resolution: z.string().optional(),
11
+ n: z.number().int().min(1).max(4).default(1).optional(),
12
+ cache: z.boolean().default(true).optional(),
13
+ };
14
+ export function buildImagePayload(args) {
15
+ return {
16
+ model: args.model || DEFAULT_IMAGE_MODEL,
17
+ prompt: args.prompt,
18
+ n: args.n || 1,
19
+ ...(args.aspect_ratio ? { aspect_ratio: args.aspect_ratio } : {}),
20
+ ...(args.resolution ? { resolution: args.resolution } : {}),
21
+ };
22
+ }
23
+ export async function handleImageGenerate(args, client = new XaiClient(), fetchImpl) {
24
+ const { data, credentials } = await client.json('/images/generations', { method: 'POST', body: buildImagePayload(args) });
25
+ const images = (data.data || []);
26
+ if (!Array.isArray(images) || images.length === 0)
27
+ throw new Error('xAI image response did not contain data[]');
28
+ const outputs = [];
29
+ for (const image of images) {
30
+ const contentType = typeof image.mime_type === 'string' ? image.mime_type : 'image/png';
31
+ if (args.cache !== false && typeof image.b64_json === 'string') {
32
+ const cached = await cacheBase64Artifact(image.b64_json, { mediaType: 'image', contentType, cacheDir: getConfig().cacheDir });
33
+ outputs.push({ image: cached.path, bytes: cached.bytes, content_type: cached.contentType, revised_prompt: image.revised_prompt ?? null });
34
+ }
35
+ else if (args.cache !== false && typeof image.url === 'string') {
36
+ const cached = await cacheUrlArtifact(image.url, { mediaType: 'image', cacheDir: getConfig().cacheDir, fetchImpl });
37
+ outputs.push({ image: cached.path, remote_url: image.url, bytes: cached.bytes, content_type: cached.contentType, revised_prompt: image.revised_prompt ?? null });
38
+ }
39
+ else {
40
+ outputs.push({ image: typeof image.url === 'string' ? image.url : null, remote_url: image.url ?? null, revised_prompt: image.revised_prompt ?? null });
41
+ }
42
+ }
43
+ return { images: outputs, model: data.model ?? args.model ?? DEFAULT_IMAGE_MODEL, credential_source: credentials.credentialSource };
44
+ }
45
+ //# sourceMappingURL=image-generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-generate.js","sourceRoot":"","sources":["../../src/tools/image-generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { z } from 'zod';
2
+ import { XaiClient } from '../xai/client.js';
3
+ export declare const videoGenerateSchema: {
4
+ prompt: z.ZodString;
5
+ model: z.ZodOptional<z.ZodString>;
6
+ image_url: z.ZodOptional<z.ZodString>;
7
+ reference_images: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
8
+ duration: z.ZodOptional<z.ZodNumber>;
9
+ aspect_ratio: z.ZodOptional<z.ZodString>;
10
+ resolution: z.ZodOptional<z.ZodString>;
11
+ poll_interval_ms: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
12
+ timeout_ms: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
13
+ cache_video: z.ZodOptional<z.ZodBoolean>;
14
+ };
15
+ export type VideoGenerateArgs = z.objectOutputType<typeof videoGenerateSchema, z.ZodTypeAny>;
16
+ export declare function defaultVideoModel(args: VideoGenerateArgs): string;
17
+ export declare function buildVideoPayload(args: VideoGenerateArgs): {
18
+ resolution?: string | undefined;
19
+ aspect_ratio?: string | undefined;
20
+ duration?: number | undefined;
21
+ reference_images?: string[] | undefined;
22
+ image_url?: string | undefined;
23
+ model: string;
24
+ prompt: string;
25
+ };
26
+ export declare function handleVideoGenerate(args: VideoGenerateArgs, client?: XaiClient, fetchImpl?: typeof fetch): Promise<{
27
+ video: string;
28
+ remote_url: string;
29
+ request_id: string;
30
+ status: string;
31
+ bytes: number;
32
+ content_type: string | undefined;
33
+ credential_source: import("../auth/credentials.js").CredentialSource;
34
+ cache_warning?: undefined;
35
+ timeout?: undefined;
36
+ } | {
37
+ video: string;
38
+ remote_url: string;
39
+ request_id: string;
40
+ status: string;
41
+ cache_warning: string;
42
+ credential_source: import("../auth/credentials.js").CredentialSource;
43
+ bytes?: undefined;
44
+ content_type?: undefined;
45
+ timeout?: undefined;
46
+ } | {
47
+ video: string;
48
+ remote_url: string;
49
+ request_id: string;
50
+ status: string;
51
+ credential_source: import("../auth/credentials.js").CredentialSource;
52
+ bytes?: undefined;
53
+ content_type?: undefined;
54
+ cache_warning?: undefined;
55
+ timeout?: undefined;
56
+ } | {
57
+ request_id: string;
58
+ status: string;
59
+ timeout: boolean;
60
+ remote_url: null;
61
+ video: null;
62
+ credential_source: import("../auth/credentials.js").CredentialSource;
63
+ bytes?: undefined;
64
+ content_type?: undefined;
65
+ cache_warning?: undefined;
66
+ }>;
@@ -0,0 +1,89 @@
1
+ import { z } from 'zod';
2
+ import { DEFAULT_POLL_INTERVAL_MS, DEFAULT_VIDEO_IMAGE_MODEL, DEFAULT_VIDEO_MODEL, DEFAULT_VIDEO_TIMEOUT_MS } from '../config/constants.js';
3
+ import { getConfig } from '../config/env.js';
4
+ import { cacheUrlArtifact } from '../cache/artifacts.js';
5
+ import { XaiClient } from '../xai/client.js';
6
+ export const videoGenerateSchema = {
7
+ prompt: z.string().min(1),
8
+ model: z.string().optional(),
9
+ image_url: z.string().url().optional(),
10
+ reference_images: z.array(z.string().url()).optional(),
11
+ duration: z.number().int().min(1).max(30).optional(),
12
+ aspect_ratio: z.string().optional(),
13
+ resolution: z.string().optional(),
14
+ poll_interval_ms: z.number().int().min(250).max(30000).default(DEFAULT_POLL_INTERVAL_MS).optional(),
15
+ timeout_ms: z.number().int().min(1000).max(30 * 60_000).default(DEFAULT_VIDEO_TIMEOUT_MS).optional(),
16
+ cache_video: z.boolean().optional(),
17
+ };
18
+ export function defaultVideoModel(args) {
19
+ return args.model || (args.image_url || args.reference_images?.length ? DEFAULT_VIDEO_IMAGE_MODEL : DEFAULT_VIDEO_MODEL);
20
+ }
21
+ export function buildVideoPayload(args) {
22
+ return {
23
+ model: defaultVideoModel(args),
24
+ prompt: args.prompt,
25
+ ...(args.image_url ? { image_url: args.image_url } : {}),
26
+ ...(args.reference_images?.length ? { reference_images: args.reference_images } : {}),
27
+ ...(args.duration ? { duration: args.duration } : {}),
28
+ ...(args.aspect_ratio ? { aspect_ratio: args.aspect_ratio } : {}),
29
+ ...(args.resolution ? { resolution: args.resolution } : {}),
30
+ };
31
+ }
32
+ function sleep(ms) {
33
+ return new Promise((resolve) => setTimeout(resolve, ms));
34
+ }
35
+ function statusOf(data) {
36
+ const obj = data;
37
+ return String(obj.status || obj.state || obj.phase || '').toLowerCase();
38
+ }
39
+ function videoUrlOf(data) {
40
+ const obj = data;
41
+ if (typeof obj.video_url === 'string')
42
+ return obj.video_url;
43
+ if (typeof obj.url === 'string')
44
+ return obj.url;
45
+ if (Array.isArray(obj.data)) {
46
+ const first = obj.data[0];
47
+ if (typeof first?.url === 'string')
48
+ return first.url;
49
+ if (typeof first?.video_url === 'string')
50
+ return first.video_url;
51
+ }
52
+ return undefined;
53
+ }
54
+ export async function handleVideoGenerate(args, client = new XaiClient(), fetchImpl) {
55
+ const { data: submitted, credentials } = await client.json('/videos/generations', { method: 'POST', body: buildVideoPayload(args) });
56
+ const submitObj = submitted;
57
+ const requestId = String(submitObj.request_id || submitObj.id || '');
58
+ if (!requestId)
59
+ throw new Error('xAI video response did not contain request_id');
60
+ const deadline = Date.now() + (args.timeout_ms || DEFAULT_VIDEO_TIMEOUT_MS);
61
+ let last = submitted;
62
+ for (;;) {
63
+ const status = statusOf(last);
64
+ const directUrl = videoUrlOf(last);
65
+ if (directUrl || ['done', 'completed', 'succeeded', 'success'].includes(status)) {
66
+ const remoteUrl = directUrl || videoUrlOf(last);
67
+ if (!remoteUrl)
68
+ throw new Error('xAI video completed without a video URL');
69
+ const shouldCache = args.cache_video ?? getConfig().cacheVideoByDefault;
70
+ if (shouldCache) {
71
+ try {
72
+ const cached = await cacheUrlArtifact(remoteUrl, { mediaType: 'video', cacheDir: getConfig().cacheDir, fetchImpl });
73
+ return { video: cached.path, remote_url: remoteUrl, request_id: requestId, status: status || 'completed', bytes: cached.bytes, content_type: cached.contentType, credential_source: credentials.credentialSource };
74
+ }
75
+ catch (error) {
76
+ return { video: remoteUrl, remote_url: remoteUrl, request_id: requestId, status: status || 'completed', cache_warning: error.message, credential_source: credentials.credentialSource };
77
+ }
78
+ }
79
+ return { video: remoteUrl, remote_url: remoteUrl, request_id: requestId, status: status || 'completed', credential_source: credentials.credentialSource };
80
+ }
81
+ if (['failed', 'error', 'cancelled', 'canceled'].includes(status))
82
+ throw new Error(`xAI video generation failed: ${JSON.stringify(last)}`);
83
+ if (Date.now() >= deadline)
84
+ return { request_id: requestId, status: status || 'pending', timeout: true, remote_url: null, video: null, credential_source: credentials.credentialSource };
85
+ await sleep(args.poll_interval_ms || DEFAULT_POLL_INTERVAL_MS);
86
+ last = (await client.json(`/videos/${encodeURIComponent(requestId)}`, { method: 'GET' })).data;
87
+ }
88
+ }
89
+ //# sourceMappingURL=video-generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-generate.js","sourceRoot":"","sources":["../../src/tools/video-generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { z } from 'zod';
2
+ import { XaiClient } from '../xai/client.js';
3
+ export declare const xSearchSchema: {
4
+ query: z.ZodString;
5
+ model: z.ZodOptional<z.ZodDefault<z.ZodString>>;
6
+ from_date: z.ZodOptional<z.ZodString>;
7
+ to_date: z.ZodOptional<z.ZodString>;
8
+ include_handles: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
9
+ exclude_handles: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
10
+ include_images: z.ZodOptional<z.ZodBoolean>;
11
+ include_videos: z.ZodOptional<z.ZodBoolean>;
12
+ max_results: z.ZodOptional<z.ZodNumber>;
13
+ };
14
+ export type XSearchArgs = z.objectOutputType<typeof xSearchSchema, z.ZodTypeAny>;
15
+ export declare function buildXSearchPayload(args: XSearchArgs): {
16
+ model: string;
17
+ input: string;
18
+ tools: Record<string, unknown>[];
19
+ };
20
+ export declare function handleXSearch(args: XSearchArgs, client?: XaiClient): Promise<{
21
+ answer: string;
22
+ citations: any[];
23
+ raw_id: {} | null;
24
+ model: {};
25
+ credential_source: import("../auth/credentials.js").CredentialSource;
26
+ degraded: boolean;
27
+ }>;
@@ -0,0 +1,48 @@
1
+ import { z } from 'zod';
2
+ import { DEFAULT_X_SEARCH_MODEL } from '../config/constants.js';
3
+ import { XaiClient, extractOutputText } from '../xai/client.js';
4
+ export const xSearchSchema = {
5
+ query: z.string().min(1).describe('Search question or query for X.'),
6
+ model: z.string().default(DEFAULT_X_SEARCH_MODEL).optional(),
7
+ from_date: z.string().optional().describe('Optional inclusive YYYY-MM-DD lower date bound.'),
8
+ to_date: z.string().optional().describe('Optional inclusive YYYY-MM-DD upper date bound.'),
9
+ include_handles: z.array(z.string()).optional(),
10
+ exclude_handles: z.array(z.string()).optional(),
11
+ include_images: z.boolean().optional(),
12
+ include_videos: z.boolean().optional(),
13
+ max_results: z.number().int().min(1).max(50).optional(),
14
+ };
15
+ export function buildXSearchPayload(args) {
16
+ const tool = { type: 'x_search' };
17
+ if (args.from_date)
18
+ tool.from_date = args.from_date;
19
+ if (args.to_date)
20
+ tool.to_date = args.to_date;
21
+ if (args.include_handles?.length)
22
+ tool.included_x_handles = args.include_handles;
23
+ if (args.exclude_handles?.length)
24
+ tool.excluded_x_handles = args.exclude_handles;
25
+ if (args.include_images !== undefined || args.include_videos !== undefined) {
26
+ tool.search_parameters = { include_images: Boolean(args.include_images), include_videos: Boolean(args.include_videos) };
27
+ }
28
+ if (args.max_results)
29
+ tool.max_search_results = args.max_results;
30
+ return {
31
+ model: args.model || DEFAULT_X_SEARCH_MODEL,
32
+ input: args.query,
33
+ tools: [tool],
34
+ };
35
+ }
36
+ export async function handleXSearch(args, client = new XaiClient()) {
37
+ const { data, credentials } = await client.json('/responses', { method: 'POST', body: buildXSearchPayload(args) });
38
+ const obj = data;
39
+ return {
40
+ answer: extractOutputText(data),
41
+ citations: Array.isArray(obj.citations) ? obj.citations : [],
42
+ raw_id: obj.id ?? null,
43
+ model: obj.model ?? args.model ?? DEFAULT_X_SEARCH_MODEL,
44
+ credential_source: credentials.credentialSource,
45
+ degraded: !extractOutputText(data),
46
+ };
47
+ }
48
+ //# sourceMappingURL=x-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x-search.js","sourceRoot":"","sources":["../../src/tools/x-search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { ResolvedCredentials } from '../auth/credentials.js';
2
+ export type XaiClientOptions = {
3
+ fetchImpl?: typeof fetch;
4
+ credentials?: ResolvedCredentials;
5
+ env?: NodeJS.ProcessEnv;
6
+ };
7
+ export declare class XaiError extends Error {
8
+ code: string;
9
+ status?: number | undefined;
10
+ details?: unknown | undefined;
11
+ constructor(code: string, message: string, status?: number | undefined, details?: unknown | undefined);
12
+ }
13
+ export declare class XaiClient {
14
+ private options;
15
+ constructor(options?: XaiClientOptions);
16
+ json(path: string, init?: {
17
+ method?: string;
18
+ body?: unknown;
19
+ timeoutMs?: number;
20
+ }, retrying?: boolean): Promise<{
21
+ data: unknown;
22
+ credentials: ResolvedCredentials;
23
+ }>;
24
+ }
25
+ export declare function extractOutputText(response: unknown): string;
@@ -0,0 +1,77 @@
1
+ import { DEFAULT_XAI_BASE_URL, PACKAGE_NAME, PACKAGE_VERSION } from '../config/constants.js';
2
+ import { resolveCredentials, redactSecret } from '../auth/credentials.js';
3
+ import { validateInferenceBaseUrl } from '../auth/oauth.js';
4
+ export class XaiError extends Error {
5
+ code;
6
+ status;
7
+ details;
8
+ constructor(code, message, status, details) {
9
+ super(redactSecret(message));
10
+ this.code = code;
11
+ this.status = status;
12
+ this.details = details;
13
+ this.name = 'XaiError';
14
+ }
15
+ }
16
+ export class XaiClient {
17
+ options;
18
+ constructor(options = {}) {
19
+ this.options = options;
20
+ }
21
+ async json(path, init = {}, retrying = false) {
22
+ const credentials = this.options.credentials || (await resolveCredentials({ fetchImpl: this.options.fetchImpl, env: this.options.env }));
23
+ const baseUrl = credentials.provider === 'xai-oauth' ? validateInferenceBaseUrl(credentials.baseUrl) : (credentials.baseUrl || DEFAULT_XAI_BASE_URL).replace(/\/$/, '');
24
+ const url = `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;
25
+ const controller = new AbortController();
26
+ const timer = init.timeoutMs ? setTimeout(() => controller.abort(), init.timeoutMs) : undefined;
27
+ const response = await (this.options.fetchImpl || fetch)(url, {
28
+ method: init.method || 'GET',
29
+ headers: {
30
+ accept: 'application/json',
31
+ 'content-type': 'application/json',
32
+ authorization: credentials.authorization,
33
+ 'user-agent': `${PACKAGE_NAME}/${PACKAGE_VERSION}`,
34
+ },
35
+ body: init.body === undefined ? undefined : JSON.stringify(init.body),
36
+ signal: controller.signal,
37
+ }).finally(() => timer && clearTimeout(timer));
38
+ const data = await response.json().catch(() => ({}));
39
+ if (response.status === 401 && credentials.provider === 'xai-oauth' && !retrying && !this.options.credentials) {
40
+ await resolveCredentials({ forceRefresh: true, fetchImpl: this.options.fetchImpl, env: this.options.env });
41
+ return this.json(path, init, true);
42
+ }
43
+ if (!response.ok) {
44
+ const msg = typeof data.error === 'string' ? data.error : `xAI request failed with HTTP ${response.status}`;
45
+ throw new XaiError('xai_http_error', msg, response.status, data);
46
+ }
47
+ return { data, credentials };
48
+ }
49
+ }
50
+ export function extractOutputText(response) {
51
+ const obj = response;
52
+ if (typeof obj.output_text === 'string')
53
+ return obj.output_text;
54
+ if (Array.isArray(obj.output)) {
55
+ const parts = [];
56
+ for (const item of obj.output) {
57
+ if (typeof item.content === 'string')
58
+ parts.push(item.content);
59
+ if (Array.isArray(item.content)) {
60
+ for (const content of item.content) {
61
+ if (typeof content.text === 'string')
62
+ parts.push(content.text);
63
+ }
64
+ }
65
+ }
66
+ if (parts.length)
67
+ return parts.join('\n');
68
+ }
69
+ if (Array.isArray(obj.choices)) {
70
+ const choice = obj.choices[0];
71
+ const message = choice?.message;
72
+ if (typeof message?.content === 'string')
73
+ return message.content;
74
+ }
75
+ return '';
76
+ }
77
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/xai/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAuB,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC/F,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAQ5D,MAAM,OAAO,QAAS,SAAQ,KAAK;IACd;IAAsC;IAAwB;IAAjF,YAAmB,IAAY,EAAE,OAAe,EAAS,MAAe,EAAS,OAAiB;QAChG,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;QADZ,SAAI,GAAJ,IAAI,CAAQ;QAA0B,WAAM,GAAN,MAAM,CAAS;QAAS,YAAO,GAAP,OAAO,CAAU;QAEhG,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AAED,MAAM,OAAO,SAAS;IACA;IAApB,YAAoB,UAA4B,EAAE;QAA9B,YAAO,GAAP,OAAO,CAAuB;IAAG,CAAC;IAEtD,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,OAAgE,EAAE,EAAE,QAAQ,GAAG,KAAK;QAC3G,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACzI,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,wBAAwB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,IAAI,oBAAoB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxK,MAAM,GAAG,GAAG,GAAG,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;QACpE,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAChG,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,GAAG,EAAE;YAC5D,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;YAC5B,OAAO,EAAE;gBACP,MAAM,EAAE,kBAAkB;gBAC1B,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,WAAW,CAAC,aAAa;gBACxC,YAAY,EAAE,GAAG,YAAY,IAAI,eAAe,EAAE;aACnD;YACD,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;YACrE,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrD,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,QAAQ,KAAK,WAAW,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC9G,MAAM,kBAAkB,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;YAC3G,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG,GAAG,OAAQ,IAAgC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAE,IAA+B,CAAC,KAAK,CAAC,CAAC,CAAC,gCAAgC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrK,MAAM,IAAI,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAiB;IACjD,MAAM,GAAG,GAAG,QAAmC,CAAC;IAChD,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC,WAAW,CAAC;IAChE,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,MAAwC,EAAE,CAAC;YAChE,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC/D,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAChC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,OAAyC,EAAE,CAAC;oBACrE,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ;wBAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACjE,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,KAAK,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC,CAAwC,CAAC;QACrE,MAAM,OAAO,GAAG,MAAM,EAAE,OAA8C,CAAC;QACvE,IAAI,OAAO,OAAO,EAAE,OAAO,KAAK,QAAQ;YAAE,OAAO,OAAO,CAAC,OAAO,CAAC;IACnE,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "grok-it-mcp",
3
+ "version": "0.1.0",
4
+ "description": "Claude Code and Codex plugin wrapper around a local MCP server for Grok x_search, image generation, and video generation.",
5
+ "type": "module",
6
+ "bin": {
7
+ "grok-it-mcp": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "README.md",
12
+ "plugins"
13
+ ],
14
+ "engines": {
15
+ "node": ">=20"
16
+ },
17
+ "scripts": {
18
+ "build": "tsc -p tsconfig.json && node scripts/make-bin-executable.mjs",
19
+ "typecheck": "tsc -p tsconfig.json --noEmit",
20
+ "test": "vitest run",
21
+ "validate:plugin": "node scripts/validate-plugin.mjs",
22
+ "validate": "npm run typecheck && npm test && npm run build && npm run validate:plugin && npm run validate:codex-plugin",
23
+ "validate:codex-plugin": "node scripts/validate-codex-plugin.mjs"
24
+ },
25
+ "dependencies": {
26
+ "@modelcontextprotocol/sdk": "1.29.0",
27
+ "zod": "3.25.76"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "24.10.1",
31
+ "toml": "3.0.0",
32
+ "typescript": "5.9.3",
33
+ "vitest": "4.0.15",
34
+ "yaml": "2.8.2"
35
+ }
36
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "grok-it",
3
+ "version": "0.1.0",
4
+ "description": "Claude Code plugin that exposes Grok x_search, image generation, and video generation through a local MCP server.",
5
+ "author": {
6
+ "name": "local"
7
+ },
8
+ "homepage": "https://github.com/local/grok-it",
9
+ "license": "MIT",
10
+ "skills": "./skills/",
11
+ "mcpServers": "./.mcp.json"
12
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "grok-it",
3
+ "version": "0.1.0",
4
+ "description": "Cross-platform Claude Code and Codex plugin that exposes Grok x_search, image generation, and video generation through a local MCP server.",
5
+ "author": {
6
+ "name": "local"
7
+ },
8
+ "homepage": "https://github.com/local/grok-it",
9
+ "license": "MIT",
10
+ "keywords": [
11
+ "grok",
12
+ "xai",
13
+ "mcp",
14
+ "x-search",
15
+ "image-generation",
16
+ "video-generation"
17
+ ],
18
+ "skills": "./skills/",
19
+ "mcpServers": "./.mcp.json",
20
+ "interface": {
21
+ "displayName": "Grok It",
22
+ "shortDescription": "Use Grok X search, image, and video tools in Codex.",
23
+ "longDescription": "Grok It bundles a shared cross-platform plugin root with a local MCP server and skill guidance so Claude Code and Codex agents can call Grok OAuth or xAI API-key backed X search, image generation, and video generation tools.",
24
+ "developerName": "local",
25
+ "category": "Productivity",
26
+ "capabilities": [
27
+ "Interactive",
28
+ "Read",
29
+ "Write"
30
+ ],
31
+ "defaultPrompt": [
32
+ "Search X with Grok for recent context.",
33
+ "Generate an image with Grok.",
34
+ "Generate a short video with Grok."
35
+ ]
36
+ }
37
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "mcpServers": {
3
+ "grok-it": {
4
+ "command": "npx",
5
+ "args": [
6
+ "-y",
7
+ "grok-it-mcp@0.1.0"
8
+ ],
9
+ "env": {
10
+ "GROK_IT_TOKEN_STORE": "${HOME}/.grok-it/auth.json",
11
+ "GROK_IT_CACHE_DIR": "${HOME}/.grok-it/artifacts"
12
+ }
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ ---
2
+ name: grok-tools
3
+ description: "Use when Claude Code or Codex should call Grok/xAI MCP tools for X search, image generation, video generation, Grok OAuth login/status, or XAI_API_KEY fallback through the grok-it MCP server."
4
+ ---
5
+
6
+ # Grok Tools
7
+
8
+ Prefer the local `grok-it` MCP server tools rather than reimplementing xAI HTTP calls:
9
+
10
+ 1. Run `grok_auth_status` to check OAuth/API-key availability without exposing secrets.
11
+ 2. Run `grok_login` when OAuth setup is needed. First call returns an authorize URL plus PKCE verifier/state; second call with the callback URL completes login. Never request raw access or refresh tokens.
12
+ 3. Use `grok_x_search` for X/Twitter search with optional handle/date/media filters.
13
+ 4. Use `grok_image_generate` for image generation. It returns local cached image paths by default.
14
+ 5. Use `grok_video_generate` for video generation. It returns remote URLs by default; pass `cache_video:true` only when local video caching is desired.
15
+
16
+ OAuth bearer credentials are pinned to `https://*.x.ai`; API key mode may use `XAI_BASE_URL` for compatible endpoints.
@@ -0,0 +1,13 @@
1
+ interface:
2
+ display_name: Grok Tools
3
+ short_description: Call Grok X search, image generation, and video generation.
4
+ default_prompt: Use $grok-tools with the grok-it MCP tools for X search, image generation, video generation, and Grok OAuth/API-key auth checks.
5
+ policy:
6
+ allow_implicit_invocation: true
7
+ dependencies:
8
+ tools:
9
+ - grok_auth_status
10
+ - grok_login
11
+ - grok_x_search
12
+ - grok_image_generate
13
+ - grok_video_generate